Merge remote-tracking branch 'origin/develop' into patch/TD-1983
This commit is contained in:
commit
5f3797c11f
|
@ -61,7 +61,7 @@ The use of each configuration item is:
|
|||
|
||||
* **port**: This is the `http` service port which enables other application to manage rules by `restful API`.
|
||||
* **database**: rules are stored in a `sqlite` database, this is the path of the database file (if the file does not exist, the alert application creates it automatically).
|
||||
* **tdengine**: connection string of `TDEngine` server, note the database name should be put in the `sql` field of a rule in most cases, thus it should NOT be included in the string.
|
||||
* **tdengine**: connection string of `TDEngine` server (please refer the documentation of GO connector for the detailed format of this string), note the database name should be put in the `sql` field of a rule in most cases, thus it should NOT be included in the string.
|
||||
* **log > level**: log level, could be `production` or `debug`.
|
||||
* **log > path**: log output file path.
|
||||
* **receivers > alertManager**: the alert application pushes alerts to `AlertManager` at this URL.
|
||||
|
|
|
@ -58,7 +58,7 @@ $ go build
|
|||
|
||||
* **port**:报警监测程序支持使用 `restful API` 对规则进行管理,这个参数用于配置 `http` 服务的侦听端口。
|
||||
* **database**:报警监测程序将规则保存到了一个 `sqlite` 数据库中,这个参数用于指定数据库文件的路径(不需要提前创建这个文件,如果它不存在,程序会自动创建它)。
|
||||
* **tdengine**:`TDEngine` 的连接字符串,一般来说,数据库名应该在报警规则的 `sql` 语句中指定,所以这个字符串中 **不** 应包含数据库名。
|
||||
* **tdengine**:`TDEngine` 的连接字符串(这个字符串的详细格式说明请见 GO 连接器的文档),一般来说,数据库名应该在报警规则的 `sql` 语句中指定,所以这个字符串中 **不** 应包含数据库名。
|
||||
* **log > level**:日志的记录级别,可选 `production` 或 `debug`。
|
||||
* **log > path**:日志文件的路径。
|
||||
* **receivers > alertManager**:报警监测程序会将报警推送到 `AlertManager`,在这里指定 `AlertManager` 的接收地址。
|
||||
|
|
|
@ -84,6 +84,7 @@ func (alert *Alert) doRefresh(firing bool, rule *Rule) bool {
|
|||
|
||||
case firing && (alert.State == AlertStateWaiting):
|
||||
alert.StartsAt = time.Now()
|
||||
alert.EndsAt = time.Time{}
|
||||
if rule.For.Nanoseconds() > 0 {
|
||||
alert.State = AlertStatePending
|
||||
return false
|
||||
|
@ -95,6 +96,7 @@ func (alert *Alert) doRefresh(firing bool, rule *Rule) bool {
|
|||
return false
|
||||
}
|
||||
alert.StartsAt = alert.StartsAt.Add(rule.For.Duration)
|
||||
alert.EndsAt = time.Time{}
|
||||
alert.State = AlertStateFiring
|
||||
|
||||
case firing && (alert.State == AlertStateFiring):
|
||||
|
|
|
@ -9,7 +9,7 @@ ELSEIF (TD_WINDOWS)
|
|||
ELSE ()
|
||||
SET(CMAKE_INSTALL_PREFIX C:/TDengine)
|
||||
ENDIF ()
|
||||
|
||||
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/go DESTINATION connector)
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/nodejs DESTINATION connector)
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/python DESTINATION connector)
|
||||
|
@ -20,12 +20,12 @@ ELSEIF (TD_WINDOWS)
|
|||
INSTALL(FILES ${TD_COMMUNITY_DIR}/src/inc/taoserror.h DESTINATION include)
|
||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.lib DESTINATION driver)
|
||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.exp DESTINATION driver)
|
||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.dll DESTINATION driver)
|
||||
|
||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.dll DESTINATION driver)
|
||||
|
||||
IF (TD_POWER)
|
||||
INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/power.exe DESTINATION .)
|
||||
ELSE ()
|
||||
INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/taos.exe DESTINATION .)
|
||||
ELSE ()
|
||||
INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/taos.exe DESTINATION .)
|
||||
INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/taosdemo.exe DESTINATION .)
|
||||
ENDIF ()
|
||||
|
||||
|
|
|
@ -312,7 +312,7 @@ function install_data() {
|
|||
}
|
||||
|
||||
function install_connector() {
|
||||
${csudo} cp -rf ${script_dir}/connector/* ${install_main_dir}/connector
|
||||
${csudo} cp -rf ${script_dir}/connector/ ${install_main_dir}/
|
||||
}
|
||||
|
||||
function install_examples() {
|
||||
|
|
|
@ -163,7 +163,7 @@ function install_log() {
|
|||
}
|
||||
|
||||
function install_connector() {
|
||||
${csudo} cp -rf ${script_dir}/connector/* ${install_main_dir}/connector
|
||||
${csudo} cp -rf ${script_dir}/connector/ ${install_main_dir}/
|
||||
}
|
||||
|
||||
function install_examples() {
|
||||
|
|
|
@ -20,6 +20,6 @@ ADD_SUBDIRECTORY(tsdb)
|
|||
ADD_SUBDIRECTORY(wal)
|
||||
ADD_SUBDIRECTORY(cq)
|
||||
ADD_SUBDIRECTORY(dnode)
|
||||
ADD_SUBDIRECTORY(connector/odbc)
|
||||
#ADD_SUBDIRECTORY(connector/odbc)
|
||||
ADD_SUBDIRECTORY(connector/jdbc)
|
||||
|
||||
|
|
|
@ -84,9 +84,9 @@ typedef struct SRetrieveSupport {
|
|||
} SRetrieveSupport;
|
||||
|
||||
int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pDesc,
|
||||
SColumnModel **pFinalModel, uint32_t nBufferSize);
|
||||
SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSize);
|
||||
|
||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel,
|
||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, SColumnModel* pFFModel,
|
||||
int32_t numOfVnodes);
|
||||
|
||||
int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, void *data,
|
||||
|
|
|
@ -39,9 +39,9 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql);
|
|||
int32_t tscHandleInsertRetry(SSqlObj* pSql);
|
||||
|
||||
void tscBuildResFromSubqueries(SSqlObj *pSql);
|
||||
TAOS_ROW doSetResultRowData(SSqlObj *pSql, bool finalResult);
|
||||
TAOS_ROW doSetResultRowData(SSqlObj *pSql);
|
||||
|
||||
char *getArithemicInputSrc(void *param, const char *name, int32_t colId);
|
||||
char *getArithmeticInputSrc(void *param, const char *name, int32_t colId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -282,6 +282,7 @@ int tscSetMgmtEpSetFromCfg(const char *first, const char *second);
|
|||
|
||||
bool tscSetSqlOwner(SSqlObj* pSql);
|
||||
void tscClearSqlOwner(SSqlObj* pSql);
|
||||
int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize);
|
||||
|
||||
void* malloc_throw(size_t size);
|
||||
void* calloc_throw(size_t nmemb, size_t size);
|
||||
|
|
|
@ -293,32 +293,32 @@ typedef struct SResRec {
|
|||
} SResRec;
|
||||
|
||||
typedef struct {
|
||||
int64_t numOfRows; // num of results in current retrieved
|
||||
int64_t numOfRowsGroup; // num of results of current group
|
||||
int64_t numOfTotal; // num of total results
|
||||
int64_t numOfClauseTotal; // num of total result in current subclause
|
||||
char * pRsp;
|
||||
int32_t rspType;
|
||||
int32_t rspLen;
|
||||
uint64_t qhandle;
|
||||
int64_t uid;
|
||||
int64_t useconds;
|
||||
int64_t offset; // offset value from vnode during projection query of stable
|
||||
int32_t row;
|
||||
int16_t numOfCols;
|
||||
int16_t precision;
|
||||
bool completed;
|
||||
int32_t code;
|
||||
int32_t numOfGroups;
|
||||
SResRec * pGroupRec;
|
||||
char * data;
|
||||
TAOS_ROW tsrow;
|
||||
int32_t* length; // length for each field for current row
|
||||
char ** buffer; // Buffer used to put multibytes encoded using unicode (wchar_t)
|
||||
SColumnIndex * pColumnIndex;
|
||||
int32_t numOfRows; // num of results in current retrieval
|
||||
int64_t numOfRowsGroup; // num of results of current group
|
||||
int64_t numOfTotal; // num of total results
|
||||
int64_t numOfClauseTotal; // num of total result in current subclause
|
||||
char * pRsp;
|
||||
int32_t rspType;
|
||||
int32_t rspLen;
|
||||
uint64_t qhandle;
|
||||
int64_t useconds;
|
||||
int64_t offset; // offset value from vnode during projection query of stable
|
||||
int32_t row;
|
||||
int16_t numOfCols;
|
||||
int16_t precision;
|
||||
bool completed;
|
||||
int32_t code;
|
||||
int32_t numOfGroups;
|
||||
SResRec * pGroupRec;
|
||||
char * data;
|
||||
TAOS_ROW tsrow;
|
||||
TAOS_ROW urow;
|
||||
int32_t* length; // length for each field for current row
|
||||
char ** buffer; // Buffer used to put multibytes encoded using unicode (wchar_t)
|
||||
SColumnIndex* pColumnIndex;
|
||||
|
||||
SArithmeticSupport* pArithSup; // support the arithmetic expression calculation on agg functions
|
||||
|
||||
struct SLocalReducer *pLocalReducer;
|
||||
struct SLocalReducer* pLocalReducer;
|
||||
} SSqlRes;
|
||||
|
||||
typedef struct STscObj {
|
||||
|
@ -425,6 +425,7 @@ int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo *pQueryInfo);
|
|||
void tscRestoreSQLFuncForSTableQuery(SQueryInfo *pQueryInfo);
|
||||
|
||||
int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo);
|
||||
void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
||||
|
||||
void tscResetSqlCmdObj(SSqlCmd *pCmd, bool removeFromCache);
|
||||
|
||||
|
@ -471,8 +472,9 @@ static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pField
|
|||
int32_t bytes = pInfo->field.bytes;
|
||||
|
||||
char* pData = pRes->data + (int32_t)(offset * pRes->numOfRows + bytes * pRes->row);
|
||||
UNUSED(pData);
|
||||
|
||||
// user defined constant value output columns
|
||||
// user defined constant value output columns
|
||||
if (pInfo->pSqlExpr != NULL && TSDB_COL_IS_UD_COL(pInfo->pSqlExpr->colInfo.flag)) {
|
||||
if (type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BINARY) {
|
||||
pData = pInfo->pSqlExpr->param[1].pz;
|
||||
|
|
|
@ -129,6 +129,14 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getSchemaMetaData
|
|||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp
|
||||
(JNIEnv *, jobject, jlong, jlong, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||
* Method: fetchBlockImp
|
||||
* Signature: (JJLcom/taosdata/jdbc/TSDBResultSetBlockData;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchBlockImp
|
||||
(JNIEnv *, jobject, jlong, jlong, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||
* Method: closeConnectionImp
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "taos.h"
|
||||
#include "tlog.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tsclient.h"
|
||||
|
||||
#include "com_taosdata_jdbc_TSDBJNIConnector.h"
|
||||
|
||||
|
@ -57,6 +56,10 @@ jmethodID g_rowdataSetStringFp;
|
|||
jmethodID g_rowdataSetTimestampFp;
|
||||
jmethodID g_rowdataSetByteArrayFp;
|
||||
|
||||
jmethodID g_blockdataSetByteArrayFp;
|
||||
jmethodID g_blockdataSetNumOfRowsFp;
|
||||
jmethodID g_blockdataSetNumOfColsFp;
|
||||
|
||||
#define JNI_SUCCESS 0
|
||||
#define JNI_TDENGINE_ERROR -1
|
||||
#define JNI_CONNECTION_NULL -2
|
||||
|
@ -66,7 +69,7 @@ jmethodID g_rowdataSetByteArrayFp;
|
|||
#define JNI_FETCH_END -6
|
||||
#define JNI_OUT_OF_MEMORY -7
|
||||
|
||||
void jniGetGlobalMethod(JNIEnv *env) {
|
||||
static void jniGetGlobalMethod(JNIEnv *env) {
|
||||
// make sure init function executed once
|
||||
switch (atomic_val_compare_exchange_32(&__init, 0, 1)) {
|
||||
case 0:
|
||||
|
@ -114,10 +117,31 @@ void jniGetGlobalMethod(JNIEnv *env) {
|
|||
g_rowdataSetByteArrayFp = (*env)->GetMethodID(env, g_rowdataClass, "setByteArray", "(I[B)V");
|
||||
(*env)->DeleteLocalRef(env, rowdataClass);
|
||||
|
||||
jclass blockdataClass = (*env)->FindClass(env, "com/taosdata/jdbc/TSDBResultSetBlockData");
|
||||
jclass g_blockdataClass = (*env)->NewGlobalRef(env, blockdataClass);
|
||||
g_blockdataSetByteArrayFp = (*env)->GetMethodID(env, g_blockdataClass, "setByteArray", "(II[B)V");
|
||||
g_blockdataSetNumOfRowsFp = (*env)->GetMethodID(env, g_blockdataClass, "setNumOfRows", "(I)V");
|
||||
g_blockdataSetNumOfColsFp = (*env)->GetMethodID(env, g_blockdataClass, "setNumOfCols", "(I)V");
|
||||
(*env)->DeleteLocalRef(env, blockdataClass);
|
||||
|
||||
atomic_store_32(&__init, 2);
|
||||
jniDebug("native method register finished");
|
||||
}
|
||||
|
||||
static int32_t check_for_params(jobject jobj, jlong conn, jlong res) {
|
||||
if ((TAOS*) conn == NULL) {
|
||||
jniError("jobj:%p, connection is closed", jobj);
|
||||
return JNI_CONNECTION_NULL;
|
||||
}
|
||||
|
||||
if ((TAOS_RES *) res == NULL) {
|
||||
jniError("jobj:%p, conn:%p, res is null", jobj, (TAOS*) conn);
|
||||
return JNI_RESULT_SET_NULL;
|
||||
}
|
||||
|
||||
return JNI_SUCCESS;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setAllocModeImp(JNIEnv *env, jobject jobj, jint jMode,
|
||||
jstring jPath, jboolean jAutoDump) {
|
||||
if (jPath != NULL) {
|
||||
|
@ -192,39 +216,37 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setOptions(JNIEnv
|
|||
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_connectImp(JNIEnv *env, jobject jobj, jstring jhost,
|
||||
jint jport, jstring jdbName, jstring juser,
|
||||
jstring jpass) {
|
||||
jlong ret = 0;
|
||||
jlong ret = 0;
|
||||
const char *host = NULL;
|
||||
const char *dbname = NULL;
|
||||
const char *user = NULL;
|
||||
const char *pass = NULL;
|
||||
const char *dbname = NULL;
|
||||
|
||||
if (jhost != NULL) {
|
||||
host = (*env)->GetStringUTFChars(env, jhost, NULL);
|
||||
}
|
||||
|
||||
if (jdbName != NULL) {
|
||||
dbname = (*env)->GetStringUTFChars(env, jdbName, NULL);
|
||||
}
|
||||
|
||||
if (juser != NULL) {
|
||||
user = (*env)->GetStringUTFChars(env, juser, NULL);
|
||||
}
|
||||
|
||||
if (jpass != NULL) {
|
||||
pass = (*env)->GetStringUTFChars(env, jpass, NULL);
|
||||
}
|
||||
|
||||
if (user == NULL) {
|
||||
jniDebug("jobj:%p, user is null, use default user %s", jobj, TSDB_DEFAULT_USER);
|
||||
jniDebug("jobj:%p, user not specified, use default user %s", jobj, TSDB_DEFAULT_USER);
|
||||
}
|
||||
|
||||
if (pass == NULL) {
|
||||
jniDebug("jobj:%p, pass is null, use default password", jobj);
|
||||
jniDebug("jobj:%p, pass not specified, use default password", jobj);
|
||||
}
|
||||
|
||||
/*
|
||||
* set numOfThreadsPerCore = 0
|
||||
* means only one thread for client side scheduler
|
||||
*/
|
||||
tsNumOfThreadsPerCore = 0.0;
|
||||
|
||||
ret = (jlong)taos_connect((char *)host, (char *)user, (char *)pass, (char *)dbname, (uint16_t)jport);
|
||||
ret = (jlong) taos_connect((char *)host, (char *)user, (char *)pass, (char *)dbname, (uint16_t)jport);
|
||||
if (ret == 0) {
|
||||
jniError("jobj:%p, conn:%p, connect to database failed, host=%s, user=%s, dbname=%s, port=%d", jobj, (void *)ret,
|
||||
(char *)host, (char *)user, (char *)dbname, (int32_t)jport);
|
||||
|
@ -233,10 +255,21 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_connectImp(JNIEn
|
|||
(char *)host, (char *)user, (char *)dbname, (int32_t)jport);
|
||||
}
|
||||
|
||||
if (host != NULL) (*env)->ReleaseStringUTFChars(env, jhost, host);
|
||||
if (dbname != NULL) (*env)->ReleaseStringUTFChars(env, jdbName, dbname);
|
||||
if (user != NULL) (*env)->ReleaseStringUTFChars(env, juser, user);
|
||||
if (pass != NULL) (*env)->ReleaseStringUTFChars(env, jpass, pass);
|
||||
if (host != NULL) {
|
||||
(*env)->ReleaseStringUTFChars(env, jhost, host);
|
||||
}
|
||||
|
||||
if (dbname != NULL) {
|
||||
(*env)->ReleaseStringUTFChars(env, jdbName, dbname);
|
||||
}
|
||||
|
||||
if (user != NULL) {
|
||||
(*env)->ReleaseStringUTFChars(env, juser, user);
|
||||
}
|
||||
|
||||
if (pass != NULL) {
|
||||
(*env)->ReleaseStringUTFChars(env, jpass, pass);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -245,64 +278,53 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeQueryImp(
|
|||
jbyteArray jsql, jlong con) {
|
||||
TAOS *tscon = (TAOS *)con;
|
||||
if (tscon == NULL) {
|
||||
jniError("jobj:%p, connection is already closed", jobj);
|
||||
jniError("jobj:%p, connection already closed", jobj);
|
||||
return JNI_CONNECTION_NULL;
|
||||
}
|
||||
|
||||
if (jsql == NULL) {
|
||||
jniError("jobj:%p, conn:%p, sql is null", jobj, tscon);
|
||||
jniError("jobj:%p, conn:%p, empty sql string", jobj, tscon);
|
||||
return JNI_SQL_NULL;
|
||||
}
|
||||
|
||||
jsize len = (*env)->GetArrayLength(env, jsql);
|
||||
|
||||
char *dst = (char *)calloc(1, sizeof(char) * (len + 1));
|
||||
if (dst == NULL) {
|
||||
jniError("jobj:%p, conn:%p, can not alloc memory", jobj, tscon);
|
||||
char *str = (char *) calloc(1, sizeof(char) * (len + 1));
|
||||
if (str == NULL) {
|
||||
jniError("jobj:%p, conn:%p, alloc memory failed", jobj, tscon);
|
||||
return JNI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
(*env)->GetByteArrayRegion(env, jsql, 0, len, (jbyte *)dst);
|
||||
(*env)->GetByteArrayRegion(env, jsql, 0, len, (jbyte *)str);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
// todo handle error
|
||||
}
|
||||
|
||||
jniDebug("jobj:%p, conn:%p, sql:%s", jobj, tscon, dst);
|
||||
|
||||
SSqlObj *pSql = taos_query(tscon, dst);
|
||||
SSqlObj *pSql = taos_query(tscon, str);
|
||||
int32_t code = taos_errno(pSql);
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
jniError("jobj:%p, conn:%p, code:%s, msg:%s", jobj, tscon, tstrerror(code), taos_errstr(pSql));
|
||||
} else {
|
||||
int32_t affectRows = 0;
|
||||
if (pSql->cmd.command == TSDB_SQL_INSERT) {
|
||||
affectRows = taos_affected_rows(pSql);
|
||||
int32_t affectRows = taos_affected_rows(pSql);
|
||||
jniDebug("jobj:%p, conn:%p, code:%s, affect rows:%d", jobj, tscon, tstrerror(code), affectRows);
|
||||
} else {
|
||||
jniDebug("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code));
|
||||
}
|
||||
}
|
||||
|
||||
free(dst);
|
||||
return (jlong)pSql;
|
||||
free(str);
|
||||
return (jlong) pSql;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getErrCodeImp(JNIEnv *env, jobject jobj, jlong con, jlong tres) {
|
||||
TAOS *tscon = (TAOS *)con;
|
||||
if (tscon == NULL) {
|
||||
jniError("jobj:%p, connection is closed", jobj);
|
||||
return (jint)TSDB_CODE_TSC_INVALID_CONNECTION;
|
||||
int32_t code = check_for_params(jobj, con, tres);
|
||||
if (code != JNI_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
if ((void *)tres == NULL) {
|
||||
jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon);
|
||||
return JNI_RESULT_SET_NULL;
|
||||
}
|
||||
|
||||
TAOS_RES *pSql = (TAOS_RES *)tres;
|
||||
|
||||
return (jint)taos_errno(pSql);
|
||||
return (jint)taos_errno((TAOS_RES*) tres);
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getErrMsgImp(JNIEnv *env, jobject jobj, jlong tres) {
|
||||
|
@ -313,23 +335,16 @@ JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getErrMsgImp(J
|
|||
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultSetImp(JNIEnv *env, jobject jobj, jlong con,
|
||||
jlong tres) {
|
||||
TAOS *tscon = (TAOS *)con;
|
||||
if (tscon == NULL) {
|
||||
jniError("jobj:%p, connection is closed", jobj);
|
||||
return JNI_CONNECTION_NULL;
|
||||
}
|
||||
|
||||
if ((void *)tres == NULL) {
|
||||
jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon);
|
||||
return JNI_RESULT_SET_NULL;
|
||||
int32_t code = check_for_params(jobj, con, tres);
|
||||
if (code != JNI_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
SSqlObj *pSql = (TAOS_RES *)tres;
|
||||
STscObj *pObj = pSql->pTscObj;
|
||||
|
||||
if (tscIsUpdateQuery(pSql)) {
|
||||
jniDebug("jobj:%p, conn:%p, update query, no resultset, %p", jobj, pObj, (void *)tres);
|
||||
jniDebug("jobj:%p, conn:%p, update query, no resultset, %p", jobj, tscon, (void *)tres);
|
||||
} else {
|
||||
jniDebug("jobj:%p, conn:%p, get resultset, %p", jobj, pObj, (void *)tres);
|
||||
jniDebug("jobj:%p, conn:%p, get resultset, %p", jobj, tscon, (void *)tres);
|
||||
}
|
||||
|
||||
return tres;
|
||||
|
@ -337,15 +352,9 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultSetImp(
|
|||
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_isUpdateQueryImp(JNIEnv *env, jobject jobj, jlong con,
|
||||
jlong tres) {
|
||||
TAOS *tscon = (TAOS *)con;
|
||||
if (tscon == NULL) {
|
||||
jniError("jobj:%p, connection is closed", jobj);
|
||||
return JNI_CONNECTION_NULL;
|
||||
}
|
||||
|
||||
if ((void *)tres == NULL) {
|
||||
jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon);
|
||||
return JNI_RESULT_SET_NULL;
|
||||
int32_t code = check_for_params(jobj, con, tres);
|
||||
if (code != JNI_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
SSqlObj *pSql = (TAOS_RES *)tres;
|
||||
|
@ -355,37 +364,27 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_isUpdateQueryImp(
|
|||
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_freeResultSetImp(JNIEnv *env, jobject jobj, jlong con,
|
||||
jlong res) {
|
||||
TAOS *tscon = (TAOS *)con;
|
||||
if (tscon == NULL) {
|
||||
jniError("jobj:%p, connection is closed", jobj);
|
||||
return JNI_CONNECTION_NULL;
|
||||
}
|
||||
|
||||
if ((void *)res == NULL) {
|
||||
jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon);
|
||||
return JNI_RESULT_SET_NULL;
|
||||
int32_t code = check_for_params(jobj, con, res);
|
||||
if (code != JNI_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
taos_free_result((void *)res);
|
||||
jniDebug("jobj:%p, conn:%p, free resultset:%p", jobj, tscon, (void *)res);
|
||||
jniDebug("jobj:%p, conn:%p, free resultset:%p", jobj, (TAOS*) con, (void *)res);
|
||||
|
||||
return JNI_SUCCESS;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getAffectedRowsImp(JNIEnv *env, jobject jobj, jlong con,
|
||||
jlong res) {
|
||||
TAOS *tscon = (TAOS *)con;
|
||||
if (tscon == NULL) {
|
||||
jniError("jobj:%p, connection is closed", jobj);
|
||||
return JNI_CONNECTION_NULL;
|
||||
}
|
||||
|
||||
if ((void *)res == NULL) {
|
||||
jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon);
|
||||
return JNI_RESULT_SET_NULL;
|
||||
int32_t code = check_for_params(jobj, con, res);
|
||||
if (code != JNI_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
jint ret = taos_affected_rows((SSqlObj *)res);
|
||||
jniDebug("jobj:%p, conn:%p, sql:%p, res: %p, affect rows:%d", jobj, tscon, (void *)con, (void *)res, (int32_t)ret);
|
||||
jniDebug("jobj:%p, conn:%p, sql:%p, res: %p, affect rows:%d", jobj, tscon, (TAOS *)con, (TAOS_RES *)res, (int32_t)ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -394,27 +393,20 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getSchemaMetaData
|
|||
jlong con, jlong res,
|
||||
jobject arrayListObj) {
|
||||
TAOS *tscon = (TAOS *)con;
|
||||
if (tscon == NULL) {
|
||||
jniError("jobj:%p, connection is closed", jobj);
|
||||
return JNI_CONNECTION_NULL;
|
||||
int32_t code = check_for_params(jobj, con, res);
|
||||
if (code != JNI_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
TAOS_RES *result = (TAOS_RES *)res;
|
||||
if (result == NULL) {
|
||||
jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon);
|
||||
return JNI_RESULT_SET_NULL;
|
||||
}
|
||||
|
||||
TAOS_FIELD *fields = taos_fetch_fields(result);
|
||||
int num_fields = taos_num_fields(result);
|
||||
|
||||
// jobject arrayListObj = (*env)->NewObject(env, g_arrayListClass, g_arrayListConstructFp, "");
|
||||
TAOS_RES* tres = (TAOS_RES*) res;
|
||||
TAOS_FIELD *fields = taos_fetch_fields(tres);
|
||||
|
||||
int32_t num_fields = taos_num_fields(tres);
|
||||
if (num_fields == 0) {
|
||||
jniError("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, (void *)res, num_fields);
|
||||
jniError("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, tres, num_fields);
|
||||
return JNI_NUM_OF_FIELDS_0;
|
||||
} else {
|
||||
jniDebug("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, (void *)res, num_fields);
|
||||
jniDebug("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, tres, num_fields);
|
||||
for (int i = 0; i < num_fields; ++i) {
|
||||
jobject metadataObj = (*env)->NewObject(env, g_metadataClass, g_metadataConstructFp);
|
||||
(*env)->SetIntField(env, metadataObj, g_metadataColtypeField, fields[i].type);
|
||||
|
@ -457,21 +449,21 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn
|
|||
}
|
||||
|
||||
TAOS_FIELD *fields = taos_fetch_fields(result);
|
||||
int num_fields = taos_num_fields(result);
|
||||
|
||||
if (num_fields == 0) {
|
||||
jniError("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, (void*)res, num_fields);
|
||||
int32_t numOfFields = taos_num_fields(result);
|
||||
if (numOfFields == 0) {
|
||||
jniError("jobj:%p, conn:%p, resultset:%p, fields size %d", jobj, tscon, (void*)res, numOfFields);
|
||||
return JNI_NUM_OF_FIELDS_0;
|
||||
}
|
||||
|
||||
TAOS_ROW row = taos_fetch_row(result);
|
||||
if (row == NULL) {
|
||||
int tserrno = taos_errno(result);
|
||||
if (tserrno == 0) {
|
||||
jniDebug("jobj:%p, conn:%p, resultset:%p, fields size is %d, fetch row to the end", jobj, tscon, (void*)res, num_fields);
|
||||
int code = taos_errno(result);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
jniDebug("jobj:%p, conn:%p, resultset:%p, fields size is %d, fetch row to the end", jobj, tscon, (void*)res, numOfFields);
|
||||
return JNI_FETCH_END;
|
||||
} else {
|
||||
jniDebug("jobj:%p, conn:%p, interruptted query", jobj, tscon);
|
||||
jniDebug("jobj:%p, conn:%p, interrupted query", jobj, tscon);
|
||||
return JNI_RESULT_SET_NULL;
|
||||
}
|
||||
}
|
||||
|
@ -480,7 +472,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn
|
|||
|
||||
char tmp[TSDB_MAX_BYTES_PER_ROW] = {0};
|
||||
|
||||
for (int i = 0; i < num_fields; i++) {
|
||||
for (int i = 0; i < numOfFields; i++) {
|
||||
if (row[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
@ -534,6 +526,45 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn
|
|||
return JNI_SUCCESS;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchBlockImp(JNIEnv *env, jobject jobj, jlong con,
|
||||
jlong res, jobject rowobj) {
|
||||
TAOS * tscon = (TAOS *)con;
|
||||
int32_t code = check_for_params(jobj, con, res);
|
||||
if (code != JNI_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
TAOS_RES * tres = (TAOS_RES *)res;
|
||||
TAOS_FIELD *fields = taos_fetch_fields(tres);
|
||||
|
||||
int32_t numOfFields = taos_num_fields(tres);
|
||||
assert(numOfFields > 0);
|
||||
|
||||
TAOS_ROW row = NULL;
|
||||
int32_t numOfRows = taos_fetch_block(tres, &row);
|
||||
if (numOfRows == 0) {
|
||||
code = taos_errno(tres);
|
||||
if (code == JNI_SUCCESS) {
|
||||
jniDebug("jobj:%p, conn:%p, resultset:%p, numOfFields:%d, no data to retrieve", jobj, tscon, (void *)res,
|
||||
numOfFields);
|
||||
return JNI_FETCH_END;
|
||||
} else {
|
||||
jniDebug("jobj:%p, conn:%p, query interrupted", jobj, tscon);
|
||||
return JNI_RESULT_SET_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
(*env)->CallVoidMethod(env, rowobj, g_blockdataSetNumOfRowsFp, (jint)numOfRows);
|
||||
(*env)->CallVoidMethod(env, rowobj, g_blockdataSetNumOfColsFp, (jint)numOfFields);
|
||||
|
||||
for (int i = 0; i < numOfFields; i++) {
|
||||
(*env)->CallVoidMethod(env, rowobj, g_blockdataSetByteArrayFp, i, fields[i].bytes * numOfRows,
|
||||
jniFromNCharToByteArray(env, (char *)row[i], fields[i].bytes * numOfRows));
|
||||
}
|
||||
|
||||
return JNI_SUCCESS;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeConnectionImp(JNIEnv *env, jobject jobj,
|
||||
jlong con) {
|
||||
TAOS *tscon = (TAOS *)con;
|
||||
|
@ -589,7 +620,6 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_consumeImp(JNIEn
|
|||
jniGetGlobalMethod(env);
|
||||
|
||||
TAOS_SUB *tsub = (TAOS_SUB *)sub;
|
||||
|
||||
TAOS_RES *res = taos_consume(tsub);
|
||||
|
||||
if (res == NULL) {
|
||||
|
@ -621,16 +651,16 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_validateCreateTab
|
|||
|
||||
jsize len = (*env)->GetArrayLength(env, jsql);
|
||||
|
||||
char *dst = (char *)calloc(1, sizeof(char) * (len + 1));
|
||||
(*env)->GetByteArrayRegion(env, jsql, 0, len, (jbyte *)dst);
|
||||
char *str = (char *)calloc(1, sizeof(char) * (len + 1));
|
||||
(*env)->GetByteArrayRegion(env, jsql, 0, len, (jbyte *)str);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
// todo handle error
|
||||
}
|
||||
|
||||
int code = taos_validate_sql(tscon, dst);
|
||||
int code = taos_validate_sql(tscon, str);
|
||||
jniDebug("jobj:%p, conn:%p, code is %d", jobj, tscon, code);
|
||||
|
||||
free(dst);
|
||||
free(str);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,8 +91,8 @@ void taos_query_a(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *pa
|
|||
int32_t sqlLen = (int32_t)strlen(sqlstr);
|
||||
if (sqlLen > tsMaxSQLStringLen) {
|
||||
tscError("sql string exceeds max length:%d", tsMaxSQLStringLen);
|
||||
terrno = TSDB_CODE_TSC_INVALID_SQL;
|
||||
tscQueueAsyncError(fp, param, TSDB_CODE_TSC_INVALID_SQL);
|
||||
terrno = TSDB_CODE_TSC_EXCEED_SQL_LIMIT;
|
||||
tscQueueAsyncError(fp, param, terrno);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -130,11 +130,11 @@ typedef struct STopBotInfo {
|
|||
} STopBotInfo;
|
||||
|
||||
// leastsquares do not apply to super table
|
||||
typedef struct SLeastsquareInfo {
|
||||
typedef struct SLeastsquaresInfo {
|
||||
double mat[2][3];
|
||||
double startVal;
|
||||
int64_t num;
|
||||
} SLeastsquareInfo;
|
||||
} SLeastsquaresInfo;
|
||||
|
||||
typedef struct SAPercentileInfo {
|
||||
SHistogramInfo *pHisto;
|
||||
|
@ -316,7 +316,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
|||
*interBytes = (int16_t)sizeof(SPercentileInfo);
|
||||
} else if (functionId == TSDB_FUNC_LEASTSQR) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = TSDB_AVG_FUNCTION_INTER_BUFFER_SIZE; // string
|
||||
*bytes = MAX(TSDB_AVG_FUNCTION_INTER_BUFFER_SIZE, sizeof(SLeastsquaresInfo)); // string
|
||||
*interBytes = *bytes;
|
||||
} else if (functionId == TSDB_FUNC_FIRST_DST || functionId == TSDB_FUNC_LAST_DST) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
|
@ -681,7 +681,7 @@ static int32_t firstFuncRequired(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, i
|
|||
}
|
||||
|
||||
// no result for first query, data block is required
|
||||
if (GET_RES_INFO(pCtx)->numOfRes <= 0) {
|
||||
if (GET_RES_INFO(pCtx) == NULL || GET_RES_INFO(pCtx)->numOfRes <= 0) {
|
||||
return BLK_DATA_ALL_NEEDED;
|
||||
} else {
|
||||
return BLK_DATA_NO_NEEDED;
|
||||
|
@ -693,7 +693,7 @@ static int32_t lastFuncRequired(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, in
|
|||
return BLK_DATA_NO_NEEDED;
|
||||
}
|
||||
|
||||
if (GET_RES_INFO(pCtx)->numOfRes <= 0) {
|
||||
if (GET_RES_INFO(pCtx) == NULL || GET_RES_INFO(pCtx)->numOfRes <= 0) {
|
||||
return BLK_DATA_ALL_NEEDED;
|
||||
} else {
|
||||
return BLK_DATA_NO_NEEDED;
|
||||
|
@ -2756,7 +2756,7 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx) {
|
|||
}
|
||||
|
||||
SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
|
||||
SLeastsquareInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
// 2*3 matrix
|
||||
pInfo->startVal = pCtx->param[0].dKey;
|
||||
|
@ -2783,7 +2783,7 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx) {
|
|||
|
||||
static void leastsquares_function(SQLFunctionCtx *pCtx) {
|
||||
SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
|
||||
SLeastsquareInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
double(*param)[3] = pInfo->mat;
|
||||
double x = pInfo->startVal;
|
||||
|
@ -2853,40 +2853,40 @@ static void leastsquares_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
|||
return;
|
||||
}
|
||||
|
||||
SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
|
||||
SLeastsquareInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
double(*param)[3] = pInfo->mat;
|
||||
|
||||
switch (pCtx->inputType) {
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
int32_t *p = pData;
|
||||
LEASTSQR_CAL(param, pInfo->startVal, p, index, pCtx->param[1].dKey);
|
||||
LEASTSQR_CAL(param, pInfo->startVal, p, 0, pCtx->param[1].dKey);
|
||||
break;
|
||||
};
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
int8_t *p = pData;
|
||||
LEASTSQR_CAL(param, pInfo->startVal, p, index, pCtx->param[1].dKey);
|
||||
LEASTSQR_CAL(param, pInfo->startVal, p, 0, pCtx->param[1].dKey);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
int16_t *p = pData;
|
||||
LEASTSQR_CAL(param, pInfo->startVal, p, index, pCtx->param[1].dKey);
|
||||
LEASTSQR_CAL(param, pInfo->startVal, p, 0, pCtx->param[1].dKey);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t *p = pData;
|
||||
LEASTSQR_CAL(param, pInfo->startVal, p, index, pCtx->param[1].dKey);
|
||||
LEASTSQR_CAL(param, pInfo->startVal, p, 0, pCtx->param[1].dKey);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float *p = pData;
|
||||
LEASTSQR_CAL(param, pInfo->startVal, p, index, pCtx->param[1].dKey);
|
||||
LEASTSQR_CAL(param, pInfo->startVal, p, 0, pCtx->param[1].dKey);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double *p = pData;
|
||||
LEASTSQR_CAL(param, pInfo->startVal, p, index, pCtx->param[1].dKey);
|
||||
LEASTSQR_CAL(param, pInfo->startVal, p, 0, pCtx->param[1].dKey);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -2904,15 +2904,10 @@ static void leastsquares_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
|||
static void leastsquares_finalizer(SQLFunctionCtx *pCtx) {
|
||||
// no data in query
|
||||
SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
|
||||
SLeastsquareInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
if (pInfo->num == 0) {
|
||||
if (pCtx->outputType == TSDB_DATA_TYPE_BINARY || pCtx->outputType == TSDB_DATA_TYPE_NCHAR) {
|
||||
setVardataNull(pCtx->aOutputBuf, pCtx->outputType);
|
||||
} else {
|
||||
setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
|
||||
}
|
||||
|
||||
setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -341,7 +341,7 @@ TAOS_ROW tscFetchRow(void *param) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void* data = doSetResultRowData(pSql, true);
|
||||
void* data = doSetResultRowData(pSql);
|
||||
|
||||
tscClearSqlOwner(pSql);
|
||||
return data;
|
||||
|
|
|
@ -30,8 +30,6 @@ typedef struct SCompareParam {
|
|||
int32_t groupOrderType;
|
||||
} SCompareParam;
|
||||
|
||||
static void doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize);
|
||||
|
||||
int32_t treeComparator(const void *pLeft, const void *pRight, void *param) {
|
||||
int32_t pLeftIdx = *(int32_t *)pLeft;
|
||||
int32_t pRightIdx = *(int32_t *)pRight;
|
||||
|
@ -174,14 +172,14 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
SSqlRes* pRes = &pSql->res;
|
||||
|
||||
if (pMemBuffer == NULL) {
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer);
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
tscError("%p pMemBuffer is NULL", pMemBuffer);
|
||||
pRes->code = TSDB_CODE_TSC_APP_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (pDesc->pColumnModel == NULL) {
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer);
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
tscError("%p no local buffer or intermediate result format model", pSql);
|
||||
pRes->code = TSDB_CODE_TSC_APP_ERROR;
|
||||
return;
|
||||
|
@ -199,7 +197,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
}
|
||||
|
||||
if (numOfFlush == 0 || numOfBuffer == 0) {
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer);
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
tscDebug("%p retrieved no data", pSql);
|
||||
return;
|
||||
}
|
||||
|
@ -208,7 +206,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
tscError("%p Invalid value of buffer capacity %d and page size %d ", pSql, pDesc->pColumnModel->capacity,
|
||||
pMemBuffer[0]->pageSize);
|
||||
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer);
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
pRes->code = TSDB_CODE_TSC_APP_ERROR;
|
||||
return;
|
||||
}
|
||||
|
@ -219,7 +217,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
if (pReducer == NULL) {
|
||||
tscError("%p failed to create local merge structure, out of memory", pSql);
|
||||
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer);
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return;
|
||||
}
|
||||
|
@ -336,6 +334,8 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
pReducer->resColModel = finalmodel;
|
||||
pReducer->resColModel->capacity = pReducer->nResultBufSize;
|
||||
|
||||
pReducer->finalModel = pFFModel;
|
||||
|
||||
assert(pReducer->finalRowSize > 0);
|
||||
if (pReducer->finalRowSize > 0) {
|
||||
pReducer->resColModel->capacity /= pReducer->finalRowSize;
|
||||
|
@ -533,7 +533,7 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
|
|||
tfree(pLocalReducer->pFinalRes);
|
||||
tfree(pLocalReducer->discardData);
|
||||
|
||||
tscLocalReducerEnvDestroy(pLocalReducer->pExtMemBuffer, pLocalReducer->pDesc, pLocalReducer->resColModel,
|
||||
tscLocalReducerEnvDestroy(pLocalReducer->pExtMemBuffer, pLocalReducer->pDesc, pLocalReducer->resColModel, pLocalReducer->finalModel,
|
||||
pLocalReducer->numOfVnode);
|
||||
for (int32_t i = 0; i < pLocalReducer->numOfBuffer; ++i) {
|
||||
tfree(pLocalReducer->pLocalDataSrc[i]);
|
||||
|
@ -657,7 +657,7 @@ bool isSameGroup(SSqlCmd *pCmd, SLocalReducer *pReducer, char *pPrev, tFilePage
|
|||
}
|
||||
|
||||
int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pOrderDesc,
|
||||
SColumnModel **pFinalModel, uint32_t nBufferSizes) {
|
||||
SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSizes) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
|
@ -755,6 +755,18 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
|
||||
*pFinalModel = createColumnModel(pSchema, (int32_t)size, capacity);
|
||||
|
||||
memset(pSchema, 0, sizeof(SSchema) * size);
|
||||
size = tscNumOfFields(pQueryInfo);
|
||||
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
SInternalField* pField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i);
|
||||
pSchema[i].bytes = pField->field.bytes;
|
||||
pSchema[i].type = pField->field.type;
|
||||
tstrncpy(pSchema[i].name, pField->field.name, tListLen(pSchema[i].name));
|
||||
}
|
||||
|
||||
*pFFModel = createColumnModel(pSchema, (int32_t) size, capacity);
|
||||
|
||||
tfree(pSchema);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -765,9 +777,11 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
* @param pFinalModel
|
||||
* @param numOfVnodes
|
||||
*/
|
||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel,
|
||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, SColumnModel *pFFModel,
|
||||
int32_t numOfVnodes) {
|
||||
destroyColumnModel(pFinalModel);
|
||||
destroyColumnModel(pFFModel);
|
||||
|
||||
tOrderDescDestroy(pDesc);
|
||||
|
||||
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
||||
|
@ -870,17 +884,17 @@ static void genFinalResWithoutFill(SSqlRes* pRes, SLocalReducer *pLocalReducer,
|
|||
tFilePage * pBeforeFillData = pLocalReducer->pResultBuf;
|
||||
|
||||
pRes->data = pLocalReducer->pFinalRes;
|
||||
pRes->numOfRows = pBeforeFillData->num;
|
||||
pRes->numOfRows = (int32_t) pBeforeFillData->num;
|
||||
|
||||
if (pQueryInfo->limit.offset > 0) {
|
||||
if (pQueryInfo->limit.offset < pRes->numOfRows) {
|
||||
int32_t prevSize = (int32_t)pBeforeFillData->num;
|
||||
tColModelErase(pLocalReducer->resColModel, pBeforeFillData, prevSize, 0, (int32_t)pQueryInfo->limit.offset - 1);
|
||||
int32_t prevSize = (int32_t) pBeforeFillData->num;
|
||||
tColModelErase(pLocalReducer->finalModel, pBeforeFillData, prevSize, 0, (int32_t)pQueryInfo->limit.offset - 1);
|
||||
|
||||
/* remove the hole in column model */
|
||||
tColModelCompact(pLocalReducer->resColModel, pBeforeFillData, prevSize);
|
||||
tColModelCompact(pLocalReducer->finalModel, pBeforeFillData, prevSize);
|
||||
|
||||
pRes->numOfRows -= pQueryInfo->limit.offset;
|
||||
pRes->numOfRows -= (int32_t) pQueryInfo->limit.offset;
|
||||
pQueryInfo->limit.offset = 0;
|
||||
} else {
|
||||
pQueryInfo->limit.offset -= pRes->numOfRows;
|
||||
|
@ -900,7 +914,7 @@ static void genFinalResWithoutFill(SSqlRes* pRes, SLocalReducer *pLocalReducer,
|
|||
pRes->numOfRows -= overflow;
|
||||
pBeforeFillData->num -= overflow;
|
||||
|
||||
tColModelCompact(pLocalReducer->resColModel, pBeforeFillData, prevSize);
|
||||
tColModelCompact(pLocalReducer->finalModel, pBeforeFillData, prevSize);
|
||||
|
||||
// set remain data to be discarded, and reset the interpolation information
|
||||
savePrevRecordAndSetupFillInfo(pLocalReducer, pQueryInfo, pLocalReducer->pFillInfo);
|
||||
|
@ -948,7 +962,7 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO
|
|||
}
|
||||
|
||||
pRes->data = pLocalReducer->pFinalRes;
|
||||
pRes->numOfRows = newRows;
|
||||
pRes->numOfRows = (int32_t) newRows;
|
||||
|
||||
pQueryInfo->limit.offset = 0;
|
||||
break;
|
||||
|
@ -1242,7 +1256,7 @@ bool genFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool noMoreCur
|
|||
tColModelCompact(pModel, pResBuf, pModel->capacity);
|
||||
|
||||
if (tscIsSecondStageQuery(pQueryInfo)) {
|
||||
doArithmeticCalculate(pQueryInfo, pResBuf, pModel->rowSize, pLocalReducer->finalRowSize);
|
||||
pLocalReducer->finalRowSize = doArithmeticCalculate(pQueryInfo, pResBuf, pModel->rowSize, pLocalReducer->finalRowSize);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_VIEW
|
||||
|
@ -1612,7 +1626,7 @@ void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen)
|
|||
pRes->data = pRes->pLocalReducer->pResultBuf->data;
|
||||
}
|
||||
|
||||
void doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize) {
|
||||
int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize) {
|
||||
char* pbuf = calloc(1, pOutput->num * rowSize);
|
||||
|
||||
size_t size = tscNumOfFields(pQueryInfo);
|
||||
|
@ -1637,7 +1651,7 @@ void doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t r
|
|||
// calculate the result from several other columns
|
||||
if (pSup->pArithExprInfo != NULL) {
|
||||
arithSup.pArithExpr = pSup->pArithExprInfo;
|
||||
tExprTreeCalcTraverse(arithSup.pArithExpr->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithemicInputSrc);
|
||||
tExprTreeCalcTraverse(arithSup.pArithExpr->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithmeticInputSrc);
|
||||
} else {
|
||||
SSqlExpr* pExpr = pSup->pSqlExpr;
|
||||
memcpy(pbuf + pOutput->num * offset, pExpr->offset * pOutput->num + pOutput->data, pExpr->resBytes * pOutput->num);
|
||||
|
@ -1647,8 +1661,10 @@ void doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t r
|
|||
}
|
||||
|
||||
assert(finalRowSize <= rowSize);
|
||||
memcpy(pOutput->data, pbuf, pOutput->num * finalRowSize);
|
||||
memcpy(pOutput->data, pbuf, pOutput->num * offset);
|
||||
|
||||
tfree(pbuf);
|
||||
tfree(arithSup.data);
|
||||
|
||||
return offset;
|
||||
}
|
|
@ -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;
|
||||
short size = (short)*bind->length;
|
||||
STR_WITH_SIZE_TO_VARSTR(data + param->offset, bind->buffer, size);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
|
|
|
@ -1454,13 +1454,13 @@ static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo) {
|
|||
}
|
||||
}
|
||||
|
||||
SColumnIndex index = {0};
|
||||
|
||||
// set the constant column value always attached to first table.
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, PRIMARYKEY_TIMESTAMP_COL_INDEX);
|
||||
|
||||
// add the timestamp column into the output columns
|
||||
SColumnIndex index = {0}; // primary timestamp column info
|
||||
int32_t numOfCols = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
|
||||
tscAddSpecialColumnForSelect(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &index, pSchema, TSDB_COL_NORMAL);
|
||||
|
||||
|
@ -2432,6 +2432,8 @@ int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColum
|
|||
if (pTableToken->n == 0) { // only one table and no table name prefix in column name
|
||||
if (pQueryInfo->numOfTables == 1) {
|
||||
pIndex->tableIndex = 0;
|
||||
} else {
|
||||
pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -3950,9 +3952,6 @@ static void doExtractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo*
|
|||
return;
|
||||
}
|
||||
|
||||
SStrToken t = {0};
|
||||
extractTableNameFromToken(&pLeft->colInfo, &t);
|
||||
|
||||
*pOut = *pExpr;
|
||||
(*pExpr) = NULL;
|
||||
|
||||
|
@ -4187,7 +4186,7 @@ static void cleanQueryExpr(SCondExpr* pCondExpr) {
|
|||
static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
SColumnIndex index = {0};
|
||||
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||
|
||||
if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
||||
tscError("%p: invalid column name (left)", pQueryInfo);
|
||||
|
@ -4604,7 +4603,7 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQu
|
|||
}
|
||||
|
||||
SStrToken columnName = {pVar->nLen, pVar->nType, pVar->pz};
|
||||
SColumnIndex index = {0};
|
||||
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||
|
||||
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { // super table query
|
||||
if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
||||
|
@ -5509,7 +5508,9 @@ void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
|
|||
|
||||
tscAddSpecialColumnForSelect(pQueryInfo, (int32_t)size, TSDB_FUNC_PRJ, &colIndex, pSchema, TSDB_COL_NORMAL);
|
||||
|
||||
SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, (int32_t)size);
|
||||
int32_t numOfFields = tscNumOfFields(pQueryInfo);
|
||||
SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfFields - 1);
|
||||
|
||||
doLimitOutputNormalColOfGroupby(pInfo->pSqlExpr);
|
||||
pInfo->visible = false;
|
||||
}
|
||||
|
@ -6412,7 +6413,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
|||
return code;
|
||||
}
|
||||
|
||||
tVariantListItem* p1 = taosArrayGet(pQuerySql->from, i);
|
||||
tVariantListItem* p1 = taosArrayGet(pQuerySql->from, i + 1);
|
||||
if (p1->pVar.nType != TSDB_DATA_TYPE_BINARY) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
|
||||
}
|
||||
|
@ -6620,7 +6621,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS
|
|||
}
|
||||
}
|
||||
} else if (pSqlExpr->nSQLOptr == TK_ID) { // column name, normal column arithmetic expression
|
||||
SColumnIndex index = {0};
|
||||
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||
int32_t ret = getColumnIndexByName(pCmd, &pSqlExpr->colInfo, pQueryInfo, &index);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
|
|
|
@ -547,7 +547,7 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) {
|
|||
int32_t srcColListSize = (int32_t)(taosArrayGetSize(pQueryInfo->colList) * sizeof(SColumnInfo));
|
||||
|
||||
size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
int32_t exprSize = (int32_t)(sizeof(SSqlFuncMsg) * numOfExprs);
|
||||
int32_t exprSize = (int32_t)(sizeof(SSqlFuncMsg) * numOfExprs * 2);
|
||||
|
||||
int32_t tsBufSize = (pQueryInfo->tsBuf != NULL) ? pQueryInfo->tsBuf->fileSize : 0;
|
||||
|
||||
|
@ -787,8 +787,9 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
pSqlFuncExpr = (SSqlFuncMsg *)pMsg;
|
||||
}
|
||||
|
||||
if(tscIsSecondStageQuery(pQueryInfo)) {
|
||||
size_t output = tscNumOfFields(pQueryInfo);
|
||||
size_t output = tscNumOfFields(pQueryInfo);
|
||||
|
||||
if (tscIsSecondStageQuery(pQueryInfo)) {
|
||||
pQueryMsg->secondStageOutput = htonl((int32_t) output);
|
||||
|
||||
SSqlFuncMsg *pSqlFuncExpr1 = (SSqlFuncMsg *)pMsg;
|
||||
|
@ -1437,19 +1438,6 @@ int tscBuildRetrieveFromMgmtMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int tscSetResultPointer(SQueryInfo *pQueryInfo, SSqlRes *pRes) {
|
||||
if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) {
|
||||
return pRes->code;
|
||||
}
|
||||
|
||||
for (int i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
|
||||
int16_t offset = tscFieldInfoGetOffset(pQueryInfo, i);
|
||||
pRes->tsrow[i] = (unsigned char*)((char*) pRes->data + offset * pRes->numOfRows);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* this function can only be called once.
|
||||
* by using pRes->rspType to denote its status
|
||||
|
@ -1460,15 +1448,18 @@ static int tscLocalResultCommonBuilder(SSqlObj *pSql, int32_t numOfRes) {
|
|||
SSqlRes *pRes = &pSql->res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
pRes->code = TSDB_CODE_SUCCESS;
|
||||
if (pRes->rspType == 0) {
|
||||
pRes->numOfRows = numOfRes;
|
||||
pRes->row = 0;
|
||||
pRes->rspType = 1;
|
||||
|
||||
tscSetResultPointer(pQueryInfo, pRes);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) {
|
||||
return pRes->code;
|
||||
}
|
||||
|
||||
tscSetResRawPtr(pRes, pQueryInfo);
|
||||
} else {
|
||||
tscResetForNextRetrieve(pRes);
|
||||
}
|
||||
|
@ -1512,10 +1503,11 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
pRes->code = tscDoLocalMerge(pSql);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) {
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
tscCreateResPointerInfo(pRes, pQueryInfo);
|
||||
tscSetResRawPtr(pRes, pQueryInfo);
|
||||
}
|
||||
|
||||
pRes->row = 0;
|
||||
|
@ -2195,7 +2187,16 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) {
|
|||
if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) {
|
||||
return pRes->code;
|
||||
}
|
||||
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
if (pCmd->command == TSDB_SQL_RETRIEVE) {
|
||||
tscSetResRawPtr(pRes, pQueryInfo);
|
||||
} else if ((UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo) || UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) && !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_SUBQUERY)) {
|
||||
tscSetResRawPtr(pRes, pQueryInfo);
|
||||
} else if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) && !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY) && !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)) {
|
||||
tscSetResRawPtr(pRes, pQueryInfo);
|
||||
}
|
||||
|
||||
if (pSql->pSubscription != NULL) {
|
||||
int32_t numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
|
||||
|
||||
|
@ -2217,7 +2218,7 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
pRes->row = 0;
|
||||
tscDebug("%p numOfRows:%" PRId64 ", offset:%" PRId64 ", complete:%d", pSql, pRes->numOfRows, pRes->offset, pRes->completed);
|
||||
tscDebug("%p numOfRows:%d, offset:%" PRId64 ", complete:%d", pSql, pRes->numOfRows, pRes->offset, pRes->completed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -321,7 +321,7 @@ TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen, TAOS_RES
|
|||
|
||||
if (sqlLen > (uint32_t)tsMaxSQLStringLen) {
|
||||
tscError("sql string exceeds max length:%d", tsMaxSQLStringLen);
|
||||
terrno = TSDB_CODE_TSC_INVALID_SQL;
|
||||
terrno = TSDB_CODE_TSC_EXCEED_SQL_LIMIT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -394,7 +394,7 @@ int taos_affected_rows(TAOS_RES *tres) {
|
|||
SSqlObj* pSql = (SSqlObj*) tres;
|
||||
if (pSql == NULL || pSql->signature != pSql) return 0;
|
||||
|
||||
return (int)(pSql->res.numOfRows);
|
||||
return pSql->res.numOfRows;
|
||||
}
|
||||
|
||||
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
|
||||
|
@ -443,50 +443,30 @@ int taos_retrieve(TAOS_RES *res) {
|
|||
if (pCmd->command < TSDB_SQL_LOCAL) {
|
||||
pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH;
|
||||
}
|
||||
tscProcessSql(pSql);
|
||||
|
||||
return (int)pRes->numOfRows;
|
||||
tscProcessSql(pSql);
|
||||
return pRes->numOfRows;
|
||||
}
|
||||
|
||||
int taos_fetch_block_impl(TAOS_RES *res, TAOS_ROW *rows) {
|
||||
SSqlObj *pSql = (SSqlObj *)res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
static bool needToFetchNewBlock(SSqlObj* pSql) {
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
if (pRes->qhandle == 0 || pSql->signature != pSql) {
|
||||
*rows = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Retrieve new block
|
||||
tscResetForNextRetrieve(pRes);
|
||||
if (pCmd->command < TSDB_SQL_LOCAL) {
|
||||
pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH;
|
||||
}
|
||||
|
||||
tscProcessSql(pSql);
|
||||
if (pRes->numOfRows == 0) {
|
||||
*rows = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// secondary merge has handle this situation
|
||||
if (pCmd->command != TSDB_SQL_RETRIEVE_LOCALMERGE) {
|
||||
pRes->numOfClauseTotal += pRes->numOfRows;
|
||||
}
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
if (pQueryInfo == NULL)
|
||||
return 0;
|
||||
|
||||
assert(0);
|
||||
for (int i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
|
||||
tscGetResultColumnChr(pRes, &pQueryInfo->fieldsInfo, i, 0);
|
||||
}
|
||||
|
||||
*rows = pRes->tsrow;
|
||||
|
||||
return (int)((pQueryInfo->order.order == TSDB_ORDER_DESC) ? pRes->numOfRows : -pRes->numOfRows);
|
||||
return (pRes->completed != true || hasMoreVnodesToTry(pSql) || hasMoreClauseToTry(pSql)) &&
|
||||
(pCmd->command == TSDB_SQL_RETRIEVE ||
|
||||
pCmd->command == TSDB_SQL_RETRIEVE_LOCALMERGE ||
|
||||
pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE ||
|
||||
pCmd->command == TSDB_SQL_FETCH ||
|
||||
pCmd->command == TSDB_SQL_SHOW ||
|
||||
pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE ||
|
||||
pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE ||
|
||||
pCmd->command == TSDB_SQL_SELECT ||
|
||||
pCmd->command == TSDB_SQL_DESCRIBE_TABLE ||
|
||||
pCmd->command == TSDB_SQL_SERV_STATUS ||
|
||||
pCmd->command == TSDB_SQL_CURRENT_DB ||
|
||||
pCmd->command == TSDB_SQL_SERV_VERSION ||
|
||||
pCmd->command == TSDB_SQL_CLI_VERSION ||
|
||||
pCmd->command == TSDB_SQL_CURRENT_USER);
|
||||
}
|
||||
|
||||
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
|
||||
|
@ -509,77 +489,50 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
|
|||
// set the sql object owner
|
||||
tscSetSqlOwner(pSql);
|
||||
|
||||
// current data set are exhausted, fetch more data from node
|
||||
if (pRes->row >= pRes->numOfRows && (pRes->completed != true || hasMoreVnodesToTry(pSql) || hasMoreClauseToTry(pSql)) &&
|
||||
(pCmd->command == TSDB_SQL_RETRIEVE ||
|
||||
pCmd->command == TSDB_SQL_RETRIEVE_LOCALMERGE ||
|
||||
pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE ||
|
||||
pCmd->command == TSDB_SQL_FETCH ||
|
||||
pCmd->command == TSDB_SQL_SHOW ||
|
||||
pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE ||
|
||||
pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE ||
|
||||
pCmd->command == TSDB_SQL_SELECT ||
|
||||
pCmd->command == TSDB_SQL_DESCRIBE_TABLE ||
|
||||
pCmd->command == TSDB_SQL_SERV_STATUS ||
|
||||
pCmd->command == TSDB_SQL_CURRENT_DB ||
|
||||
pCmd->command == TSDB_SQL_SERV_VERSION ||
|
||||
pCmd->command == TSDB_SQL_CLI_VERSION ||
|
||||
pCmd->command == TSDB_SQL_CURRENT_USER )) {
|
||||
// current data set are exhausted, fetch more result from node
|
||||
if (pRes->row >= pRes->numOfRows && needToFetchNewBlock(pSql)) {
|
||||
taos_fetch_rows_a(res, waitForRetrieveRsp, pSql->pTscObj);
|
||||
tsem_wait(&pSql->rspSem);
|
||||
}
|
||||
|
||||
void* data = doSetResultRowData(pSql, true);
|
||||
void* data = doSetResultRowData(pSql);
|
||||
|
||||
tscClearSqlOwner(pSql);
|
||||
return data;
|
||||
}
|
||||
|
||||
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
|
||||
#if 0
|
||||
SSqlObj *pSql = (SSqlObj *)res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
int nRows = 0;
|
||||
|
||||
if (pSql == NULL || pSql->signature != pSql) {
|
||||
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||
*rows = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// projection query on metric, pipeline retrieve data from vnode list,
|
||||
// instead of two-stage mergednodeProcessMsgFromShell free qhandle
|
||||
nRows = taos_fetch_block_impl(res, rows);
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
// current subclause is completed, try the next subclause
|
||||
while (rows == NULL && pCmd->clauseIndex < pCmd->numOfClause - 1) {
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
pSql->cmd.command = pQueryInfo->command;
|
||||
pCmd->clauseIndex++;
|
||||
|
||||
pRes->numOfTotal += pRes->numOfClauseTotal;
|
||||
pRes->numOfClauseTotal = 0;
|
||||
pRes->rspType = 0;
|
||||
|
||||
pSql->subState.numOfSub = 0;
|
||||
tfree(pSql->pSubs);
|
||||
|
||||
assert(pSql->fp == NULL);
|
||||
|
||||
tscDebug("%p try data in the next subclause:%d, total subclause:%d", pSql, pCmd->clauseIndex, pCmd->numOfClause);
|
||||
tscProcessSql(pSql);
|
||||
|
||||
nRows = taos_fetch_block_impl(res, rows);
|
||||
if (pRes->qhandle == 0 ||
|
||||
pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED ||
|
||||
pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
|
||||
pCmd->command == TSDB_SQL_INSERT) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nRows;
|
||||
#endif
|
||||
tscResetForNextRetrieve(pRes);
|
||||
|
||||
(*rows) = taos_fetch_row(res);
|
||||
return ((*rows) != NULL)? 1:0;
|
||||
// set the sql object owner
|
||||
tscSetSqlOwner(pSql);
|
||||
|
||||
// current data set are exhausted, fetch more data from node
|
||||
if (needToFetchNewBlock(pSql)) {
|
||||
taos_fetch_rows_a(res, waitForRetrieveRsp, pSql->pTscObj);
|
||||
tsem_wait(&pSql->rspSem);
|
||||
}
|
||||
|
||||
*rows = pRes->urow;
|
||||
|
||||
tscClearSqlOwner(pSql);
|
||||
return pRes->numOfRows;
|
||||
}
|
||||
|
||||
int taos_select_db(TAOS *taos, const char *db) {
|
||||
|
@ -600,7 +553,7 @@ int taos_select_db(TAOS *taos, const char *db) {
|
|||
}
|
||||
|
||||
// send free message to vnode to free qhandle and corresponding resources in vnode
|
||||
static UNUSED_FUNC bool tscKillQueryInDnode(SSqlObj* pSql) {
|
||||
static bool tscKillQueryInDnode(SSqlObj* pSql) {
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SSqlRes* pRes = &pSql->res;
|
||||
|
||||
|
@ -795,6 +748,25 @@ void taos_stop_query(TAOS_RES *res) {
|
|||
tscDebug("%p query is cancelled", res);
|
||||
}
|
||||
|
||||
bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
|
||||
SSqlObj *pSql = (SSqlObj *)res;
|
||||
if (pSql == NULL || pSql->signature != pSql) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
||||
if (pQueryInfo == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SInternalField* pInfo = (SInternalField*)TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, col);
|
||||
if (col < 0 || col >= tscNumOfFields(pQueryInfo) || row < 0 || row > pSql->res.numOfRows) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return isNull(((char*) pSql->res.urow[col]) + row * pInfo->field.bytes, pInfo->field.type);
|
||||
}
|
||||
|
||||
int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
|
||||
int len = 0;
|
||||
for (int i = 0; i < num_fields; ++i) {
|
||||
|
@ -892,18 +864,16 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
int32_t sqlLen = (int32_t)strlen(sql);
|
||||
if (sqlLen > tsMaxSQLStringLen) {
|
||||
tscError("%p sql too long", pSql);
|
||||
pRes->code = TSDB_CODE_TSC_INVALID_SQL;
|
||||
tfree(pSql);
|
||||
return pRes->code;
|
||||
return TSDB_CODE_TSC_EXCEED_SQL_LIMIT;
|
||||
}
|
||||
|
||||
pSql->sqlstr = realloc(pSql->sqlstr, sqlLen + 1);
|
||||
if (pSql->sqlstr == NULL) {
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tscError("%p failed to malloc sql string buffer", pSql);
|
||||
tscDebug("%p Valid SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(pSql), pObj);
|
||||
tfree(pSql);
|
||||
return pRes->code;
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
strtolower(pSql->sqlstr, sql);
|
||||
|
|
|
@ -594,7 +594,7 @@ void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArr
|
|||
|
||||
if (taosArrayGetSize(result) > 0) {
|
||||
SVgroupTableInfo* prevGroup = taosArrayGet(result, taosArrayGetSize(result) - 1);
|
||||
tscDebug("%p vgId:%d, tables:%"PRId64, pSql, prevGroup->vgInfo.vgId, taosArrayGetSize(prevGroup->itemList));
|
||||
tscDebug("%p vgId:%d, tables:%"PRIzu, pSql, prevGroup->vgInfo.vgId, taosArrayGetSize(prevGroup->itemList));
|
||||
}
|
||||
|
||||
taosArrayPush(result, &info);
|
||||
|
@ -612,7 +612,7 @@ void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArr
|
|||
|
||||
if (taosArrayGetSize(result) > 0) {
|
||||
SVgroupTableInfo* g = taosArrayGet(result, taosArrayGetSize(result) - 1);
|
||||
tscDebug("%p vgId:%d, tables:%"PRId64, pSql, g->vgInfo.vgId, taosArrayGetSize(g->itemList));
|
||||
tscDebug("%p vgId:%d, tables:%"PRIzu, pSql, g->vgInfo.vgId, taosArrayGetSize(g->itemList));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -753,7 +753,7 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar
|
|||
}
|
||||
#endif
|
||||
|
||||
tscDebug("%p tags match complete, result: %"PRId64", %"PRId64, pParentSql, t1, t2);
|
||||
tscDebug("%p tags match complete, result: %"PRIzu", %"PRIzu, pParentSql, t1, t2);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -948,7 +948,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
|||
if (!pRes->completed) {
|
||||
taosGetTmpfilePath("ts-join", pSupporter->path);
|
||||
pSupporter->f = fopen(pSupporter->path, "w");
|
||||
pRes->row = (int32_t)pRes->numOfRows;
|
||||
pRes->row = pRes->numOfRows;
|
||||
|
||||
taos_fetch_rows_a(tres, tsCompRetrieveCallback, param);
|
||||
return;
|
||||
|
@ -974,7 +974,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
|||
|
||||
// TODO check for failure
|
||||
pSupporter->f = fopen(pSupporter->path, "w");
|
||||
pRes->row = (int32_t)pRes->numOfRows;
|
||||
pRes->row = pRes->numOfRows;
|
||||
|
||||
// set the callback function
|
||||
pSql->fp = tscJoinQueryCallback;
|
||||
|
@ -1085,7 +1085,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
|
|||
SSqlRes* pRes1 = &pParentSql->pSubs[i]->res;
|
||||
|
||||
if (pRes1->row > 0 && pRes1->numOfRows > 0) {
|
||||
tscDebug("%p sub:%p index:%d numOfRows:%"PRId64" total:%"PRId64 " (not retrieve)", pParentSql, pParentSql->pSubs[i], i,
|
||||
tscDebug("%p sub:%p index:%d numOfRows:%d total:%"PRId64 " (not retrieve)", pParentSql, pParentSql->pSubs[i], i,
|
||||
pRes1->numOfRows, pRes1->numOfTotal);
|
||||
assert(pRes1->row < pRes1->numOfRows);
|
||||
} else {
|
||||
|
@ -1093,7 +1093,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
|
|||
pRes1->numOfClauseTotal += pRes1->numOfRows;
|
||||
}
|
||||
|
||||
tscDebug("%p sub:%p index:%d numOfRows:%"PRId64" total:%"PRId64, pParentSql, pParentSql->pSubs[i], i,
|
||||
tscDebug("%p sub:%p index:%d numOfRows:%d total:%"PRId64, pParentSql, pParentSql->pSubs[i], i,
|
||||
pRes1->numOfRows, pRes1->numOfTotal);
|
||||
}
|
||||
}
|
||||
|
@ -1644,6 +1644,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
|||
tExtMemBuffer ** pMemoryBuf = NULL;
|
||||
tOrderDescriptor *pDesc = NULL;
|
||||
SColumnModel *pModel = NULL;
|
||||
SColumnModel *pFinalModel = NULL;
|
||||
|
||||
pRes->qhandle = 0x1; // hack the qhandle check
|
||||
|
||||
|
@ -1662,7 +1663,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
|||
|
||||
assert(pState->numOfSub > 0);
|
||||
|
||||
int32_t ret = tscLocalReducerEnvCreate(pSql, &pMemoryBuf, &pDesc, &pModel, nBufferSize);
|
||||
int32_t ret = tscLocalReducerEnvCreate(pSql, &pMemoryBuf, &pDesc, &pModel, &pFinalModel, nBufferSize);
|
||||
if (ret != 0) {
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tscQueueAsyncRes(pSql);
|
||||
|
@ -1677,7 +1678,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
|||
if (pSql->pSubs == NULL) {
|
||||
tfree(pSql->pSubs);
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pState->numOfSub);
|
||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pFinalModel,pState->numOfSub);
|
||||
|
||||
tscQueueAsyncRes(pSql);
|
||||
return ret;
|
||||
|
@ -1707,6 +1708,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
|||
trs->subqueryIndex = i;
|
||||
trs->pParentSql = pSql;
|
||||
trs->pFinalColModel = pModel;
|
||||
trs->pFFColModel = pFinalModel;
|
||||
|
||||
SSqlObj *pNew = tscCreateSTableSubquery(pSql, trs, NULL);
|
||||
if (pNew == NULL) {
|
||||
|
@ -1730,13 +1732,13 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
|||
tscError("%p failed to prepare subquery structure and launch subqueries", pSql);
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
|
||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pState->numOfSub);
|
||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pFinalModel, pState->numOfSub);
|
||||
doCleanupSubqueries(pSql, i);
|
||||
return pRes->code; // free all allocated resource
|
||||
}
|
||||
|
||||
if (pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED) {
|
||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pState->numOfSub);
|
||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pFinalModel, pState->numOfSub);
|
||||
doCleanupSubqueries(pSql, i);
|
||||
return pRes->code;
|
||||
}
|
||||
|
@ -1876,7 +1878,7 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO
|
|||
tstrerror(pParentSql->res.code));
|
||||
|
||||
// release allocated resource
|
||||
tscLocalReducerEnvDestroy(trsupport->pExtMemBuffer, trsupport->pOrderDescriptor, trsupport->pFinalColModel,
|
||||
tscLocalReducerEnvDestroy(trsupport->pExtMemBuffer, trsupport->pOrderDescriptor, trsupport->pFinalColModel, trsupport->pFFColModel,
|
||||
pState->numOfSub);
|
||||
|
||||
tscFreeRetrieveSup(pSql);
|
||||
|
@ -2030,7 +2032,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR
|
|||
assert(pRes->numOfRows == numOfRows);
|
||||
int64_t num = atomic_add_fetch_64(&pState->numOfRetrievedRows, numOfRows);
|
||||
|
||||
tscDebug("%p sub:%p retrieve numOfRows:%" PRId64 " totalNumOfRows:%" PRIu64 " from ep:%s, orderOfSub:%d", pParentSql, pSql,
|
||||
tscDebug("%p sub:%p retrieve numOfRows:%d totalNumOfRows:%" PRIu64 " from ep:%s, orderOfSub:%d", pParentSql, pSql,
|
||||
pRes->numOfRows, pState->numOfRetrievedRows, pSql->epSet.fqdn[pSql->epSet.inUse], idx);
|
||||
|
||||
if (num > tsMaxNumOfOrderedResults && tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||
|
@ -2057,7 +2059,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR
|
|||
}
|
||||
|
||||
int32_t ret = saveToBuffer(trsupport->pExtMemBuffer[idx], pDesc, trsupport->localBuffer, pRes->data,
|
||||
(int32_t)pRes->numOfRows, pQueryInfo->groupbyExpr.orderType);
|
||||
pRes->numOfRows, pQueryInfo->groupbyExpr.orderType);
|
||||
if (ret != 0) { // set no disk space error info, and abort retry
|
||||
tscAbortFurtherRetryRetrieval(trsupport, tres, TSDB_CODE_TSC_NO_DISKSPACE);
|
||||
} else if (pRes->completed) {
|
||||
|
@ -2169,7 +2171,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
|
|||
return;
|
||||
}
|
||||
|
||||
tscDebug("%p Async insertion completed, total inserted:%" PRId64, pParentObj, pParentObj->res.numOfRows);
|
||||
tscDebug("%p Async insertion completed, total inserted:%d", pParentObj, pParentObj->res.numOfRows);
|
||||
|
||||
// restore user defined fp
|
||||
pParentObj->fp = pParentObj->fetchFp;
|
||||
|
@ -2312,10 +2314,10 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) {
|
|||
return;
|
||||
}
|
||||
|
||||
int32_t totalSize = tscGetResRowLength(pQueryInfo->exprList);
|
||||
int32_t rowSize = tscGetResRowLength(pQueryInfo->exprList);
|
||||
|
||||
assert(numOfRes * totalSize > 0);
|
||||
char* tmp = realloc(pRes->pRsp, numOfRes * totalSize);
|
||||
assert(numOfRes * rowSize > 0);
|
||||
char* tmp = realloc(pRes->pRsp, numOfRes * rowSize + sizeof(tFilePage));
|
||||
if (tmp == NULL) {
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return;
|
||||
|
@ -2323,9 +2325,12 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) {
|
|||
pRes->pRsp = tmp;
|
||||
}
|
||||
|
||||
pRes->data = pRes->pRsp;
|
||||
tFilePage* pFilePage = (tFilePage*) pRes->pRsp;
|
||||
pFilePage->num = numOfRes;
|
||||
|
||||
pRes->data = pFilePage->data;
|
||||
char* data = pRes->data;
|
||||
|
||||
int16_t bytes = 0;
|
||||
|
||||
size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
|
@ -2352,6 +2357,17 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) {
|
|||
|
||||
pRes->numOfRows = numOfRes;
|
||||
pRes->numOfClauseTotal += numOfRes;
|
||||
|
||||
int32_t finalRowSize = 0;
|
||||
for(int32_t i = 0; i < tscNumOfFields(pQueryInfo); ++i) {
|
||||
TAOS_FIELD* pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
|
||||
finalRowSize += pField->bytes;
|
||||
}
|
||||
|
||||
doArithmeticCalculate(pQueryInfo, pFilePage, rowSize, finalRowSize);
|
||||
|
||||
pRes->data = pFilePage->data;
|
||||
tscSetResRawPtr(pRes, pQueryInfo);
|
||||
}
|
||||
|
||||
void tscBuildResFromSubqueries(SSqlObj *pSql) {
|
||||
|
@ -2364,13 +2380,12 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
|
|||
|
||||
if (pRes->tsrow == NULL) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
|
||||
pRes->numOfCols = (int16_t) tscSqlExprNumOfExprs(pQueryInfo);
|
||||
|
||||
size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
pRes->numOfCols = (int16_t)numOfExprs;
|
||||
|
||||
pRes->tsrow = calloc(numOfExprs, POINTER_BYTES);
|
||||
pRes->buffer = calloc(numOfExprs, POINTER_BYTES);
|
||||
pRes->length = calloc(numOfExprs, sizeof(int32_t));
|
||||
pRes->tsrow = calloc(pRes->numOfCols, POINTER_BYTES);
|
||||
pRes->urow = calloc(pRes->numOfCols, POINTER_BYTES);
|
||||
pRes->buffer = calloc(pRes->numOfCols, POINTER_BYTES);
|
||||
pRes->length = calloc(pRes->numOfCols, sizeof(int32_t));
|
||||
|
||||
if (pRes->tsrow == NULL || pRes->buffer == NULL || pRes->length == NULL) {
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
|
@ -2390,7 +2405,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
|
|||
}
|
||||
}
|
||||
|
||||
static void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pField) {
|
||||
static UNUSED_FUNC void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pField) {
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
if (pRes->tsrow[columnIndex] != NULL && pField->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
|
@ -2414,7 +2429,7 @@ static void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pF
|
|||
}
|
||||
}
|
||||
|
||||
char *getArithemicInputSrc(void *param, const char *name, int32_t colId) {
|
||||
char *getArithmeticInputSrc(void *param, const char *name, int32_t colId) {
|
||||
SArithmeticSupport *pSupport = (SArithmeticSupport *) param;
|
||||
|
||||
int32_t index = -1;
|
||||
|
@ -2432,7 +2447,7 @@ char *getArithemicInputSrc(void *param, const char *name, int32_t colId) {
|
|||
return pSupport->data[index] + pSupport->offset * pExpr->resBytes;
|
||||
}
|
||||
|
||||
TAOS_ROW doSetResultRowData(SSqlObj *pSql, bool finalResult) {
|
||||
TAOS_ROW doSetResultRowData(SSqlObj *pSql) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
|
@ -2445,22 +2460,20 @@ TAOS_ROW doSetResultRowData(SSqlObj *pSql, bool finalResult) {
|
|||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
size_t size = tscNumOfFields(pQueryInfo);
|
||||
int32_t offset = 0;
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
tscGetResultColumnChr(pRes, &pQueryInfo->fieldsInfo, i, offset);
|
||||
TAOS_FIELD *pField = TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, i);
|
||||
SInternalField* pInfo = (SInternalField*)TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, i);
|
||||
|
||||
offset += pField->bytes;
|
||||
int32_t type = pInfo->field.type;
|
||||
int32_t bytes = pInfo->field.bytes;
|
||||
|
||||
// primary key column cannot be null in interval query, no need to check
|
||||
if (i == 0 && pQueryInfo->interval.interval > 0) {
|
||||
continue;
|
||||
if (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR) {
|
||||
pRes->tsrow[i] = isNull(pRes->urow[i], type) ? NULL : pRes->urow[i];
|
||||
} else {
|
||||
pRes->tsrow[i] = isNull(pRes->urow[i], type) ? NULL : varDataVal(pRes->urow[i]);
|
||||
pRes->length[i] = varDataLen(pRes->urow[i]);
|
||||
}
|
||||
|
||||
if (pRes->tsrow[i] != NULL && pField->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
transferNcharData(pSql, i, pField);
|
||||
}
|
||||
((char**) pRes->urow)[i] += bytes;
|
||||
}
|
||||
|
||||
pRes->row++; // index increase one-step
|
||||
|
|
|
@ -220,13 +220,11 @@ bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo) {
|
|||
}
|
||||
|
||||
bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo) {
|
||||
size_t numOfOutput = tscNumOfFields(pQueryInfo);
|
||||
size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
|
||||
if (numOfOutput == numOfExprs) {
|
||||
if (tscIsProjectionQuery(pQueryInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t numOfOutput = tscNumOfFields(pQueryInfo);
|
||||
for(int32_t i = 0; i < numOfOutput; ++i) {
|
||||
SExprInfo* pExprInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i)->pArithExprInfo;
|
||||
if (pExprInfo != NULL) {
|
||||
|
@ -265,16 +263,20 @@ void tscClearInterpInfo(SQueryInfo* pQueryInfo) {
|
|||
|
||||
int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
|
||||
if (pRes->tsrow == NULL) {
|
||||
int32_t numOfOutput = pQueryInfo->fieldsInfo.numOfOutput;
|
||||
pRes->numOfCols = numOfOutput;
|
||||
pRes->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
|
||||
|
||||
pRes->tsrow = calloc(numOfOutput, POINTER_BYTES);
|
||||
pRes->length = calloc(numOfOutput, sizeof(int32_t));
|
||||
pRes->buffer = calloc(numOfOutput, POINTER_BYTES);
|
||||
pRes->tsrow = calloc(pRes->numOfCols, POINTER_BYTES);
|
||||
pRes->urow = calloc(pRes->numOfCols, POINTER_BYTES);
|
||||
pRes->length = calloc(pRes->numOfCols, sizeof(int32_t));
|
||||
pRes->buffer = calloc(pRes->numOfCols, POINTER_BYTES);
|
||||
|
||||
// not enough memory
|
||||
if (pRes->tsrow == NULL || (pRes->buffer == NULL && pRes->numOfCols > 0)) {
|
||||
if (pRes->tsrow == NULL || pRes->urow == NULL || pRes->length == NULL || (pRes->buffer == NULL && pRes->numOfCols > 0)) {
|
||||
tfree(pRes->tsrow);
|
||||
tfree(pRes->urow);
|
||||
tfree(pRes->length);
|
||||
tfree(pRes->buffer);
|
||||
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return pRes->code;
|
||||
}
|
||||
|
@ -283,6 +285,71 @@ int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
|
||||
assert(pRes->numOfCols > 0);
|
||||
|
||||
int32_t offset = 0;
|
||||
|
||||
for (int32_t i = 0; i < pRes->numOfCols; ++i) {
|
||||
SInternalField* pInfo = (SInternalField*)TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, i);
|
||||
|
||||
pRes->urow[i] = pRes->data + offset * pRes->numOfRows;
|
||||
pRes->length[i] = pInfo->field.bytes;
|
||||
|
||||
offset += pInfo->field.bytes;
|
||||
|
||||
// generated the user-defined column result
|
||||
if (pInfo->pSqlExpr != NULL && TSDB_COL_IS_UD_COL(pInfo->pSqlExpr->colInfo.flag)) {
|
||||
if (pInfo->pSqlExpr->param[1].nType == TSDB_DATA_TYPE_NULL) {
|
||||
setNullN(pRes->urow[i], pInfo->field.type, pInfo->field.bytes, (int32_t) pRes->numOfRows);
|
||||
} else {
|
||||
if (pInfo->field.type == TSDB_DATA_TYPE_NCHAR || pInfo->field.type == TSDB_DATA_TYPE_BINARY) {
|
||||
assert(pInfo->pSqlExpr->param[1].nLen <= pInfo->field.bytes);
|
||||
|
||||
for (int32_t k = 0; k < pRes->numOfRows; ++k) {
|
||||
char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes;
|
||||
|
||||
memcpy(varDataVal(p), pInfo->pSqlExpr->param[1].pz, pInfo->pSqlExpr->param[1].nLen);
|
||||
varDataSetLen(p, pInfo->pSqlExpr->param[1].nLen);
|
||||
}
|
||||
} else {
|
||||
for (int32_t k = 0; k < pRes->numOfRows; ++k) {
|
||||
char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes;
|
||||
memcpy(p, &pInfo->pSqlExpr->param[1].i64Key, pInfo->field.bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (pInfo->field.type == TSDB_DATA_TYPE_NCHAR) {
|
||||
// convert unicode to native code in a temporary buffer extra one byte for terminated symbol
|
||||
pRes->buffer[i] = realloc(pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows);
|
||||
|
||||
// string terminated char for binary data
|
||||
memset(pRes->buffer[i], 0, pInfo->field.bytes * pRes->numOfRows);
|
||||
|
||||
char* p = pRes->urow[i];
|
||||
for (int32_t k = 0; k < pRes->numOfRows; ++k) {
|
||||
char* dst = pRes->buffer[i] + k * pInfo->field.bytes;
|
||||
|
||||
if (isNull(p, TSDB_DATA_TYPE_NCHAR)) {
|
||||
memcpy(dst, p, varDataTLen(p));
|
||||
} else {
|
||||
int32_t length = taosUcs4ToMbs(varDataVal(p), varDataLen(p), varDataVal(dst));
|
||||
varDataSetLen(dst, length);
|
||||
|
||||
if (length == 0) {
|
||||
tscError("charset:%s to %s. val:%s convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, (char*)p);
|
||||
}
|
||||
}
|
||||
|
||||
p += pInfo->field.bytes;
|
||||
}
|
||||
|
||||
memcpy(pRes->urow[i], pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void tscDestroyResPointerInfo(SSqlRes* pRes) {
|
||||
if (pRes->buffer != NULL) { // free all buffers containing the multibyte string
|
||||
for (int i = 0; i < pRes->numOfCols; i++) {
|
||||
|
@ -297,6 +364,7 @@ static void tscDestroyResPointerInfo(SSqlRes* pRes) {
|
|||
tfree(pRes->tsrow);
|
||||
tfree(pRes->length);
|
||||
tfree(pRes->buffer);
|
||||
tfree(pRes->urow);
|
||||
|
||||
tfree(pRes->pGroupRec);
|
||||
tfree(pRes->pColumnIndex);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d598db167eb256fe67409b7bb3d0eb7fffc3ff8c
|
||||
Subproject commit ec77d9049a719dabfd1a7c1122a209e201861944
|
|
@ -56,6 +56,23 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- for restful -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.58</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
package com.taosdata.jdbc;
|
||||
|
||||
import java.io.*;
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverPropertyInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public abstract class AbstractTaosDriver implements Driver {
|
||||
|
||||
private static final String TAOS_CFG_FILENAME = "taos.cfg";
|
||||
|
||||
/**
|
||||
* @param cfgDirPath
|
||||
* @return return the config dir
|
||||
**/
|
||||
protected File loadConfigDir(String cfgDirPath) {
|
||||
if (cfgDirPath == null)
|
||||
return loadDefaultConfigDir();
|
||||
File cfgDir = new File(cfgDirPath);
|
||||
if (!cfgDir.exists())
|
||||
return loadDefaultConfigDir();
|
||||
return cfgDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return search the default config dir, if the config dir is not exist will return null
|
||||
*/
|
||||
protected File loadDefaultConfigDir() {
|
||||
File cfgDir;
|
||||
File cfgDir_linux = new File("/etc/taos");
|
||||
cfgDir = cfgDir_linux.exists() ? cfgDir_linux : null;
|
||||
File cfgDir_windows = new File("C:\\TDengine\\cfg");
|
||||
cfgDir = (cfgDir == null && cfgDir_windows.exists()) ? cfgDir_windows : cfgDir;
|
||||
return cfgDir;
|
||||
}
|
||||
|
||||
protected List<String> loadConfigEndpoints(File cfgFile) {
|
||||
List<String> endpoints = new ArrayList<>();
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(cfgFile))) {
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.trim().startsWith("firstEp") || line.trim().startsWith("secondEp")) {
|
||||
endpoints.add(line.substring(line.indexOf('p') + 1).trim());
|
||||
}
|
||||
if (endpoints.size() > 1)
|
||||
break;
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return endpoints;
|
||||
}
|
||||
|
||||
protected void loadTaosConfig(Properties info) {
|
||||
if ((info.getProperty(TSDBDriver.PROPERTY_KEY_HOST) == null ||
|
||||
info.getProperty(TSDBDriver.PROPERTY_KEY_HOST).isEmpty()) && (
|
||||
info.getProperty(TSDBDriver.PROPERTY_KEY_PORT) == null ||
|
||||
info.getProperty(TSDBDriver.PROPERTY_KEY_PORT).isEmpty())) {
|
||||
File cfgDir = loadConfigDir(info.getProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR));
|
||||
File cfgFile = cfgDir.listFiles((dir, name) -> TAOS_CFG_FILENAME.equalsIgnoreCase(name))[0];
|
||||
List<String> endpoints = loadConfigEndpoints(cfgFile);
|
||||
if (!endpoints.isEmpty()) {
|
||||
info.setProperty(TSDBDriver.PROPERTY_KEY_HOST, endpoints.get(0).split(":")[0]);
|
||||
info.setProperty(TSDBDriver.PROPERTY_KEY_PORT, endpoints.get(0).split(":")[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected DriverPropertyInfo[] getPropertyInfo(Properties info) {
|
||||
DriverPropertyInfo hostProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_HOST, info.getProperty(TSDBDriver.PROPERTY_KEY_HOST));
|
||||
hostProp.required = false;
|
||||
hostProp.description = "Hostname";
|
||||
|
||||
DriverPropertyInfo portProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_PORT, info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, TSDBConstants.DEFAULT_PORT));
|
||||
portProp.required = false;
|
||||
portProp.description = "Port";
|
||||
|
||||
DriverPropertyInfo dbProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_DBNAME, info.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME));
|
||||
dbProp.required = false;
|
||||
dbProp.description = "Database name";
|
||||
|
||||
DriverPropertyInfo userProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_USER, info.getProperty(TSDBDriver.PROPERTY_KEY_USER));
|
||||
userProp.required = true;
|
||||
userProp.description = "User";
|
||||
|
||||
DriverPropertyInfo passwordProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_PASSWORD, info.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD));
|
||||
passwordProp.required = true;
|
||||
passwordProp.description = "Password";
|
||||
|
||||
DriverPropertyInfo[] propertyInfo = new DriverPropertyInfo[5];
|
||||
propertyInfo[0] = hostProp;
|
||||
propertyInfo[1] = portProp;
|
||||
propertyInfo[2] = dbProp;
|
||||
propertyInfo[3] = userProp;
|
||||
propertyInfo[4] = passwordProp;
|
||||
return propertyInfo;
|
||||
}
|
||||
|
||||
protected Properties parseURL(String url, Properties defaults) {
|
||||
Properties urlProps = (defaults != null) ? defaults : new Properties();
|
||||
|
||||
// parse properties
|
||||
int beginningOfSlashes = url.indexOf("//");
|
||||
int index = url.indexOf("?");
|
||||
if (index != -1) {
|
||||
String paramString = url.substring(index + 1, url.length());
|
||||
url = url.substring(0, index);
|
||||
StringTokenizer queryParams = new StringTokenizer(paramString, "&");
|
||||
while (queryParams.hasMoreElements()) {
|
||||
String parameterValuePair = queryParams.nextToken();
|
||||
int indexOfEqual = parameterValuePair.indexOf("=");
|
||||
String parameter = null;
|
||||
String value = null;
|
||||
if (indexOfEqual != -1) {
|
||||
parameter = parameterValuePair.substring(0, indexOfEqual);
|
||||
if (indexOfEqual + 1 < parameterValuePair.length()) {
|
||||
value = parameterValuePair.substring(indexOfEqual + 1);
|
||||
}
|
||||
}
|
||||
if ((value != null && value.length() > 0) && (parameter != null && parameter.length() > 0)) {
|
||||
urlProps.setProperty(parameter, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parse Product Name
|
||||
String dbProductName = url.substring(0, beginningOfSlashes);
|
||||
dbProductName = dbProductName.substring(dbProductName.indexOf(":") + 1);
|
||||
dbProductName = dbProductName.substring(0, dbProductName.indexOf(":"));
|
||||
// parse dbname
|
||||
url = url.substring(beginningOfSlashes + 2);
|
||||
int indexOfSlash = url.indexOf("/");
|
||||
if (indexOfSlash != -1) {
|
||||
if (indexOfSlash + 1 < url.length()) {
|
||||
urlProps.setProperty(TSDBDriver.PROPERTY_KEY_DBNAME, url.substring(indexOfSlash + 1));
|
||||
}
|
||||
url = url.substring(0, indexOfSlash);
|
||||
}
|
||||
// parse port
|
||||
int indexOfColon = url.indexOf(":");
|
||||
if (indexOfColon != -1) {
|
||||
if (indexOfColon + 1 < url.length()) {
|
||||
urlProps.setProperty(TSDBDriver.PROPERTY_KEY_PORT, url.substring(indexOfColon + 1));
|
||||
}
|
||||
url = url.substring(0, indexOfColon);
|
||||
}
|
||||
// parse host
|
||||
if (url != null && url.length() > 0 && url.trim().length() > 0) {
|
||||
urlProps.setProperty(TSDBDriver.PROPERTY_KEY_HOST, url);
|
||||
}
|
||||
return urlProps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -16,10 +16,10 @@ package com.taosdata.jdbc;
|
|||
|
||||
public class ColumnMetaData {
|
||||
|
||||
int colType = 0;
|
||||
String colName = null;
|
||||
int colSize = -1;
|
||||
int colIndex = 0;
|
||||
private int colType = 0;
|
||||
private String colName = null;
|
||||
private int colSize = -1;
|
||||
private int colIndex = 0;
|
||||
|
||||
public int getColSize() {
|
||||
return colSize;
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
*****************************************************************************/
|
||||
package com.taosdata.jdbc;
|
||||
|
||||
import java.io.*;
|
||||
import java.sql.Array;
|
||||
import java.sql.Blob;
|
||||
import java.sql.CallableStatement;
|
||||
|
@ -35,11 +34,10 @@ import java.util.*;
|
|||
import java.util.concurrent.Executor;
|
||||
|
||||
public class TSDBConnection implements Connection {
|
||||
protected Properties props = null;
|
||||
|
||||
private TSDBJNIConnector connector = null;
|
||||
|
||||
protected Properties props = null;
|
||||
|
||||
private String catalog = null;
|
||||
|
||||
private TSDBDatabaseMetaData dbMetaData = null;
|
||||
|
@ -47,15 +45,21 @@ public class TSDBConnection implements Connection {
|
|||
private Properties clientInfoProps = new Properties();
|
||||
|
||||
private int timeoutMilliseconds = 0;
|
||||
|
||||
private String tsCharSet = "";
|
||||
|
||||
private boolean batchFetch = false;
|
||||
|
||||
public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException {
|
||||
this.dbMetaData = meta;
|
||||
connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST),
|
||||
Integer.parseInt(info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "0")),
|
||||
info.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME), info.getProperty(TSDBDriver.PROPERTY_KEY_USER),
|
||||
info.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME),
|
||||
info.getProperty(TSDBDriver.PROPERTY_KEY_USER),
|
||||
info.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD));
|
||||
|
||||
String batchLoad = info.getProperty(TSDBDriver.PROPERTY_KEY_BATCH_LOAD);
|
||||
if (batchLoad != null) {
|
||||
this.batchFetch = Boolean.parseBoolean(batchLoad);
|
||||
}
|
||||
}
|
||||
|
||||
private void connect(String host, int port, String dbName, String user, String password) throws SQLException {
|
||||
|
@ -223,6 +227,14 @@ public class TSDBConnection implements Connection {
|
|||
|
||||
return this.prepareStatement(sql);
|
||||
}
|
||||
|
||||
public Boolean getBatchFetch() {
|
||||
return this.batchFetch;
|
||||
}
|
||||
|
||||
public void setBatchFetch(Boolean batchFetch) {
|
||||
this.batchFetch = batchFetch;
|
||||
}
|
||||
|
||||
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
*****************************************************************************/
|
||||
package com.taosdata.jdbc;
|
||||
|
||||
import java.io.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
|
@ -38,7 +37,7 @@ import java.util.logging.Logger;
|
|||
* register it with the DriverManager. This means that a user can load and
|
||||
* register a driver by doing Class.forName("foo.bah.Driver")
|
||||
*/
|
||||
public class TSDBDriver implements java.sql.Driver {
|
||||
public class TSDBDriver extends AbstractTaosDriver {
|
||||
|
||||
@Deprecated
|
||||
private static final String URL_PREFIX1 = "jdbc:TSDB://";
|
||||
|
@ -87,6 +86,11 @@ public class TSDBDriver implements java.sql.Driver {
|
|||
*/
|
||||
public static final String PROPERTY_KEY_CHARSET = "charset";
|
||||
|
||||
/**
|
||||
* fetch data from native function in a batch model
|
||||
*/
|
||||
public static final String PROPERTY_KEY_BATCH_LOAD = "batchfetch";
|
||||
|
||||
private TSDBDatabaseMetaData dbMetaData = null;
|
||||
|
||||
static {
|
||||
|
@ -97,50 +101,6 @@ public class TSDBDriver implements java.sql.Driver {
|
|||
}
|
||||
}
|
||||
|
||||
private List<String> loadConfigEndpoints(File cfgFile) {
|
||||
List<String> endpoints = new ArrayList<>();
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(cfgFile))) {
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.trim().startsWith("firstEp") || line.trim().startsWith("secondEp")) {
|
||||
endpoints.add(line.substring(line.indexOf('p') + 1).trim());
|
||||
}
|
||||
if (endpoints.size() > 1)
|
||||
break;
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return endpoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cfgDirPath
|
||||
* @return return the config dir
|
||||
**/
|
||||
private File loadConfigDir(String cfgDirPath) {
|
||||
if (cfgDirPath == null)
|
||||
return loadDefaultConfigDir();
|
||||
File cfgDir = new File(cfgDirPath);
|
||||
if (!cfgDir.exists())
|
||||
return loadDefaultConfigDir();
|
||||
return cfgDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return search the default config dir, if the config dir is not exist will return null
|
||||
*/
|
||||
private File loadDefaultConfigDir() {
|
||||
File cfgDir;
|
||||
File cfgDir_linux = new File("/etc/taos");
|
||||
cfgDir = cfgDir_linux.exists() ? cfgDir_linux : null;
|
||||
File cfgDir_windows = new File("C:\\TDengine\\cfg");
|
||||
cfgDir = (cfgDir == null && cfgDir_windows.exists()) ? cfgDir_windows : cfgDir;
|
||||
return cfgDir;
|
||||
}
|
||||
|
||||
public Connection connect(String url, Properties info) throws SQLException {
|
||||
if (url == null)
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("url is not set!"));
|
||||
|
@ -152,26 +112,12 @@ public class TSDBDriver implements java.sql.Driver {
|
|||
if ((props = parseURL(url, info)) == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//load taos.cfg start
|
||||
if ((info.getProperty(TSDBDriver.PROPERTY_KEY_HOST) == null ||
|
||||
info.getProperty(TSDBDriver.PROPERTY_KEY_HOST).isEmpty()) && (
|
||||
info.getProperty(TSDBDriver.PROPERTY_KEY_PORT) == null ||
|
||||
info.getProperty(TSDBDriver.PROPERTY_KEY_PORT).isEmpty())) {
|
||||
File cfgDir = loadConfigDir(info.getProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR));
|
||||
File cfgFile = cfgDir.listFiles((dir, name) -> "taos.cfg".equalsIgnoreCase(name))[0];
|
||||
List<String> endpoints = loadConfigEndpoints(cfgFile);
|
||||
if (!endpoints.isEmpty()) {
|
||||
info.setProperty(TSDBDriver.PROPERTY_KEY_HOST, endpoints.get(0).split(":")[0]);
|
||||
info.setProperty(TSDBDriver.PROPERTY_KEY_PORT, endpoints.get(0).split(":")[1]);
|
||||
}
|
||||
}
|
||||
loadTaosConfig(info);
|
||||
|
||||
try {
|
||||
TSDBJNIConnector.init((String) props.get(PROPERTY_KEY_CONFIG_DIR),
|
||||
(String) props.get(PROPERTY_KEY_LOCALE),
|
||||
(String) props.get(PROPERTY_KEY_CHARSET),
|
||||
(String) props.get(PROPERTY_KEY_TIME_ZONE));
|
||||
TSDBJNIConnector.init((String) props.get(PROPERTY_KEY_CONFIG_DIR), (String) props.get(PROPERTY_KEY_LOCALE),
|
||||
(String) props.get(PROPERTY_KEY_CHARSET), (String) props.get(PROPERTY_KEY_TIME_ZONE));
|
||||
Connection newConn = new TSDBConnection(props, this.dbMetaData);
|
||||
return newConn;
|
||||
} catch (SQLWarning sqlWarning) {
|
||||
|
@ -208,39 +154,13 @@ public class TSDBDriver implements java.sql.Driver {
|
|||
info = parseURL(url, info);
|
||||
}
|
||||
|
||||
DriverPropertyInfo hostProp = new DriverPropertyInfo(PROPERTY_KEY_HOST, info.getProperty(PROPERTY_KEY_HOST));
|
||||
hostProp.required = false;
|
||||
hostProp.description = "Hostname";
|
||||
|
||||
DriverPropertyInfo portProp = new DriverPropertyInfo(PROPERTY_KEY_PORT, info.getProperty(PROPERTY_KEY_PORT, TSDBConstants.DEFAULT_PORT));
|
||||
portProp.required = false;
|
||||
portProp.description = "Port";
|
||||
|
||||
DriverPropertyInfo dbProp = new DriverPropertyInfo(PROPERTY_KEY_DBNAME, info.getProperty(PROPERTY_KEY_DBNAME));
|
||||
dbProp.required = false;
|
||||
dbProp.description = "Database name";
|
||||
|
||||
DriverPropertyInfo userProp = new DriverPropertyInfo(PROPERTY_KEY_USER, info.getProperty(PROPERTY_KEY_USER));
|
||||
userProp.required = true;
|
||||
userProp.description = "User";
|
||||
|
||||
DriverPropertyInfo passwordProp = new DriverPropertyInfo(PROPERTY_KEY_PASSWORD, info.getProperty(PROPERTY_KEY_PASSWORD));
|
||||
passwordProp.required = true;
|
||||
passwordProp.description = "Password";
|
||||
|
||||
DriverPropertyInfo[] propertyInfo = new DriverPropertyInfo[5];
|
||||
propertyInfo[0] = hostProp;
|
||||
propertyInfo[1] = portProp;
|
||||
propertyInfo[2] = dbProp;
|
||||
propertyInfo[3] = userProp;
|
||||
propertyInfo[4] = passwordProp;
|
||||
|
||||
return propertyInfo;
|
||||
return getPropertyInfo(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* example: jdbc:TAOS://127.0.0.1:0/db?user=root&password=your_password
|
||||
*/
|
||||
@Override
|
||||
public Properties parseURL(String url, Properties defaults) {
|
||||
Properties urlProps = (defaults != null) ? defaults : new Properties();
|
||||
if (url == null || url.length() <= 0 || url.trim().length() <= 0)
|
||||
|
@ -257,26 +177,21 @@ public class TSDBDriver implements java.sql.Driver {
|
|||
url = url.substring(0, index);
|
||||
StringTokenizer queryParams = new StringTokenizer(paramString, "&");
|
||||
while (queryParams.hasMoreElements()) {
|
||||
String parameterValuePair = queryParams.nextToken();
|
||||
int indexOfEqual = parameterValuePair.indexOf("=");
|
||||
String parameter = null;
|
||||
String value = null;
|
||||
if (indexOfEqual != -1) {
|
||||
parameter = parameterValuePair.substring(0, indexOfEqual);
|
||||
if (indexOfEqual + 1 < parameterValuePair.length()) {
|
||||
value = parameterValuePair.substring(indexOfEqual + 1);
|
||||
}
|
||||
}
|
||||
if ((value != null && value.length() > 0) && (parameter != null && parameter.length() > 0)) {
|
||||
urlProps.setProperty(parameter, value);
|
||||
String oneToken = queryParams.nextToken();
|
||||
String[] pair = oneToken.split("=");
|
||||
|
||||
if ((pair[0] != null && pair[0].trim().length() > 0) && (pair[1] != null && pair[1].trim().length() > 0)) {
|
||||
urlProps.setProperty(pair[0].trim(), pair[1].trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parse Product Name
|
||||
String dbProductName = url.substring(0, beginningOfSlashes);
|
||||
dbProductName = dbProductName.substring(dbProductName.indexOf(":") + 1);
|
||||
dbProductName = dbProductName.substring(0, dbProductName.indexOf(":"));
|
||||
// parse dbname
|
||||
|
||||
// parse database name
|
||||
url = url.substring(beginningOfSlashes + 2);
|
||||
int indexOfSlash = url.indexOf("/");
|
||||
if (indexOfSlash != -1) {
|
||||
|
@ -285,6 +200,7 @@ public class TSDBDriver implements java.sql.Driver {
|
|||
}
|
||||
url = url.substring(0, indexOfSlash);
|
||||
}
|
||||
|
||||
// parse port
|
||||
int indexOfColon = url.indexOf(":");
|
||||
if (indexOfColon != -1) {
|
||||
|
@ -293,89 +209,15 @@ public class TSDBDriver implements java.sql.Driver {
|
|||
}
|
||||
url = url.substring(0, indexOfColon);
|
||||
}
|
||||
|
||||
if (url != null && url.length() > 0 && url.trim().length() > 0) {
|
||||
urlProps.setProperty(TSDBDriver.PROPERTY_KEY_HOST, url);
|
||||
}
|
||||
|
||||
|
||||
this.dbMetaData = new TSDBDatabaseMetaData(dbProductName, urlForMeta, urlProps.getProperty(TSDBDriver.PROPERTY_KEY_USER));
|
||||
|
||||
/*
|
||||
String urlForMeta = url;
|
||||
String dbProductName = url.substring(url.indexOf(":") + 1);
|
||||
dbProductName = dbProductName.substring(0, dbProductName.indexOf(":"));
|
||||
int beginningOfSlashes = url.indexOf("//");
|
||||
url = url.substring(beginningOfSlashes + 2);
|
||||
|
||||
String host = url.substring(0, url.indexOf(":"));
|
||||
url = url.substring(url.indexOf(":") + 1);
|
||||
urlProps.setProperty(PROPERTY_KEY_HOST, host);
|
||||
|
||||
String port = url.substring(0, url.indexOf("/"));
|
||||
urlProps.setProperty(PROPERTY_KEY_PORT, port);
|
||||
url = url.substring(url.indexOf("/") + 1);
|
||||
|
||||
if (url.indexOf("?") != -1) {
|
||||
String dbName = url.substring(0, url.indexOf("?"));
|
||||
urlProps.setProperty(PROPERTY_KEY_DBNAME, dbName);
|
||||
url = url.trim().substring(url.indexOf("?") + 1);
|
||||
} else {
|
||||
// without user & password so return
|
||||
if (!url.trim().isEmpty()) {
|
||||
String dbName = url.trim();
|
||||
urlProps.setProperty(PROPERTY_KEY_DBNAME, dbName);
|
||||
}
|
||||
this.dbMetaData = new TSDBDatabaseMetaData(dbProductName, urlForMeta, urlProps.getProperty("user"));
|
||||
return urlProps;
|
||||
}
|
||||
|
||||
String user = "";
|
||||
|
||||
if (url.indexOf("&") == -1) {
|
||||
String[] kvPair = url.trim().split("=");
|
||||
if (kvPair.length == 2) {
|
||||
setPropertyValue(urlProps, kvPair);
|
||||
return urlProps;
|
||||
}
|
||||
}
|
||||
|
||||
String[] queryStrings = url.trim().split("&");
|
||||
for (String queryStr : queryStrings) {
|
||||
String[] kvPair = queryStr.trim().split("=");
|
||||
if (kvPair.length < 2) {
|
||||
continue;
|
||||
}
|
||||
setPropertyValue(urlProps, kvPair);
|
||||
}
|
||||
|
||||
user = urlProps.getProperty(PROPERTY_KEY_USER).toString();
|
||||
this.dbMetaData = new TSDBDatabaseMetaData(dbProductName, urlForMeta, user);
|
||||
*/
|
||||
return urlProps;
|
||||
}
|
||||
|
||||
private void setPropertyValue(Properties property, String[] keyValuePair) {
|
||||
switch (keyValuePair[0].toLowerCase()) {
|
||||
case PROPERTY_KEY_USER:
|
||||
property.setProperty(PROPERTY_KEY_USER, keyValuePair[1]);
|
||||
break;
|
||||
case PROPERTY_KEY_PASSWORD:
|
||||
property.setProperty(PROPERTY_KEY_PASSWORD, keyValuePair[1]);
|
||||
break;
|
||||
case PROPERTY_KEY_TIME_ZONE:
|
||||
property.setProperty(PROPERTY_KEY_TIME_ZONE, keyValuePair[1]);
|
||||
break;
|
||||
case PROPERTY_KEY_LOCALE:
|
||||
property.setProperty(PROPERTY_KEY_LOCALE, keyValuePair[1]);
|
||||
break;
|
||||
case PROPERTY_KEY_CHARSET:
|
||||
property.setProperty(PROPERTY_KEY_CHARSET, keyValuePair[1]);
|
||||
break;
|
||||
case PROPERTY_KEY_CONFIG_DIR:
|
||||
property.setProperty(PROPERTY_KEY_CONFIG_DIR, keyValuePair[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public int getMajorVersion() {
|
||||
return 2;
|
||||
}
|
||||
|
|
|
@ -243,6 +243,11 @@ public class TSDBJNIConnector {
|
|||
|
||||
private native int fetchRowImp(long connection, long resultSet, TSDBResultSetRowData rowData);
|
||||
|
||||
public int fetchBlock(long resultSet, TSDBResultSetBlockData blockData) {
|
||||
return this.fetchBlockImp(this.taos, resultSet, blockData);
|
||||
}
|
||||
|
||||
private native int fetchBlockImp(long connection, long resultSet, TSDBResultSetBlockData blockData);
|
||||
/**
|
||||
* Execute close operation from C to release connection pointer by JNI
|
||||
*
|
||||
|
|
|
@ -47,10 +47,14 @@ public class TSDBResultSet implements ResultSet {
|
|||
private List<ColumnMetaData> columnMetaDataList = new ArrayList<ColumnMetaData>();
|
||||
|
||||
private TSDBResultSetRowData rowData;
|
||||
private TSDBResultSetBlockData blockData;
|
||||
|
||||
private boolean batchFetch = false;
|
||||
private boolean lastWasNull = false;
|
||||
private final int COLUMN_INDEX_START_VALUE = 1;
|
||||
|
||||
private int rowIndex = 0;
|
||||
|
||||
public TSDBJNIConnector getJniConnector() {
|
||||
return jniConnector;
|
||||
}
|
||||
|
@ -67,6 +71,14 @@ public class TSDBResultSet implements ResultSet {
|
|||
this.resultSetPointer = resultSetPointer;
|
||||
}
|
||||
|
||||
public void setBatchFetch(boolean batchFetch) {
|
||||
this.batchFetch = batchFetch;
|
||||
}
|
||||
|
||||
public Boolean getBatchFetch() {
|
||||
return this.batchFetch;
|
||||
}
|
||||
|
||||
public List<ColumnMetaData> getColumnMetaDataList() {
|
||||
return columnMetaDataList;
|
||||
}
|
||||
|
@ -94,8 +106,8 @@ public class TSDBResultSet implements ResultSet {
|
|||
public TSDBResultSet() {
|
||||
}
|
||||
|
||||
public TSDBResultSet(TSDBJNIConnector connecter, long resultSetPointer) throws SQLException {
|
||||
this.jniConnector = connecter;
|
||||
public TSDBResultSet(TSDBJNIConnector connector, long resultSetPointer) throws SQLException {
|
||||
this.jniConnector = connector;
|
||||
this.resultSetPointer = resultSetPointer;
|
||||
int code = this.jniConnector.getSchemaMetaData(this.resultSetPointer, this.columnMetaDataList);
|
||||
if (code == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||
|
@ -107,6 +119,7 @@ public class TSDBResultSet implements ResultSet {
|
|||
}
|
||||
|
||||
this.rowData = new TSDBResultSetRowData(this.columnMetaDataList.size());
|
||||
this.blockData = new TSDBResultSetBlockData(this.columnMetaDataList, this.columnMetaDataList.size());
|
||||
}
|
||||
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
|
@ -118,21 +131,42 @@ public class TSDBResultSet implements ResultSet {
|
|||
}
|
||||
|
||||
public boolean next() throws SQLException {
|
||||
if (rowData != null) {
|
||||
this.rowData.clear();
|
||||
}
|
||||
if (this.getBatchFetch()) {
|
||||
if (this.blockData.forward()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int code = this.jniConnector.fetchBlock(this.resultSetPointer, this.blockData);
|
||||
this.blockData.reset();
|
||||
|
||||
if (code == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
} else if (code == TSDBConstants.JNI_RESULT_SET_NULL) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_RESULT_SET_NULL));
|
||||
} else if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_NUM_OF_FIELDS_0));
|
||||
} else if (code == TSDBConstants.JNI_FETCH_END) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int code = this.jniConnector.fetchRow(this.resultSetPointer, this.rowData);
|
||||
if (code == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
} else if (code == TSDBConstants.JNI_RESULT_SET_NULL) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_RESULT_SET_NULL));
|
||||
} else if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_NUM_OF_FIELDS_0));
|
||||
} else if (code == TSDBConstants.JNI_FETCH_END) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
} else {
|
||||
if (rowData != null) {
|
||||
this.rowData.clear();
|
||||
}
|
||||
|
||||
int code = this.jniConnector.fetchRow(this.resultSetPointer, this.rowData);
|
||||
if (code == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
} else if (code == TSDBConstants.JNI_RESULT_SET_NULL) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_RESULT_SET_NULL));
|
||||
} else if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_NUM_OF_FIELDS_0));
|
||||
} else if (code == TSDBConstants.JNI_FETCH_END) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,21 +189,30 @@ public class TSDBResultSet implements ResultSet {
|
|||
String res = null;
|
||||
int colIndex = getTrueColumnIndex(columnIndex);
|
||||
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getString(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
if (!this.getBatchFetch()) {
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getString(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return this.blockData.getString(colIndex);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean getBoolean(int columnIndex) throws SQLException {
|
||||
boolean res = false;
|
||||
int colIndex = getTrueColumnIndex(columnIndex);
|
||||
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getBoolean(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
if (!this.getBatchFetch()) {
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getBoolean(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
}
|
||||
} else {
|
||||
return this.blockData.getBoolean(colIndex);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -177,66 +220,91 @@ public class TSDBResultSet implements ResultSet {
|
|||
byte res = 0;
|
||||
int colIndex = getTrueColumnIndex(columnIndex);
|
||||
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = (byte) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
if (!this.getBatchFetch()) {
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = (byte) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return (byte) this.blockData.getInt(colIndex);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public short getShort(int columnIndex) throws SQLException {
|
||||
short res = 0;
|
||||
int colIndex = getTrueColumnIndex(columnIndex);
|
||||
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = (short) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
if (!this.getBatchFetch()) {
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = (short) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return (short) this.blockData.getInt(colIndex);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public int getInt(int columnIndex) throws SQLException {
|
||||
int res = 0;
|
||||
int colIndex = getTrueColumnIndex(columnIndex);
|
||||
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
if (!this.getBatchFetch()) {
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return this.blockData.getInt(colIndex);
|
||||
}
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
public long getLong(int columnIndex) throws SQLException {
|
||||
long res = 0l;
|
||||
int colIndex = getTrueColumnIndex(columnIndex);
|
||||
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
if (!this.getBatchFetch()) {
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return this.blockData.getLong(colIndex);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public float getFloat(int columnIndex) throws SQLException {
|
||||
float res = 0;
|
||||
int colIndex = getTrueColumnIndex(columnIndex);
|
||||
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getFloat(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
if (!this.getBatchFetch()) {
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getFloat(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return (float) this.blockData.getDouble(colIndex);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public double getDouble(int columnIndex) throws SQLException {
|
||||
double res = 0;
|
||||
int colIndex = getTrueColumnIndex(columnIndex);
|
||||
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getDouble(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
if (!this.getBatchFetch()) {
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getDouble(colIndex, this.columnMetaDataList.get(colIndex).getColType());
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return this.blockData.getDouble(colIndex);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -249,25 +317,11 @@ public class TSDBResultSet implements ResultSet {
|
|||
*/
|
||||
@Deprecated
|
||||
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
|
||||
BigDecimal res = null;
|
||||
int colIndex = getTrueColumnIndex(columnIndex);
|
||||
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = new BigDecimal(this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType()));
|
||||
}
|
||||
return res;
|
||||
return new BigDecimal(getLong(columnIndex));
|
||||
}
|
||||
|
||||
public byte[] getBytes(int columnIndex) throws SQLException {
|
||||
byte[] res = null;
|
||||
int colIndex = getTrueColumnIndex(columnIndex);
|
||||
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getString(colIndex, this.columnMetaDataList.get(colIndex).getColType()).getBytes();
|
||||
}
|
||||
return res;
|
||||
return getString(columnIndex).getBytes();
|
||||
}
|
||||
|
||||
public Date getDate(int columnIndex) throws SQLException {
|
||||
|
@ -284,11 +338,15 @@ public class TSDBResultSet implements ResultSet {
|
|||
Timestamp res = null;
|
||||
int colIndex = getTrueColumnIndex(columnIndex);
|
||||
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getTimestamp(colIndex);
|
||||
if (!this.getBatchFetch()) {
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
if (!lastWasNull) {
|
||||
res = this.rowData.getTimestamp(colIndex);
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return this.blockData.getTimestamp(columnIndex);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public InputStream getAsciiStream(int columnIndex) throws SQLException {
|
||||
|
@ -400,8 +458,12 @@ public class TSDBResultSet implements ResultSet {
|
|||
public Object getObject(int columnIndex) throws SQLException {
|
||||
int colIndex = getTrueColumnIndex(columnIndex);
|
||||
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
return this.rowData.get(colIndex);
|
||||
if (!this.getBatchFetch()) {
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
return this.rowData.get(colIndex);
|
||||
} else {
|
||||
return this.blockData.get(colIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public Object getObject(String columnLabel) throws SQLException {
|
||||
|
@ -433,8 +495,12 @@ public class TSDBResultSet implements ResultSet {
|
|||
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
|
||||
int colIndex = getTrueColumnIndex(columnIndex);
|
||||
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
return new BigDecimal(this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType()));
|
||||
if (!this.getBatchFetch()) {
|
||||
this.lastWasNull = this.rowData.wasNull(colIndex);
|
||||
return new BigDecimal(this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType()));
|
||||
} else {
|
||||
return new BigDecimal(this.blockData.getLong(colIndex));
|
||||
}
|
||||
}
|
||||
|
||||
public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
|
||||
|
|
|
@ -0,0 +1,497 @@
|
|||
/***************************************************************************
|
||||
* 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/>.
|
||||
*****************************************************************************/
|
||||
package com.taosdata.jdbc;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.DoubleBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
import java.sql.SQLDataException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class TSDBResultSetBlockData {
|
||||
private int numOfRows = 0;
|
||||
private int rowIndex = 0;
|
||||
|
||||
private List<ColumnMetaData> columnMetaDataList;
|
||||
private ArrayList<Object> colData = null;
|
||||
|
||||
public TSDBResultSetBlockData(List<ColumnMetaData> colMeta, int numOfCols) {
|
||||
this.columnMetaDataList = colMeta;
|
||||
this.colData = new ArrayList<Object>(numOfCols);
|
||||
}
|
||||
|
||||
public TSDBResultSetBlockData() {
|
||||
this.colData = new ArrayList<Object>();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
int size = this.colData.size();
|
||||
if (this.colData != null) {
|
||||
this.colData.clear();
|
||||
}
|
||||
|
||||
setNumOfCols(size);
|
||||
}
|
||||
|
||||
public int getNumOfRows() {
|
||||
return this.numOfRows;
|
||||
}
|
||||
|
||||
public void setNumOfRows(int numOfRows) {
|
||||
this.numOfRows = numOfRows;
|
||||
}
|
||||
|
||||
public int getNumOfCols() {
|
||||
return this.colData.size();
|
||||
}
|
||||
|
||||
public void setNumOfCols(int numOfCols) {
|
||||
this.colData = new ArrayList<Object>(numOfCols);
|
||||
this.colData.addAll(Collections.nCopies(numOfCols, null));
|
||||
}
|
||||
|
||||
public boolean hasMore() {
|
||||
return this.rowIndex < this.numOfRows;
|
||||
}
|
||||
|
||||
public boolean forward() {
|
||||
if (this.rowIndex > this.numOfRows) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((++this.rowIndex) < this.numOfRows);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.rowIndex = 0;
|
||||
}
|
||||
|
||||
public void setBoolean(int col, boolean value) {
|
||||
colData.set(col, value);
|
||||
}
|
||||
|
||||
public void setByteArray(int col, int length, byte[] value) {
|
||||
try {
|
||||
switch (this.columnMetaDataList.get(col).getColType()) {
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BOOL: {
|
||||
ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN).asCharBuffer();
|
||||
this.colData.set(col, buf);
|
||||
break;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
|
||||
ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
this.colData.set(col, buf);
|
||||
break;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
|
||||
ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
|
||||
ShortBuffer sb = buf.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
|
||||
this.colData.set(col, sb);
|
||||
break;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_INT: {
|
||||
ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
|
||||
IntBuffer ib = buf.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
|
||||
this.colData.set(col, ib);
|
||||
break;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
|
||||
ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
|
||||
LongBuffer lb = buf.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer();
|
||||
this.colData.set(col, lb);
|
||||
break;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
|
||||
ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
|
||||
FloatBuffer fb = buf.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
|
||||
this.colData.set(col, fb);
|
||||
break;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
|
||||
ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
|
||||
DoubleBuffer db = buf.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer();
|
||||
this.colData.set(col, db);
|
||||
break;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
|
||||
ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
this.colData.set(col, buf);
|
||||
break;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
|
||||
LongBuffer lb = buf.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer();
|
||||
this.colData.set(col, lb);
|
||||
break;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: {
|
||||
ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
this.colData.set(col, buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static class NullType {
|
||||
private static final byte NULL_BOOL_VAL = 0x2;
|
||||
private static final String NULL_STR = "null";
|
||||
|
||||
public String toString() {
|
||||
return NullType.NULL_STR;
|
||||
}
|
||||
|
||||
public static boolean isBooleanNull(byte val) {
|
||||
return val == NullType.NULL_BOOL_VAL;
|
||||
}
|
||||
|
||||
private static boolean isTinyIntNull(byte val) {
|
||||
return val == Byte.MIN_VALUE;
|
||||
}
|
||||
|
||||
private static boolean isSmallIntNull(short val) {
|
||||
return val == Short.MIN_VALUE;
|
||||
}
|
||||
|
||||
private static boolean isIntNull(int val) {
|
||||
return val == Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
private static boolean isBigIntNull(long val) {
|
||||
return val == Long.MIN_VALUE;
|
||||
}
|
||||
|
||||
private static boolean isFloatNull(float val) {
|
||||
return Float.isNaN(val);
|
||||
}
|
||||
|
||||
private static boolean isDoubleNull(double val) {
|
||||
return Double.isNaN(val);
|
||||
}
|
||||
|
||||
private static boolean isBinaryNull(byte[] val, int length) {
|
||||
if (length != Byte.BYTES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return val[0] == 0xFF;
|
||||
}
|
||||
|
||||
private static boolean isNcharNull(byte[] val, int length) {
|
||||
if (length != Integer.BYTES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (val[0] & val[1] & val[2] & val[3]) == 0xFF;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The original type may not be a string type, but will be converted to by
|
||||
* calling this method
|
||||
*
|
||||
* @param col column index
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
public String getString(int col) throws SQLException {
|
||||
Object obj = get(col);
|
||||
if (obj == null) {
|
||||
return new NullType().toString();
|
||||
}
|
||||
|
||||
return obj.toString();
|
||||
}
|
||||
|
||||
public int getInt(int col) {
|
||||
Object obj = get(col);
|
||||
if (obj == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int type = this.columnMetaDataList.get(col).getColType();
|
||||
switch (type) {
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_INT: {
|
||||
return (int) obj;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
return ((Long) obj).intValue();
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
|
||||
return ((Double) obj).intValue();
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
|
||||
return Integer.parseInt((String) obj);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean getBoolean(int col) throws SQLException {
|
||||
Object obj = get(col);
|
||||
if (obj == null) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
int type = this.columnMetaDataList.get(col).getColType();
|
||||
switch (type) {
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_INT: {
|
||||
return ((int) obj == 0L) ? Boolean.FALSE : Boolean.TRUE;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
return (((Long) obj) == 0L) ? Boolean.FALSE : Boolean.TRUE;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
|
||||
return (((Double) obj) == 0) ? Boolean.FALSE : Boolean.TRUE;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
|
||||
if ("TRUE".compareToIgnoreCase((String) obj) == 0) {
|
||||
return Boolean.TRUE;
|
||||
} else if ("FALSE".compareToIgnoreCase((String) obj) == 0) {
|
||||
return Boolean.TRUE;
|
||||
} else {
|
||||
throw new SQLDataException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
public long getLong(int col) throws SQLException {
|
||||
Object obj = get(col);
|
||||
if (obj == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int type = this.columnMetaDataList.get(col).getColType();
|
||||
switch (type) {
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_INT: {
|
||||
return (int) obj;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
return (long) obj;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
|
||||
return ((Double) obj).longValue();
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
|
||||
return Long.parseLong((String) obj);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Timestamp getTimestamp(int col) {
|
||||
try {
|
||||
return new Timestamp(getLong(col));
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public double getDouble(int col) {
|
||||
Object obj = get(col);
|
||||
if (obj == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int type = this.columnMetaDataList.get(col).getColType();
|
||||
switch (type) {
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_INT: {
|
||||
return (int) obj;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
return (long) obj;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
|
||||
return (double) obj;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
|
||||
return Double.parseDouble((String) obj);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Object get(int col) {
|
||||
int fieldSize = this.columnMetaDataList.get(col).getColSize();
|
||||
|
||||
switch (this.columnMetaDataList.get(col).getColType()) {
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BOOL: {
|
||||
ByteBuffer bb = (ByteBuffer) this.colData.get(col);
|
||||
|
||||
byte val = bb.get(this.rowIndex);
|
||||
if (NullType.isBooleanNull(val)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (val == 0x0) ? Boolean.FALSE : Boolean.TRUE;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
|
||||
ByteBuffer bb = (ByteBuffer) this.colData.get(col);
|
||||
|
||||
byte val = bb.get(this.rowIndex);
|
||||
if (NullType.isTinyIntNull(val)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
|
||||
ShortBuffer sb = (ShortBuffer) this.colData.get(col);
|
||||
short val = sb.get(this.rowIndex);
|
||||
if (NullType.isSmallIntNull(val)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_INT: {
|
||||
IntBuffer ib = (IntBuffer) this.colData.get(col);
|
||||
int val = ib.get(this.rowIndex);
|
||||
if (NullType.isIntNull(val)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
|
||||
LongBuffer lb = (LongBuffer) this.colData.get(col);
|
||||
long val = lb.get(this.rowIndex);
|
||||
if (NullType.isBigIntNull(val)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (long) val;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
|
||||
FloatBuffer fb = (FloatBuffer) this.colData.get(col);
|
||||
float val = fb.get(this.rowIndex);
|
||||
if (NullType.isFloatNull(val)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
|
||||
DoubleBuffer lb = (DoubleBuffer) this.colData.get(col);
|
||||
double val = lb.get(this.rowIndex);
|
||||
if (NullType.isDoubleNull(val)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
|
||||
ByteBuffer bb = (ByteBuffer) this.colData.get(col);
|
||||
bb.position(fieldSize * this.rowIndex);
|
||||
|
||||
int length = bb.getShort();
|
||||
|
||||
byte[] dest = new byte[length];
|
||||
bb.get(dest, 0, length);
|
||||
if (NullType.isBinaryNull(dest, length)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new String(dest);
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: {
|
||||
ByteBuffer bb = (ByteBuffer) this.colData.get(col);
|
||||
bb.position(fieldSize * this.rowIndex);
|
||||
|
||||
int length = bb.getShort();
|
||||
|
||||
byte[] dest = new byte[length];
|
||||
bb.get(dest, 0, length);
|
||||
if (NullType.isNcharNull(dest, length)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
String ss = TaosGlobalConfig.getCharset();
|
||||
return new String(dest, ss);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -218,5 +218,4 @@ public class TSDBResultSetRowData {
|
|||
public void setData(ArrayList<Object> data) {
|
||||
this.data = (ArrayList<Object>) data.clone();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
public class TSDBStatement implements Statement {
|
||||
private TSDBJNIConnector connecter = null;
|
||||
private TSDBJNIConnector connector = null;
|
||||
|
||||
/**
|
||||
* To store batched commands
|
||||
|
@ -45,9 +45,9 @@ public class TSDBStatement implements Statement {
|
|||
this.connection = connection;
|
||||
}
|
||||
|
||||
TSDBStatement(TSDBConnection connection, TSDBJNIConnector connecter) {
|
||||
TSDBStatement(TSDBConnection connection, TSDBJNIConnector connector) {
|
||||
this.connection = connection;
|
||||
this.connecter = connecter;
|
||||
this.connector = connector;
|
||||
this.isClosed = false;
|
||||
}
|
||||
|
||||
|
@ -65,25 +65,27 @@ public class TSDBStatement implements Statement {
|
|||
}
|
||||
|
||||
// TODO make sure it is not a update query
|
||||
pSql = this.connecter.executeQuery(sql);
|
||||
pSql = this.connector.executeQuery(sql);
|
||||
|
||||
long resultSetPointer = this.connecter.getResultSet();
|
||||
long resultSetPointer = this.connector.getResultSet();
|
||||
|
||||
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||
this.connecter.freeResultSet(pSql);
|
||||
this.connector.freeResultSet(pSql);
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
}
|
||||
|
||||
// create/insert/update/delete/alter
|
||||
if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) {
|
||||
this.connecter.freeResultSet(pSql);
|
||||
this.connector.freeResultSet(pSql);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!this.connecter.isUpdateQuery(pSql)) {
|
||||
return new TSDBResultSet(this.connecter, resultSetPointer);
|
||||
if (!this.connector.isUpdateQuery(pSql)) {
|
||||
TSDBResultSet res = new TSDBResultSet(this.connector, resultSetPointer);
|
||||
res.setBatchFetch(this.connection.getBatchFetch());
|
||||
return res;
|
||||
} else {
|
||||
this.connecter.freeResultSet(pSql);
|
||||
this.connector.freeResultSet(pSql);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -95,28 +97,28 @@ public class TSDBStatement implements Statement {
|
|||
}
|
||||
|
||||
// TODO check if current query is update query
|
||||
pSql = this.connecter.executeQuery(sql);
|
||||
long resultSetPointer = this.connecter.getResultSet();
|
||||
pSql = this.connector.executeQuery(sql);
|
||||
long resultSetPointer = this.connector.getResultSet();
|
||||
|
||||
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||
this.connecter.freeResultSet(pSql);
|
||||
this.connector.freeResultSet(pSql);
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
}
|
||||
|
||||
this.affectedRows = this.connecter.getAffectedRows(pSql);
|
||||
this.connecter.freeResultSet(pSql);
|
||||
this.affectedRows = this.connector.getAffectedRows(pSql);
|
||||
this.connector.freeResultSet(pSql);
|
||||
|
||||
return this.affectedRows;
|
||||
}
|
||||
|
||||
public String getErrorMsg(long pSql) {
|
||||
return this.connecter.getErrMsg(pSql);
|
||||
return this.connector.getErrMsg(pSql);
|
||||
}
|
||||
|
||||
public void close() throws SQLException {
|
||||
if (!isClosed) {
|
||||
if (!this.connecter.isResultsetClosed()) {
|
||||
this.connecter.freeResultSet();
|
||||
if (!this.connector.isResultsetClosed()) {
|
||||
this.connector.freeResultSet();
|
||||
}
|
||||
isClosed = true;
|
||||
}
|
||||
|
@ -136,7 +138,7 @@ public class TSDBStatement implements Statement {
|
|||
}
|
||||
|
||||
public void setMaxRows(int max) throws SQLException {
|
||||
// always set maxRows to zero, meaning unlimitted rows in a resultSet
|
||||
// always set maxRows to zero, meaning unlimited rows in a resultSet
|
||||
}
|
||||
|
||||
public void setEscapeProcessing(boolean enable) throws SQLException {
|
||||
|
@ -172,15 +174,15 @@ public class TSDBStatement implements Statement {
|
|||
throw new SQLException("Invalid method call on a closed statement.");
|
||||
}
|
||||
boolean res = true;
|
||||
pSql = this.connecter.executeQuery(sql);
|
||||
long resultSetPointer = this.connecter.getResultSet();
|
||||
pSql = this.connector.executeQuery(sql);
|
||||
long resultSetPointer = this.connector.getResultSet();
|
||||
|
||||
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||
this.connecter.freeResultSet(pSql);
|
||||
this.connector.freeResultSet(pSql);
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
} else if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) {
|
||||
// no result set is retrieved
|
||||
this.connecter.freeResultSet(pSql);
|
||||
this.connector.freeResultSet(pSql);
|
||||
res = false;
|
||||
}
|
||||
|
||||
|
@ -191,10 +193,10 @@ public class TSDBStatement implements Statement {
|
|||
if (isClosed) {
|
||||
throw new SQLException("Invalid method call on a closed statement.");
|
||||
}
|
||||
long resultSetPointer = connecter.getResultSet();
|
||||
long resultSetPointer = connector.getResultSet();
|
||||
TSDBResultSet resSet = null;
|
||||
if (resultSetPointer != TSDBConstants.JNI_NULL_POINTER) {
|
||||
resSet = new TSDBResultSet(connecter, resultSetPointer);
|
||||
resSet = new TSDBResultSet(connector, resultSetPointer);
|
||||
}
|
||||
return resSet;
|
||||
}
|
||||
|
@ -267,7 +269,7 @@ public class TSDBStatement implements Statement {
|
|||
}
|
||||
|
||||
public Connection getConnection() throws SQLException {
|
||||
if (this.connecter != null)
|
||||
if (this.connector != null)
|
||||
return this.connection;
|
||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,319 @@
|
|||
package com.taosdata.jdbc.rs;
|
||||
|
||||
import com.taosdata.jdbc.TSDBConstants;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public class RestfulConnection implements Connection {
|
||||
|
||||
private final String host;
|
||||
private final int port;
|
||||
private final Properties props;
|
||||
private final String database;
|
||||
private final String url;
|
||||
|
||||
|
||||
public RestfulConnection(String host, String port, Properties props, String database, String url) {
|
||||
this.host = host;
|
||||
this.port = Integer.parseInt(port);
|
||||
this.props = props;
|
||||
this.database = database;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement createStatement() throws SQLException {
|
||||
if (isClosed())
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("restful TDengine connection is closed."));
|
||||
return new RestfulStatement(this, this.database);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallableStatement prepareCall(String sql) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nativeSQL(String sql) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutoCommit(boolean autoCommit) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAutoCommit() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseMetaData getMetaData() throws SQLException {
|
||||
//TODO: RestfulDatabaseMetaData is not implemented
|
||||
return new RestfulDatabaseMetaData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadOnly(boolean readOnly) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCatalog(String catalog) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCatalog() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransactionIsolation(int level) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTransactionIsolation() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLWarning getWarnings() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearWarnings() throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Class<?>> getTypeMap() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHoldability(int holdability) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHoldability() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Savepoint setSavepoint() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Savepoint setSavepoint(String name) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback(Savepoint savepoint) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clob createClob() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blob createBlob() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NClob createNClob() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLXML createSQLXML() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(int timeout) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientInfo(String name, String value) throws SQLClientInfoException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientInfo(Properties properties) throws SQLClientInfoException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClientInfo(String name) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getClientInfo() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSchema(String schema) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSchema() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort(Executor executor) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNetworkTimeout() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public Properties getProps() {
|
||||
return props;
|
||||
}
|
||||
|
||||
public String getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,886 @@
|
|||
package com.taosdata.jdbc.rs;
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
public class RestfulDatabaseMetaData implements DatabaseMetaData {
|
||||
|
||||
@Override
|
||||
public boolean allProceduresAreCallable() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allTablesAreSelectable() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getURL() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserName() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nullsAreSortedHigh() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nullsAreSortedLow() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nullsAreSortedAtStart() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nullsAreSortedAtEnd() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDatabaseProductName() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDatabaseProductVersion() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDriverName() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDriverVersion() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDriverMajorVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDriverMinorVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesLocalFiles() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesLocalFilePerTable() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsMixedCaseIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean storesUpperCaseIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean storesLowerCaseIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean storesMixedCaseIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifierQuoteString() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQLKeywords() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNumericFunctions() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStringFunctions() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSystemFunctions() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTimeDateFunctions() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSearchStringEscape() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtraNameCharacters() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAlterTableWithAddColumn() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAlterTableWithDropColumn() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsColumnAliasing() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nullPlusNonNullIsNull() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsConvert() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsConvert(int fromType, int toType) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTableCorrelationNames() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsDifferentTableCorrelationNames() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsExpressionsInOrderBy() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOrderByUnrelated() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsGroupBy() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsGroupByUnrelated() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsGroupByBeyondSelect() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLikeEscapeClause() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsMultipleResultSets() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsMultipleTransactions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsNonNullableColumns() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsMinimumSQLGrammar() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCoreSQLGrammar() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsExtendedSQLGrammar() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsANSI92EntryLevelSQL() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsANSI92IntermediateSQL() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsANSI92FullSQL() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIntegrityEnhancementFacility() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOuterJoins() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsFullOuterJoins() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimitedOuterJoins() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSchemaTerm() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProcedureTerm() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCatalogTerm() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCatalogAtStart() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCatalogSeparator() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSchemasInDataManipulation() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSchemasInProcedureCalls() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSchemasInTableDefinitions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSchemasInIndexDefinitions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCatalogsInDataManipulation() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCatalogsInProcedureCalls() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCatalogsInTableDefinitions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPositionedDelete() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPositionedUpdate() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSelectForUpdate() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsStoredProcedures() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSubqueriesInComparisons() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSubqueriesInExists() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSubqueriesInIns() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSubqueriesInQuantifieds() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCorrelatedSubqueries() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsUnion() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsUnionAll() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxBinaryLiteralLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxCharLiteralLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxColumnNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxColumnsInGroupBy() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxColumnsInIndex() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxColumnsInOrderBy() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxColumnsInSelect() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxColumnsInTable() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxConnections() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxCursorNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxIndexLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxSchemaNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxProcedureNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxCatalogNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxRowSize() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStatementLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStatements() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxTableNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxTablesInSelect() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxUserNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultTransactionIsolation() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTransactions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getSchemas() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getCatalogs() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getTableTypes() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getTypeInfo() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsResultSetType(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ownUpdatesAreVisible(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ownDeletesAreVisible(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ownInsertsAreVisible(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean othersUpdatesAreVisible(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean othersDeletesAreVisible(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean othersInsertsAreVisible(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updatesAreDetected(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deletesAreDetected(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean insertsAreDetected(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsBatchUpdates() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSavepoints() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsNamedParameters() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsMultipleOpenResults() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsGetGeneratedKeys() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsResultSetHoldability(int holdability) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResultSetHoldability() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMajorVersion() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMinorVersion() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getJDBCMajorVersion() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getJDBCMinorVersion() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSQLStateType() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean locatorsUpdateCopy() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsStatementPooling() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RowIdLifetime getRowIdLifetime() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getClientInfoProperties() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generatedKeyAlwaysReturned() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package com.taosdata.jdbc.rs;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.taosdata.jdbc.AbstractTaosDriver;
|
||||
import com.taosdata.jdbc.TSDBConstants;
|
||||
import com.taosdata.jdbc.TSDBDriver;
|
||||
import com.taosdata.jdbc.rs.util.HttpClientPoolUtil;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class RestfulDriver extends AbstractTaosDriver {
|
||||
|
||||
private static final String URL_PREFIX = "jdbc:TAOS-RS://";
|
||||
|
||||
static {
|
||||
try {
|
||||
DriverManager.registerDriver(new RestfulDriver());
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(TSDBConstants.WrapErrMsg("can not register Restful JDBC driver"), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection connect(String url, Properties info) throws SQLException {
|
||||
// throw SQLException if url is null
|
||||
if (url == null)
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("url is not set!"));
|
||||
// return null if url is not be accepted
|
||||
if (!acceptsURL(url))
|
||||
return null;
|
||||
|
||||
Properties props = parseURL(url, info);
|
||||
String host = props.getProperty(TSDBDriver.PROPERTY_KEY_HOST, "localhost");
|
||||
String port = props.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "6041");
|
||||
String database = props.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME);
|
||||
|
||||
String loginUrl = "http://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST) + ":"
|
||||
+ props.getProperty(TSDBDriver.PROPERTY_KEY_PORT) + "/rest/login/"
|
||||
+ props.getProperty(TSDBDriver.PROPERTY_KEY_USER) + "/"
|
||||
+ props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD) + "";
|
||||
String result = HttpClientPoolUtil.execute(loginUrl);
|
||||
JSONObject jsonResult = JSON.parseObject(result);
|
||||
String status = jsonResult.getString("status");
|
||||
if (!status.equals("succ")) {
|
||||
throw new SQLException(jsonResult.getString("desc"));
|
||||
}
|
||||
|
||||
return new RestfulConnection(host, port, props, database, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptsURL(String url) throws SQLException {
|
||||
if (url == null)
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("url is null"));
|
||||
return (url != null && url.length() > 0 && url.trim().length() > 0) && url.startsWith(URL_PREFIX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
|
||||
if (info == null) {
|
||||
info = new Properties();
|
||||
}
|
||||
if (acceptsURL(url)) {
|
||||
info = parseURL(url, info);
|
||||
}
|
||||
return getPropertyInfo(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMajorVersion() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinorVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean jdbcCompliant() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
||||
return null;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,129 @@
|
|||
package com.taosdata.jdbc.rs;
|
||||
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||
|
||||
private List<String> fields;
|
||||
|
||||
public RestfulResultSetMetaData(List<String> fields) {
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() throws SQLException {
|
||||
return fields.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoIncrement(int column) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCaseSensitive(int column) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSearchable(int column) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrency(int column) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int isNullable(int column) throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSigned(int column) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnDisplaySize(int column) throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnLabel(int column) throws SQLException {
|
||||
return fields.get(column - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSchemaName(int column) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrecision(int column) throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getScale(int column) throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName(int column) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCatalogName(int column) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnType(int column) throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnTypeName(int column) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly(int column) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWritable(int column) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefinitelyWritable(int column) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnClassName(int column) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,280 @@
|
|||
package com.taosdata.jdbc.rs;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.taosdata.jdbc.TSDBConstants;
|
||||
import com.taosdata.jdbc.rs.util.HttpClientPoolUtil;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class RestfulStatement implements Statement {
|
||||
|
||||
private final String catalog;
|
||||
private final RestfulConnection conn;
|
||||
|
||||
public RestfulStatement(RestfulConnection c, String catalog) {
|
||||
this.conn = c;
|
||||
this.catalog = catalog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet executeQuery(String sql) throws SQLException {
|
||||
|
||||
final String url = "http://" + conn.getHost() + ":"+conn.getPort()+"/rest/sql";
|
||||
|
||||
String result = HttpClientPoolUtil.execute(url, sql);
|
||||
String fields = "";
|
||||
List<String> words = Arrays.asList(sql.split(" "));
|
||||
if (words.get(0).equalsIgnoreCase("select")) {
|
||||
int index = 0;
|
||||
if (words.contains("from")) {
|
||||
index = words.indexOf("from");
|
||||
}
|
||||
if (words.contains("FROM")) {
|
||||
index = words.indexOf("FROM");
|
||||
}
|
||||
fields = HttpClientPoolUtil.execute(url, "DESCRIBE " + words.get(index + 1));
|
||||
}
|
||||
|
||||
JSONObject jsonObject = JSON.parseObject(result);
|
||||
if (jsonObject.getString("status").equals("error")) {
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " +
|
||||
jsonObject.getString("desc") + "\n" +
|
||||
"error code: " + jsonObject.getString("code")));
|
||||
}
|
||||
String dataStr = jsonObject.getString("data");
|
||||
if ("use".equalsIgnoreCase(fields.split(" ")[0])) {
|
||||
return new RestfulResultSet(dataStr, "");
|
||||
}
|
||||
|
||||
JSONObject jsonField = JSON.parseObject(fields);
|
||||
if (jsonField == null) {
|
||||
return new RestfulResultSet(dataStr, "");
|
||||
}
|
||||
if (jsonField.getString("status").equals("error")) {
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " +
|
||||
jsonField.getString("desc") + "\n" +
|
||||
"error code: " + jsonField.getString("code")));
|
||||
}
|
||||
String fieldData = jsonField.getString("data");
|
||||
|
||||
return new RestfulResultSet(dataStr, fieldData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql) throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxFieldSize() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxFieldSize(int max) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxRows() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxRows(int max) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEscapeProcessing(boolean enable) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQueryTimeout() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQueryTimeout(int seconds) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLWarning getWarnings() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearWarnings() throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCursorName(String name) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String sql) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUpdateCount() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getMoreResults() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFetchDirection(int direction) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFetchDirection() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFetchSize(int rows) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFetchSize() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResultSetConcurrency() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResultSetType() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBatch(String sql) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearBatch() throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] executeBatch() throws SQLException {
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getMoreResults(int current) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getGeneratedKeys() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql, String[] columnNames) throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String sql, int[] columnIndexes) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String sql, String[] columnNames) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResultSetHoldability() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPoolable(boolean poolable) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPoolable() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeOnCompletion() throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCloseOnCompletion() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
package com.taosdata.jdbc.rs.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HeaderElement;
|
||||
import org.apache.http.HeaderElementIterator;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.*;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.conn.ConnectionKeepAliveStrategy;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.apache.http.message.BasicHeaderElementIterator;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
|
||||
public class HttpClientPoolUtil {
|
||||
public static PoolingHttpClientConnectionManager cm = null;
|
||||
public static CloseableHttpClient httpClient = null;
|
||||
/**
|
||||
* 默认content 类型
|
||||
*/
|
||||
private static final String DEFAULT_CONTENT_TYPE = "application/json";
|
||||
/**
|
||||
* 默认请求超时时间30s
|
||||
*/
|
||||
private static final int DEFAULT_TIME_OUT = 15000;
|
||||
private static final int count = 32;
|
||||
private static final int totalCount = 1000;
|
||||
private static final int Http_Default_Keep_Time = 15000;
|
||||
|
||||
/**
|
||||
* 初始化连接池
|
||||
*/
|
||||
public static synchronized void initPools() {
|
||||
if (httpClient == null) {
|
||||
cm = new PoolingHttpClientConnectionManager();
|
||||
cm.setDefaultMaxPerRoute(count);
|
||||
cm.setMaxTotal(totalCount);
|
||||
httpClient = HttpClients.custom().setKeepAliveStrategy(defaultStrategy).setConnectionManager(cm).build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Http connection keepAlive 设置
|
||||
*/
|
||||
public static ConnectionKeepAliveStrategy defaultStrategy = (response, context) -> {
|
||||
HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
|
||||
int keepTime = Http_Default_Keep_Time * 1000;
|
||||
while (it.hasNext()) {
|
||||
HeaderElement headerElement = it.nextElement();
|
||||
String param = headerElement.getName();
|
||||
String value = headerElement.getValue();
|
||||
if (value != null && param.equalsIgnoreCase("timeout")) {
|
||||
try {
|
||||
return Long.parseLong(value) * 1000;
|
||||
} catch (Exception e) {
|
||||
new Exception(
|
||||
"format KeepAlive timeout exception, exception:" + e.toString())
|
||||
.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return keepTime;
|
||||
};
|
||||
|
||||
public static CloseableHttpClient getHttpClient() {
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
public static PoolingHttpClientConnectionManager getHttpConnectionManager() {
|
||||
return cm;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行http post请求
|
||||
* 默认采用Content-Type:application/json,Accept:application/json
|
||||
*
|
||||
* @param uri 请求地址
|
||||
* @param data 请求数据
|
||||
* @return responseBody
|
||||
*/
|
||||
public static String execute(String uri, String data) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
HttpEntity httpEntity = null;
|
||||
HttpEntityEnclosingRequestBase method = null;
|
||||
String responseBody = "";
|
||||
try {
|
||||
if (httpClient == null) {
|
||||
initPools();
|
||||
}
|
||||
method = (HttpEntityEnclosingRequestBase) getRequest(uri, HttpPost.METHOD_NAME, DEFAULT_CONTENT_TYPE, 0);
|
||||
method.setEntity(new StringEntity(data));
|
||||
HttpContext context = HttpClientContext.create();
|
||||
CloseableHttpResponse httpResponse = httpClient.execute(method, context);
|
||||
httpEntity = httpResponse.getEntity();
|
||||
if (httpEntity != null) {
|
||||
responseBody = EntityUtils.toString(httpEntity, "UTF-8");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (method != null) {
|
||||
method.abort();
|
||||
}
|
||||
// e.printStackTrace();
|
||||
// logger.error("execute post request exception, url:" + uri + ", exception:" + e.toString()
|
||||
// + ", cost time(ms):" + (System.currentTimeMillis() - startTime));
|
||||
new Exception("execute post request exception, url:"
|
||||
+ uri + ", exception:" + e.toString() +
|
||||
", cost time(ms):" + (System.currentTimeMillis() - startTime))
|
||||
.printStackTrace();
|
||||
} finally {
|
||||
if (httpEntity != null) {
|
||||
try {
|
||||
EntityUtils.consumeQuietly(httpEntity);
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// logger.error("close response exception, url:" + uri + ", exception:" + e.toString()
|
||||
// + ", cost time(ms):" + (System.currentTimeMillis() - startTime));
|
||||
new Exception(
|
||||
"close response exception, url:" + uri +
|
||||
", exception:" + e.toString()
|
||||
+ ", cost time(ms):" + (System.currentTimeMillis() - startTime))
|
||||
.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* * 创建请求
|
||||
*
|
||||
* @param uri 请求url
|
||||
* @param methodName 请求的方法类型
|
||||
* @param contentType contentType类型
|
||||
* @param timeout 超时时间
|
||||
* @return HttpRequestBase 返回类型
|
||||
* @author lisc
|
||||
*/
|
||||
public static HttpRequestBase getRequest(String uri, String methodName, String contentType, int timeout) {
|
||||
if (httpClient == null) {
|
||||
initPools();
|
||||
}
|
||||
HttpRequestBase method;
|
||||
if (timeout <= 0) {
|
||||
timeout = DEFAULT_TIME_OUT;
|
||||
}
|
||||
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout * 1000)
|
||||
.setConnectTimeout(timeout * 1000).setConnectionRequestTimeout(timeout * 1000)
|
||||
.setExpectContinueEnabled(false).build();
|
||||
if (HttpPut.METHOD_NAME.equalsIgnoreCase(methodName)) {
|
||||
method = new HttpPut(uri);
|
||||
} else if (HttpPost.METHOD_NAME.equalsIgnoreCase(methodName)) {
|
||||
method = new HttpPost(uri);
|
||||
} else if (HttpGet.METHOD_NAME.equalsIgnoreCase(methodName)) {
|
||||
method = new HttpGet(uri);
|
||||
} else {
|
||||
method = new HttpPost(uri);
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(contentType)) {
|
||||
contentType = DEFAULT_CONTENT_TYPE;
|
||||
}
|
||||
method.addHeader("Content-Type", contentType);
|
||||
method.addHeader("Accept", contentType);
|
||||
method.setConfig(requestConfig);
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行GET 请求
|
||||
*
|
||||
* @param uri 网址
|
||||
* @return responseBody
|
||||
*/
|
||||
public static String execute(String uri) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
HttpEntity httpEntity = null;
|
||||
HttpRequestBase method = null;
|
||||
String responseBody = "";
|
||||
try {
|
||||
if (httpClient == null) {
|
||||
initPools();
|
||||
}
|
||||
method = getRequest(uri, HttpGet.METHOD_NAME, DEFAULT_CONTENT_TYPE, 0);
|
||||
HttpContext context = HttpClientContext.create();
|
||||
CloseableHttpResponse httpResponse = httpClient.execute(method, context);
|
||||
httpEntity = httpResponse.getEntity();
|
||||
if (httpEntity != null) {
|
||||
responseBody = EntityUtils.toString(httpEntity, "UTF-8");
|
||||
// logger.info("请求URL: " + uri + "+ 返回状态码:" + httpResponse.getStatusLine().getStatusCode());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (method != null) {
|
||||
method.abort();
|
||||
}
|
||||
e.printStackTrace();
|
||||
// logger.error("execute get request exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):"
|
||||
// + (System.currentTimeMillis() - startTime));
|
||||
System.out.println("log:调用 HttpClientPoolUtil execute get request exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):"
|
||||
+ (System.currentTimeMillis() - startTime));
|
||||
} finally {
|
||||
if (httpEntity != null) {
|
||||
try {
|
||||
EntityUtils.consumeQuietly(httpEntity);
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// logger.error("close response exception, url:" + uri + ", exception:" + e.toString()
|
||||
// + ",cost time(ms):" + (System.currentTimeMillis() - startTime));
|
||||
new Exception("close response exception, url:" + uri + ", exception:" + e.toString()
|
||||
+ ",cost time(ms):" + (System.currentTimeMillis() - startTime))
|
||||
.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return responseBody;
|
||||
}
|
||||
}
|
|
@ -5,24 +5,24 @@ import com.taosdata.jdbc.utils.TDNodes;
|
|||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
public class BaseTest {
|
||||
public abstract class BaseTest {
|
||||
|
||||
private static boolean testCluster = false;
|
||||
private static boolean testCluster = false;
|
||||
private static TDNodes nodes = new TDNodes();
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void setupEnv() {
|
||||
try{
|
||||
try {
|
||||
if (nodes.getTDNode(1).getTaosdPid() != null) {
|
||||
System.out.println("Kill taosd before running JDBC test");
|
||||
nodes.getTDNode(1).setRunning(1);
|
||||
nodes.stop(1);
|
||||
}
|
||||
nodes.setTestCluster(testCluster);
|
||||
nodes.setTestCluster(testCluster);
|
||||
nodes.deploy(1);
|
||||
nodes.start(1);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package com.taosdata.jdbc.cases;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class FailOverTest {
|
||||
|
||||
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
|
||||
|
||||
@Test
|
||||
public void testFailOver() throws ClassNotFoundException {
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
final String url = "jdbc:TAOS://:/?user=root&password=taosdata";
|
||||
|
||||
long end = System.currentTimeMillis() + 1000 * 60 * 5;
|
||||
while (System.currentTimeMillis() < end) {
|
||||
try (Connection conn = DriverManager.getConnection(url)) {
|
||||
Statement stmt = conn.createStatement();
|
||||
ResultSet resultSet = stmt.executeQuery("select server_status()");
|
||||
resultSet.next();
|
||||
int status = resultSet.getInt("server_status()");
|
||||
System.out.println(">>>>>>>>>" + sdf.format(new Date()) + " status : " + status);
|
||||
stmt.close();
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
} catch (SQLException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.taosdata.jdbc.rs;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
public class RestfulDriverTest {
|
||||
|
||||
@Test
|
||||
public void testCase001() {
|
||||
try {
|
||||
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
|
||||
Connection connection = DriverManager.getConnection("jdbc:TAOS-RS://master:6041/?user=root&password=taosdata");
|
||||
Statement statement = connection.createStatement();
|
||||
ResultSet resultSet = statement.executeQuery("select * from log.log");
|
||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||
while (resultSet.next()) {
|
||||
for (int i = 1; i <= metaData.getColumnCount(); i++) {
|
||||
String column = metaData.getColumnLabel(i);
|
||||
String value = resultSet.getString(i);
|
||||
System.out.print(column + ":" + value + "\t");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
statement.close();
|
||||
connection.close();
|
||||
} catch (SQLException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptUrl() throws SQLException {
|
||||
Driver driver = new RestfulDriver();
|
||||
boolean isAccept = driver.acceptsURL("jdbc:TAOS-RS://master:6041");
|
||||
Assert.assertTrue(isAccept);
|
||||
}
|
||||
|
||||
}
|
|
@ -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,20 +13,43 @@ 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 ()
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0.0)
|
||||
message(WARNING "gcc 4.8.0 will complain too much about flex-generated code, we just bypass building ODBC driver in such case")
|
||||
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(tools)
|
||||
ADD_SUBDIRECTORY(tests)
|
||||
endif ()
|
||||
endif()
|
||||
endif()
|
||||
ELSE ()
|
||||
message(WARNING "unixodbc is not installed yet, you may install it under ubuntu by typing: sudo apt install unixodbc")
|
||||
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(WARNING "you need to install flex first\n"
|
||||
"you may go to: https://github.com/lexxmark/winflexbison\n"
|
||||
"or download from: https://github.com/lexxmark/winflexbison/releases")
|
||||
else ()
|
||||
ADD_SUBDIRECTORY(src)
|
||||
ADD_SUBDIRECTORY(tools)
|
||||
ADD_SUBDIRECTORY(tests)
|
||||
endif()
|
||||
ENDIF ()
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
# ODBC Driver #
|
||||
|
||||
- **very initial implementation of ODBC driver for TAOS
|
||||
|
||||
- **currently partially supported ODBC functions are: `
|
||||
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
|
||||
ConfigDSN
|
||||
`
|
||||
|
||||
- **internationalized, you can specify different charset/code page for easy going. eg.: insert `utf-8.zh_cn` characters into database located in linux machine, while query them out in `gb2312/gb18030/...` code page in your chinese windows machine, or vice-versa. and much fun, insert `gb2312/gb18030/...` characters into database located in linux box from
|
||||
your japanese windows box, and query them out in your local chinese windows machine.
|
||||
|
||||
- **enable ODBC-aware software to communicate with TAOS.
|
||||
|
||||
- **enable any language with ODBC-bindings/ODBC-plugings to communicate with TAOS
|
||||
|
||||
- **still going on...
|
||||
|
||||
# Building and Testing
|
||||
**Note**: all `work` is done in TDengine's project directory
|
||||
|
||||
|
||||
# Building under Linux, use Ubuntu as example
|
||||
```
|
||||
sudo apt install unixodbc unixodbc-dev flex
|
||||
rm -rf debug && cmake -B debug && cmake --build debug && cmake --install debug && echo yes
|
||||
```
|
||||
# Building under Windows, use Windows 10 as example
|
||||
- install windows `flex` port. We use [https://github.com/lexxmark/winflexbison](url) at the moment. Please be noted to append `<path_to_win_flex.exe>` to your `PATH`.
|
||||
- install Microsoft Visual Studio, take VS2015 as example here
|
||||
- `"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64`
|
||||
- `rmdir /s /q debug`
|
||||
- `cmake -G "NMake Makefiles" -B debug`
|
||||
- `cmake --build debug`
|
||||
- `cmake --install debug`
|
||||
- open your `Command Prompt` with Administrator's priviledge
|
||||
- remove previously installed TAOS ODBC driver: run `C:\TDengine\todbcinst -u -f -n TAOS`
|
||||
- install TAOS ODBC driver that was just built: run `C:\TDengine\todbcinst -i -n TAOS -p C:\TDengine\driver`
|
||||
- add a new user dsn: run `odbcconf CONFIGDSN TAOS "DSN=TAOS_DSN|Server=<fqdn>:<port>`
|
||||
|
||||
# Test
|
||||
we highly suggest that you build both in linux(ubuntu) and windows(windows 10) platform, because currently TAOS only has it's server-side port on linux platform.
|
||||
**Note1**: content within <> shall be modified to match your environment
|
||||
**Note2**: `.stmts` source files are all encoded in `UTF-8`
|
||||
## start taosd in linux, suppose charset is `UTF-8` as default
|
||||
```
|
||||
taosd -c ./debug/test/cfg
|
||||
```
|
||||
## create data in linux
|
||||
```
|
||||
./debug/build/bin/tcodbc --dsn TAOS_DSN --uid <uid> --pwd <pwd> --sts ./src/connector/odbc/tests/create_data.stmts
|
||||
--<or with driver connection string -->
|
||||
./debug/build/bin/tcodbc --dcs 'Driver=TAOS;UID=<uid>;PWD=<pwd>;Server=<fqdn>:<port>;client_enc=UTF-8' ./src/connector/odbc/tests/create_data.stmts
|
||||
```
|
||||
## query data in windows
|
||||
```
|
||||
.\debug\build\bin\tcodbc --dsn TAOS_DSN --uid <uid> --pwd <pwd> --sts .\src\connector\odbc\tests\query_data.stmts
|
||||
--<or with driver connection string -->
|
||||
.\debug\build\bin\tcodbc --dcs "Driver=TAOS;UID=<uid>;PWD=<pwd>;Server=<fqdn>:<port>;client_enc=UTF-8" .\src\connector\odbc\tests\query_data.stmts
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
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 odbcinst)
|
||||
target_include_directories(todbc PUBLIC .)
|
||||
|
||||
install(CODE "execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/install.sh ${CMAKE_BINARY_DIR})")
|
||||
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 odbccp32 legacy_stdio_definitions)
|
||||
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")
|
||||
|
||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/todbc.lib DESTINATION driver)
|
||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/todbc.exp DESTINATION driver)
|
||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/todbc.dll DESTINATION driver)
|
||||
ENDIF ()
|
|
@ -9,16 +9,18 @@ rm -f "${BLD_DIR}/template.dsn"
|
|||
|
||||
cat > "${BLD_DIR}/template.ini" <<EOF
|
||||
[TAOS]
|
||||
Description = taos odbc driver
|
||||
Driver = ${BLD_DIR}/build/lib/libtodbc.so
|
||||
Description=taos odbc driver
|
||||
Driver=${BLD_DIR}/build/lib/libtodbc.so
|
||||
EOF
|
||||
|
||||
cat > "${BLD_DIR}/template.dsn" <<EOF
|
||||
[TAOS_DSN]
|
||||
Description=Connection to TAOS
|
||||
Driver=TAOS
|
||||
Server=localhost:6030
|
||||
EOF
|
||||
|
||||
# better remove first ?
|
||||
sudo odbcinst -i -d -f "${BLD_DIR}/template.ini" &&
|
||||
odbcinst -i -s -f "${BLD_DIR}/template.dsn" &&
|
||||
echo "odbc install done"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
|||
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
|
||||
ConfigDSN
|
||||
ConfigTranslator
|
||||
ConfigDriver
|
||||
|
|
@ -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"
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,660 @@
|
|||
/*
|
||||
* 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_log.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
const char* tsdb_conv_code_str(TSDB_CONV_CODE code) {
|
||||
switch (code) {
|
||||
case TSDB_CONV_OK: return "TSDB_CONV_OK";
|
||||
case TSDB_CONV_NOT_AVAIL: return "TSDB_CONV_NOT_AVAIL";
|
||||
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_CHAR_NOT_TS: return "TSDB_CONV_CHAR_NOT_TS";
|
||||
case TSDB_CONV_NOT_VALID_TS: return "TSDB_CONV_NOT_VALID_TS";
|
||||
case TSDB_CONV_GENERAL: return "TSDB_CONV_GENERAL";
|
||||
case TSDB_CONV_SRC_TOO_LARGE: return "TSDB_CONV_SRC_TOO_LARGE";
|
||||
case TSDB_CONV_SRC_BAD_SEQ: return "TSDB_CONV_SRC_BAD_SEQ";
|
||||
case TSDB_CONV_SRC_INCOMPLETE: return "TSDB_CONV_SRC_INCOMPLETE";
|
||||
case TSDB_CONV_SRC_GENERAL: return "TSDB_CONV_SRC_GENERAL";
|
||||
case TSDB_CONV_BAD_CHAR: return "TSDB_CONV_BAD_CHAR";
|
||||
default: return "UNKNOWN";
|
||||
};
|
||||
}
|
||||
|
||||
// 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);
|
||||
DASSERT(n>=0);
|
||||
|
||||
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);
|
||||
DASSERT(n>=0);
|
||||
|
||||
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);
|
||||
DASSERT(n>=0);
|
||||
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_timestamp(const char *src, size_t smax, SQL_TIMESTAMP_STRUCT *dst) {
|
||||
int64_t v = 0;
|
||||
// why cast to 'char*' ?
|
||||
int r = taosParseTime((char*)src, &v, (int32_t)smax, TSDB_TIME_PRECISION_MILLI, 0);
|
||||
|
||||
if (r) {
|
||||
return TSDB_CONV_CHAR_NOT_TS;
|
||||
}
|
||||
|
||||
time_t t = v/1000;
|
||||
struct tm vtm = {0};
|
||||
localtime_r(&t, &vtm);
|
||||
dst->year = (SQLSMALLINT)(vtm.tm_year + 1900);
|
||||
dst->month = (SQLUSMALLINT)(vtm.tm_mon + 1);
|
||||
dst->day = (SQLUSMALLINT)(vtm.tm_mday);
|
||||
dst->hour = (SQLUSMALLINT)(vtm.tm_hour);
|
||||
dst->minute = (SQLUSMALLINT)(vtm.tm_min);
|
||||
dst->second = (SQLUSMALLINT)(vtm.tm_sec);
|
||||
dst->fraction = (SQLUINTEGER)(v%1000 * 1000000);
|
||||
|
||||
return TSDB_CONV_OK;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_chars_to_timestamp_ts(const char *src, size_t smax, int64_t *dst) {
|
||||
// why cast to 'char*' ?
|
||||
int r = taosParseTime((char*)src, dst, (int32_t)smax, TSDB_TIME_PRECISION_MILLI, 0);
|
||||
|
||||
if (r) {
|
||||
return TSDB_CONV_CHAR_NOT_TS;
|
||||
}
|
||||
|
||||
return TSDB_CONV_OK;
|
||||
}
|
||||
|
||||
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);
|
||||
DASSERT(n>=0);
|
||||
if (n<dmax) return TSDB_CONV_OK;
|
||||
|
||||
return TSDB_CONV_TRUNC;
|
||||
}
|
||||
|
||||
|
||||
char* stack_buffer_alloc(stack_buffer_t *buffer, size_t bytes) {
|
||||
if (!buffer) return NULL;
|
||||
// align-by-size_of-size_t-bytes
|
||||
if (bytes==0) bytes = sizeof(size_t);
|
||||
bytes = (bytes + sizeof(size_t) - 1) / sizeof(size_t) * sizeof(size_t);
|
||||
|
||||
size_t next = buffer->next + bytes;
|
||||
if (next>sizeof(buffer->buf)) return NULL;
|
||||
|
||||
char *p = buffer->buf + buffer->next;
|
||||
buffer->next = next;
|
||||
return p;
|
||||
}
|
||||
|
||||
int is_owned_by_stack_buffer(stack_buffer_t *buffer, const char *ptr) {
|
||||
if (!buffer) return 0;
|
||||
if (ptr>=buffer->buf && ptr<buffer->buf+buffer->next) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct tsdb_conv_s {
|
||||
iconv_t cnv;
|
||||
unsigned int direct:1;
|
||||
};
|
||||
|
||||
static tsdb_conv_t no_conversion = {0};
|
||||
static pthread_once_t once = PTHREAD_ONCE_INIT;
|
||||
static void once_init(void) {
|
||||
no_conversion.cnv = (iconv_t)-1;
|
||||
no_conversion.direct = 1;
|
||||
}
|
||||
|
||||
tsdb_conv_t* tsdb_conv_direct() { // get a non-conversion-converter
|
||||
pthread_once(&once, once_init);
|
||||
return &no_conversion;
|
||||
}
|
||||
|
||||
tsdb_conv_t* tsdb_conv_open(const char *from_enc, const char *to_enc) {
|
||||
pthread_once(&once, once_init);
|
||||
tsdb_conv_t *cnv = (tsdb_conv_t*)calloc(1, sizeof(*cnv));
|
||||
if (!cnv) return NULL;
|
||||
if (strcmp(from_enc, to_enc)==0 && 0) {
|
||||
cnv->cnv = (iconv_t)-1;
|
||||
cnv->direct = 1;
|
||||
return cnv;
|
||||
}
|
||||
cnv->cnv = iconv_open(to_enc, from_enc);
|
||||
if (cnv->cnv == (iconv_t)-1) {
|
||||
free(cnv);
|
||||
return NULL;
|
||||
}
|
||||
cnv->direct = 0;
|
||||
return cnv;
|
||||
}
|
||||
|
||||
void tsdb_conv_close(tsdb_conv_t *cnv) {
|
||||
if (!cnv) return;
|
||||
if (cnv == &no_conversion) return;
|
||||
if (!cnv->direct) {
|
||||
if (cnv->cnv != (iconv_t)-1) {
|
||||
iconv_close(cnv->cnv);
|
||||
}
|
||||
}
|
||||
cnv->cnv = (iconv_t)-1;
|
||||
cnv->direct = 0;
|
||||
free(cnv);
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_write(tsdb_conv_t *cnv, const char *src, size_t *slen, char *dst, size_t *dlen) {
|
||||
if (!cnv) return TSDB_CONV_NOT_AVAIL;
|
||||
if (cnv->direct) {
|
||||
size_t n = (*slen > *dlen) ? *dlen : *slen;
|
||||
memcpy(dst, src, n);
|
||||
*slen -= n;
|
||||
*dlen -= n;
|
||||
if (*dlen) dst[n] = '\0';
|
||||
return TSDB_CONV_OK;
|
||||
}
|
||||
if (!cnv->cnv) return TSDB_CONV_NOT_AVAIL;
|
||||
size_t r = iconv(cnv->cnv, (char**)&src, slen, &dst, dlen);
|
||||
if (r==(size_t)-1) return TSDB_CONV_BAD_CHAR;
|
||||
if (*slen) return TSDB_CONV_TRUNC;
|
||||
if (*dlen) *dst = '\0';
|
||||
return TSDB_CONV_OK;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_write_int64(tsdb_conv_t *cnv, int64_t val, char *dst, size_t *dlen) {
|
||||
char utf8[64];
|
||||
int n = snprintf(utf8, sizeof(utf8), "%" PRId64 "", val);
|
||||
DASSERT(n>=0);
|
||||
DASSERT(n<sizeof(utf8));
|
||||
size_t len = (size_t)n;
|
||||
TSDB_CONV_CODE code = tsdb_conv_write(cnv, utf8, &len, dst, dlen);
|
||||
*dlen = (size_t)n+1;
|
||||
return code;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_write_double(tsdb_conv_t *cnv, double val, char *dst, size_t *dlen) {
|
||||
char utf8[256];
|
||||
int n = snprintf(utf8, sizeof(utf8), "%g", val);
|
||||
DASSERT(n>=0);
|
||||
DASSERT(n<sizeof(utf8));
|
||||
size_t len = (size_t)n;
|
||||
TSDB_CONV_CODE code = tsdb_conv_write(cnv, utf8, &len, dst, dlen);
|
||||
*dlen = (size_t)n+1;
|
||||
return code;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_write_timestamp(tsdb_conv_t *cnv, SQL_TIMESTAMP_STRUCT val, char *dst, size_t *dlen) {
|
||||
char utf8[256];
|
||||
int n = snprintf(utf8, sizeof(utf8), "%04d-%02d-%02d %02d:%02d:%02d.%03d",
|
||||
val.year, val.month, val.day,
|
||||
val.hour, val.minute, val.second,
|
||||
val.fraction / 1000000);
|
||||
DASSERT(n>=0);
|
||||
DASSERT(n<sizeof(utf8));
|
||||
size_t len = (size_t)n;
|
||||
TSDB_CONV_CODE code = tsdb_conv_write(cnv, utf8, &len, dst, dlen);
|
||||
*dlen = (size_t)n+1;
|
||||
return code;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_bit(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int8_t *dst) {
|
||||
const char *utf8 = NULL;
|
||||
TSDB_CONV_CODE code = tsdb_conv(cnv, buffer, src, slen, &utf8, NULL);
|
||||
if (code) return code;
|
||||
code = tsdb_chars_to_bit(utf8, sizeof(utf8), dst);
|
||||
tsdb_conv_free(cnv, utf8, buffer, src);
|
||||
return code;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_tinyint(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int8_t *dst) {
|
||||
const char *utf8 = NULL;
|
||||
TSDB_CONV_CODE code = tsdb_conv(cnv, buffer, src, slen, &utf8, NULL);
|
||||
if (code) return code;
|
||||
code = tsdb_chars_to_tinyint(utf8, sizeof(utf8), dst);
|
||||
tsdb_conv_free(cnv, utf8, buffer, src);
|
||||
return code;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_smallint(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int16_t *dst) {
|
||||
const char *utf8 = NULL;
|
||||
TSDB_CONV_CODE code = tsdb_conv(cnv, buffer, src, slen, &utf8, NULL);
|
||||
if (code) return code;
|
||||
code = tsdb_chars_to_smallint(utf8, sizeof(utf8), dst);
|
||||
tsdb_conv_free(cnv, utf8, buffer, src);
|
||||
return code;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_int(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int32_t *dst) {
|
||||
const char *utf8 = NULL;
|
||||
TSDB_CONV_CODE code = tsdb_conv(cnv, buffer, src, slen, &utf8, NULL);
|
||||
if (code) return code;
|
||||
code = tsdb_chars_to_int(utf8, sizeof(utf8), dst);
|
||||
tsdb_conv_free(cnv, utf8, buffer, src);
|
||||
return code;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_bigint(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int64_t *dst) {
|
||||
const char *utf8 = NULL;
|
||||
TSDB_CONV_CODE code = tsdb_conv(cnv, buffer, src, slen, &utf8, NULL);
|
||||
if (code) return code;
|
||||
code = tsdb_chars_to_bigint(utf8, sizeof(utf8), dst);
|
||||
tsdb_conv_free(cnv, utf8, buffer, src);
|
||||
return code;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_ts(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int64_t *dst) {
|
||||
const char *utf8 = NULL;
|
||||
TSDB_CONV_CODE code = tsdb_conv(cnv, buffer, src, slen, &utf8, NULL);
|
||||
if (code) return code;
|
||||
code = tsdb_chars_to_ts(utf8, sizeof(utf8), dst);
|
||||
tsdb_conv_free(cnv, utf8, buffer, src);
|
||||
return code;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_float(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, float *dst) {
|
||||
const char *utf8 = NULL;
|
||||
TSDB_CONV_CODE code = tsdb_conv(cnv, buffer, src, slen, &utf8, NULL);
|
||||
if (code) return code;
|
||||
code = tsdb_chars_to_float(utf8, sizeof(utf8), dst);
|
||||
tsdb_conv_free(cnv, utf8, buffer, src);
|
||||
return code;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_double(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, double *dst) {
|
||||
const char *utf8 = NULL;
|
||||
TSDB_CONV_CODE code = tsdb_conv(cnv, buffer, src, slen, &utf8, NULL);
|
||||
if (code) return code;
|
||||
code = tsdb_chars_to_double(utf8, sizeof(utf8), dst);
|
||||
tsdb_conv_free(cnv, utf8, buffer, src);
|
||||
return code;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_timestamp(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, SQL_TIMESTAMP_STRUCT *dst) {
|
||||
const char *utf8 = NULL;
|
||||
TSDB_CONV_CODE code = tsdb_conv(cnv, buffer, src, slen, &utf8, NULL);
|
||||
if (code) return code;
|
||||
code = tsdb_chars_to_timestamp(utf8, sizeof(utf8), dst);
|
||||
tsdb_conv_free(cnv, utf8, buffer, src);
|
||||
return code;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_timestamp_ts(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int64_t *dst) {
|
||||
const char *utf8 = NULL;
|
||||
TSDB_CONV_CODE code = tsdb_conv(cnv, buffer, src, slen, &utf8, NULL);
|
||||
if (code) return code;
|
||||
code = tsdb_chars_to_timestamp_ts(utf8, sizeof(utf8), dst);
|
||||
tsdb_conv_free(cnv, utf8, buffer, src);
|
||||
return code;
|
||||
}
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, const char **dst, size_t *dlen) {
|
||||
if (!cnv) return TSDB_CONV_NOT_AVAIL;
|
||||
|
||||
char *buf;
|
||||
size_t blen;
|
||||
if (cnv->direct) {
|
||||
if (src[slen]=='\0') { // access violation?
|
||||
*dst = src;
|
||||
if (dlen) *dlen = slen;
|
||||
return TSDB_CONV_OK;
|
||||
}
|
||||
blen = slen + 1;
|
||||
} else {
|
||||
blen = (slen + 1) * 4;
|
||||
}
|
||||
|
||||
buf = stack_buffer_alloc(buffer, blen);
|
||||
if (!buf) {
|
||||
buf = (char*)malloc(blen);
|
||||
if (!buf) return TSDB_CONV_OOM;
|
||||
}
|
||||
|
||||
if (cnv->direct) {
|
||||
size_t n = slen;
|
||||
DASSERT(blen > n);
|
||||
memcpy(buf, src, n);
|
||||
buf[n] = '\0';
|
||||
*dst = buf;
|
||||
if (dlen) *dlen = n;
|
||||
return TSDB_CONV_OK;
|
||||
}
|
||||
|
||||
const char *orig_s = src;
|
||||
char *orig_d = buf;
|
||||
size_t orig_blen = blen;
|
||||
|
||||
TSDB_CONV_CODE code;
|
||||
size_t r = iconv(cnv->cnv, (char**)&src, &slen, &buf, &blen);
|
||||
do {
|
||||
if (r==(size_t)-1) {
|
||||
switch(errno) {
|
||||
case E2BIG: {
|
||||
code = TSDB_CONV_SRC_TOO_LARGE;
|
||||
} break;
|
||||
case EILSEQ: {
|
||||
code = TSDB_CONV_SRC_BAD_SEQ;
|
||||
} break;
|
||||
case EINVAL: {
|
||||
code = TSDB_CONV_SRC_INCOMPLETE;
|
||||
} break;
|
||||
default: {
|
||||
code = TSDB_CONV_SRC_GENERAL;
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (slen) {
|
||||
code = TSDB_CONV_TRUNC;
|
||||
break;
|
||||
}
|
||||
DASSERT(blen);
|
||||
*buf = '\0';
|
||||
*dst = orig_d;
|
||||
if (dlen) *dlen = orig_blen - blen;
|
||||
return TSDB_CONV_OK;
|
||||
} while (0);
|
||||
|
||||
if (orig_d!=(char*)orig_s && !is_owned_by_stack_buffer(buffer, orig_d)) free(orig_d);
|
||||
return code;
|
||||
}
|
||||
|
||||
void tsdb_conv_free(tsdb_conv_t *cnv, const char *ptr, stack_buffer_t *buffer, const char *src) {
|
||||
if (ptr!=src && !is_owned_by_stack_buffer(buffer, ptr)) free((char*)ptr);
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* 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 "os.h"
|
||||
#include <iconv.h>
|
||||
#include <sql.h>
|
||||
|
||||
|
||||
typedef enum {
|
||||
TSDB_CONV_OK = 0,
|
||||
TSDB_CONV_NOT_AVAIL,
|
||||
TSDB_CONV_OOM,
|
||||
TSDB_CONV_OOR,
|
||||
TSDB_CONV_TRUNC_FRACTION,
|
||||
TSDB_CONV_TRUNC,
|
||||
TSDB_CONV_CHAR_NOT_NUM,
|
||||
TSDB_CONV_CHAR_NOT_TS,
|
||||
TSDB_CONV_NOT_VALID_TS,
|
||||
TSDB_CONV_GENERAL,
|
||||
TSDB_CONV_BAD_CHAR,
|
||||
TSDB_CONV_SRC_TOO_LARGE,
|
||||
TSDB_CONV_SRC_BAD_SEQ,
|
||||
TSDB_CONV_SRC_INCOMPLETE,
|
||||
TSDB_CONV_SRC_GENERAL,
|
||||
} TSDB_CONV_CODE;
|
||||
|
||||
const char* tsdb_conv_code_str(TSDB_CONV_CODE code);
|
||||
|
||||
typedef struct stack_buffer_s stack_buffer_t;
|
||||
struct stack_buffer_s {
|
||||
char buf[1024*16];
|
||||
size_t next;
|
||||
};
|
||||
|
||||
char* stack_buffer_alloc(stack_buffer_t *buffer, size_t bytes);
|
||||
int is_owned_by_stack_buffer(stack_buffer_t *buffer, const char *ptr);
|
||||
|
||||
typedef struct tsdb_conv_s tsdb_conv_t;
|
||||
tsdb_conv_t* tsdb_conv_direct(); // get a non-conversion-converter
|
||||
tsdb_conv_t* tsdb_conv_open(const char *from_enc, const char *to_enc);
|
||||
void tsdb_conv_close(tsdb_conv_t *cnv);
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_write(tsdb_conv_t *cnv, const char *src, size_t *slen, char *dst, size_t *dlen);
|
||||
TSDB_CONV_CODE tsdb_conv_write_int64(tsdb_conv_t *cnv, int64_t val, char *dst, size_t *dlen);
|
||||
TSDB_CONV_CODE tsdb_conv_write_double(tsdb_conv_t *cnv, double val, char *dst, size_t *dlen);
|
||||
TSDB_CONV_CODE tsdb_conv_write_timestamp(tsdb_conv_t *cnv, SQL_TIMESTAMP_STRUCT val, char *dst, size_t *dlen);
|
||||
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_bit(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int8_t *dst);
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_tinyint(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int8_t *dst);
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_smallint(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int16_t *dst);
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_int(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int32_t *dst);
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_bigint(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int64_t *dst);
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_ts(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int64_t *dst);
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_float(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, float *dst);
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_double(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, double *dst);
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_timestamp(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, SQL_TIMESTAMP_STRUCT *dst);
|
||||
TSDB_CONV_CODE tsdb_conv_chars_to_timestamp_ts(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int64_t *dst);
|
||||
TSDB_CONV_CODE tsdb_conv(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, const char **dst, size_t *dlen);
|
||||
void tsdb_conv_free(tsdb_conv_t *cnv, const char *ptr, stack_buffer_t *buffer, const char *src);
|
||||
|
||||
|
||||
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_timestamp(const char *src, size_t smax, SQL_TIMESTAMP_STRUCT *dst);
|
||||
TSDB_CONV_CODE tsdb_chars_to_char(const char *src, size_t smax, char *dst, size_t dmax);
|
||||
|
||||
#endif // _todbc_conv_h_
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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_
|
||||
|
||||
typedef struct conn_val_s conn_val_t;
|
||||
struct conn_val_s {
|
||||
char *key;
|
||||
char *dsn;
|
||||
char *uid;
|
||||
char *pwd;
|
||||
char *db;
|
||||
char *server;
|
||||
char *svr_enc;
|
||||
char *cli_enc;
|
||||
};
|
||||
|
||||
|
||||
void conn_val_reset(conn_val_t *val);
|
||||
int todbc_parse_conn_string(const char *conn, conn_val_t *val);
|
||||
|
||||
#endif // _TODBC_FLEX_H_
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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 "os.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_
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
%{
|
||||
#include "todbc_flex.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
#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, "DB")==0) { \
|
||||
free(yyextra->db); \
|
||||
yyextra->pwd = strdup(yytext); \
|
||||
break; \
|
||||
} \
|
||||
if (strcasecmp(yyextra->key, "Server")==0) { \
|
||||
free(yyextra->server); \
|
||||
yyextra->server = strdup(yytext); \
|
||||
break; \
|
||||
} \
|
||||
if (strcasecmp(yyextra->key, "SERVER_ENC")==0) { \
|
||||
free(yyextra->svr_enc); \
|
||||
yyextra->svr_enc = strdup(yytext); \
|
||||
break; \
|
||||
} \
|
||||
if (strcasecmp(yyextra->key, "CLIENT_ENC")==0) { \
|
||||
free(yyextra->cli_enc); \
|
||||
yyextra->cli_enc = strdup(yytext); \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
%}
|
||||
|
||||
%option prefix="todbc_yy"
|
||||
%option extra-type="conn_val_t *"
|
||||
%option nounistd
|
||||
%option never-interactive
|
||||
%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>[^{}\n]+ { 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, conn_val_t *val) {
|
||||
yyscan_t arg = {0};
|
||||
yylex_init(&arg);
|
||||
yyset_debug(0, arg);
|
||||
yyset_extra(val, arg);
|
||||
yy_scan_string(conn, arg);
|
||||
int ret =yylex(arg);
|
||||
yylex_destroy(arg);
|
||||
if (val->key) free(val->key); val->key = NULL;
|
||||
if (ret) {
|
||||
conn_val_reset(val);
|
||||
}
|
||||
return ret ? -1 : 0;
|
||||
}
|
||||
|
||||
void conn_val_reset(conn_val_t *val) {
|
||||
if (val->key) {
|
||||
free(val->key); val->key = NULL;
|
||||
}
|
||||
if (val->dsn) {
|
||||
free(val->dsn); val->dsn = NULL;
|
||||
}
|
||||
if (val->uid) {
|
||||
free(val->uid); val->uid = NULL;
|
||||
}
|
||||
if (val->pwd) {
|
||||
free(val->pwd); val->pwd = NULL;
|
||||
}
|
||||
if (val->db) {
|
||||
free(val->db); val->db = NULL;
|
||||
}
|
||||
if (val->server) {
|
||||
free(val->server); val->server = NULL;
|
||||
}
|
||||
if (val->svr_enc) {
|
||||
free(val->svr_enc); val->svr_enc = NULL;
|
||||
}
|
||||
if (val->cli_enc) {
|
||||
free(val->cli_enc); val->cli_enc = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -14,14 +14,10 @@
|
|||
*/
|
||||
|
||||
#include "todbc_util.h"
|
||||
|
||||
#include "iconv.h"
|
||||
|
||||
#include <sql.h>
|
||||
#include <sqltypes.h>
|
||||
#include "todbc_log.h"
|
||||
#include <iconv.h>
|
||||
#include <sqlext.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
const char* sql_sql_type(int type) {
|
||||
switch (type) {
|
||||
|
@ -111,39 +107,6 @@ int is_valid_sql_sql_type(int type) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int string_conv(const char *fromcode, const char *tocode,
|
||||
const unsigned char *src, size_t sbytes,
|
||||
unsigned char *dst, size_t dbytes,
|
||||
size_t *consumed, size_t *generated)
|
||||
{
|
||||
if (consumed) *consumed = 0;
|
||||
if (generated) *generated = 0;
|
||||
|
||||
if (dbytes <= 0) return -1;
|
||||
dst[0] = '\0';
|
||||
|
||||
iconv_t conv = iconv_open(tocode, fromcode);
|
||||
if (!conv) return -1;
|
||||
|
||||
int r = 0;
|
||||
do {
|
||||
char *s = (char*)src;
|
||||
char *d = (char*)dst;
|
||||
size_t sl = sbytes;
|
||||
size_t dl = dbytes;
|
||||
|
||||
r = iconv(conv, &s, &sl, &d, &dl);
|
||||
*d = '\0';
|
||||
|
||||
if (consumed) *consumed = sbytes - sl;
|
||||
if (generated) *generated = dbytes - dl;
|
||||
|
||||
} while (0);
|
||||
|
||||
iconv_close(conv);
|
||||
return r;
|
||||
}
|
||||
|
||||
int utf8_chars(const char *src)
|
||||
{
|
||||
const char *fromcode = "UTF-8";
|
||||
|
@ -161,78 +124,6 @@ int utf8_chars(const char *src)
|
|||
|
||||
size_t chars = (sizeof(buf) - dlen) / 2;
|
||||
iconv_close(conv);
|
||||
return chars;
|
||||
}
|
||||
|
||||
unsigned char* utf8_to_ucs4le(const char *utf8, size_t *chars)
|
||||
{
|
||||
const char *tocode = "UCS-4LE";
|
||||
const char *fromcode = "UTF-8";
|
||||
|
||||
iconv_t conv = iconv_open(tocode, fromcode);
|
||||
if (!conv) return NULL;
|
||||
|
||||
unsigned char *ucs4le = NULL;
|
||||
|
||||
do {
|
||||
size_t slen = strlen(utf8);
|
||||
size_t dlen = slen * 4;
|
||||
|
||||
ucs4le = (unsigned char*)malloc(dlen+1);
|
||||
if (!ucs4le) break;
|
||||
|
||||
char *src = (char*)utf8;
|
||||
char *dst = (char*)ucs4le;
|
||||
size_t s = slen;
|
||||
size_t d = dlen;
|
||||
iconv(conv, &src, &s, &dst, &d);
|
||||
dst[0] = '\0';
|
||||
|
||||
if (chars) *chars = (dlen - d) / 4;
|
||||
} while (0);
|
||||
|
||||
iconv_close(conv);
|
||||
return ucs4le;
|
||||
}
|
||||
|
||||
char* ucs4le_to_utf8(const unsigned char *ucs4le, size_t slen, size_t *chars)
|
||||
{
|
||||
const char *fromcode = "UCS-4LE";
|
||||
const char *tocode = "UTF-8";
|
||||
|
||||
iconv_t conv = iconv_open(tocode, fromcode);
|
||||
if (!conv) return NULL;
|
||||
|
||||
char *utf8 = NULL;
|
||||
|
||||
do {
|
||||
size_t dlen = slen;
|
||||
|
||||
utf8 = (char*)malloc(dlen+1);
|
||||
if (!utf8) break;
|
||||
|
||||
char *dst = utf8;
|
||||
char *src = (char*)ucs4le;
|
||||
size_t s = slen;
|
||||
size_t d = dlen;
|
||||
iconv(conv, &src, &s, &dst, &d);
|
||||
dst[0] = '\0';
|
||||
|
||||
if (chars) *chars = (slen - s) / 4;
|
||||
} while (0);
|
||||
|
||||
iconv_close(conv);
|
||||
return utf8;
|
||||
}
|
||||
|
||||
SQLCHAR* wchars_to_chars(const SQLWCHAR *wchars, size_t chs, size_t *bytes)
|
||||
{
|
||||
size_t dlen = chs * 4;
|
||||
SQLCHAR *dst = (SQLCHAR*)malloc(dlen + 1);
|
||||
if (!dst) return NULL;
|
||||
|
||||
string_conv("UCS-2LE", "UTF-8", (const unsigned char*)wchars, chs * sizeof(*wchars), dst, dlen + 1, NULL, bytes);
|
||||
|
||||
return dst;
|
||||
return (int)chars;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,33 +16,10 @@
|
|||
#ifndef _TODBC_UTIL_H_
|
||||
#define _TODBC_UTIL_H_
|
||||
|
||||
#include <libgen.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "os.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)
|
||||
|
||||
|
||||
#include <sqltypes.h>
|
||||
|
||||
const char* sql_sql_type(int type);
|
||||
const char* sql_c_type(int type);
|
||||
|
@ -50,14 +27,7 @@ const char* sql_c_type(int type);
|
|||
int is_valid_sql_c_type(int type);
|
||||
int is_valid_sql_sql_type(int type);
|
||||
|
||||
int string_conv(const char *fromcode, const char *tocode,
|
||||
const unsigned char *src, size_t sbytes,
|
||||
unsigned char *dst, size_t dbytes,
|
||||
size_t *consumed, size_t *generated);
|
||||
int utf8_chars(const char *src);
|
||||
|
||||
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);
|
||||
|
||||
#endif // _TODBC_UTIL_H_
|
||||
|
||||
|
|
|
@ -1,7 +1,18 @@
|
|||
PROJECT(TDengine)
|
||||
|
||||
IF (TD_LINUX)
|
||||
AUX_SOURCE_DIRECTORY(. SRC)
|
||||
# AUX_SOURCE_DIRECTORY(. SRC)
|
||||
ADD_EXECUTABLE(tcodbc main.c)
|
||||
TARGET_LINK_LIBRARIES(tcodbc odbc)
|
||||
ADD_EXECUTABLE(tconv tconv.c)
|
||||
ENDIF ()
|
||||
|
||||
IF (TD_WINDOWS_64)
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /GL")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /GL")
|
||||
# AUX_SOURCE_DIRECTORY(. SRC)
|
||||
ADD_EXECUTABLE(tcodbc main.c)
|
||||
TARGET_LINK_LIBRARIES(tcodbc odbc32 odbccp32 user32 legacy_stdio_definitions os)
|
||||
ADD_EXECUTABLE(tconv tconv.c)
|
||||
TARGET_LINK_LIBRARIES(tconv tutil)
|
||||
ENDIF ()
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
P:drop database if exists m;
|
||||
P:create database m;
|
||||
P:use m;
|
||||
|
||||
P:drop table if exists 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, name) values('2020-10-10 00:00:00', 0, 1);
|
||||
P:insert into t (ts, blob, name) values('2020-10-10 00:00:00.001', 1, 2);
|
||||
P:insert into t (ts, blob, name) values('2020-10-10 00:00:00.002', '你', '好');
|
||||
P:insert into t (ts, blob, name) values('2020-10-10 00:00:00.003', 'abc', 'd');
|
||||
P:select * from t;
|
||||
|
|
@ -1,14 +1,38 @@
|
|||
#include "../src/todbc_log.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include "os.h"
|
||||
#endif
|
||||
#include <sql.h>
|
||||
#include <sqlext.h>
|
||||
#include <odbcinst.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "os.h"
|
||||
#define CHK_TEST(statement) \
|
||||
do { \
|
||||
D("testing: %s", #statement); \
|
||||
int r = (statement); \
|
||||
if (r) { \
|
||||
D("testing failed: %s", #statement); \
|
||||
return 1; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
// static const char *dsn = "TAOS_DSN";
|
||||
// static const char *uid = "root";
|
||||
// static const char *pwd = "taosdata";
|
||||
typedef struct db_column_s db_column_t;
|
||||
struct db_column_s {
|
||||
SQLSMALLINT nameLength;
|
||||
char name[4096]; // seems enough
|
||||
SQLSMALLINT dataType;
|
||||
SQLULEN columnSize;
|
||||
SQLSMALLINT decimalDigits;
|
||||
SQLSMALLINT nullable;
|
||||
};
|
||||
|
||||
static db_column_t *columns = NULL;
|
||||
|
||||
typedef struct data_s data_t;
|
||||
struct data_s {
|
||||
|
@ -37,7 +61,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 +72,149 @@ 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, (SQLSMALLINT)(dsn ? strlen(dsn) : 0),
|
||||
(SQLCHAR*)uid, (SQLSMALLINT)(uid ? strlen(uid) : 0),
|
||||
(SQLCHAR*)pwd, (SQLSMALLINT)(pwd ? strlen(pwd) : 0));
|
||||
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 = (SQLSMALLINT)(connstr ? strlen(connstr) : 0);
|
||||
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 SQLRETURN traverse_cols(SQLHSTMT stmt, SQLSMALLINT cols) {
|
||||
SQLRETURN r = SQL_ERROR;
|
||||
for (SQLSMALLINT i=0; i<cols; ++i) {
|
||||
db_column_t column = {0};
|
||||
r = SQLDescribeCol(stmt, (SQLUSMALLINT)(i+1), (SQLCHAR*)column.name,
|
||||
(SQLSMALLINT)sizeof(column.name), &column.nameLength,
|
||||
&column.dataType, &column.columnSize,
|
||||
&column.decimalDigits, &column.nullable);
|
||||
CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "");
|
||||
D("col%02d:[%s]%d,type:[%d],colSize:[%"PRId64"],decimalDigits:[%d],nullable:[%d]",
|
||||
i+1, column.name, column.nameLength, column.dataType, column.columnSize,
|
||||
column.decimalDigits, column.nullable);
|
||||
db_column_t *col = (db_column_t*)realloc(columns, (size_t)(i+1)*sizeof(*col));
|
||||
if (!col) {
|
||||
D("out of memory");
|
||||
return SQL_ERROR;
|
||||
}
|
||||
col[i] = column;
|
||||
columns = col;
|
||||
}
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
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 = SQLExecute(stmt);
|
||||
CHK_RESULT(r, SQL_HANDLE_STMT, stmt);
|
||||
SQLSMALLINT cols = 0;
|
||||
r = SQLNumResultCols(stmt, &cols);
|
||||
CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "");
|
||||
if (r) break;
|
||||
fprintf(stderr, "done\n");
|
||||
if (cols <= 0) break;
|
||||
r = traverse_cols(stmt, cols);
|
||||
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, (SQLUSMALLINT)(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;
|
||||
}
|
||||
|
||||
|
@ -74,158 +224,450 @@ static int do_insert(SQLHSTMT stmt, data_t data) {
|
|||
SQLLEN lblob;
|
||||
|
||||
const char *statement = "insert into t values (?, ?, ?, ?, ?, ?, ?, ?, ?,?)";
|
||||
int ignored = 0;
|
||||
#define ignored 0
|
||||
|
||||
do {
|
||||
fprintf(stderr, "prepare [%s]\n", statement);
|
||||
r = SQLPrepare(stmt, (SQLCHAR*)statement, strlen(statement));
|
||||
CHK_RESULT(r, SQL_HANDLE_STMT, stmt);
|
||||
r = SQLPrepare(stmt, (SQLCHAR*)statement, (SQLINTEGER)strlen(statement));
|
||||
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);
|
||||
|
||||
#undef ignored
|
||||
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) {
|
||||
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;
|
||||
|
||||
int ok = 0;
|
||||
do {
|
||||
r = SQLAllocConnect(env, &conn);
|
||||
CHK_RESULT(r, SQL_HANDLE_ENV, env);
|
||||
SQLRETURN r = SQL_SUCCESS;
|
||||
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")) {
|
||||
break;
|
||||
}
|
||||
for (size_t i=0; i<sizeof(pre_stmts)/sizeof(pre_stmts[0]); ++i) {
|
||||
n = do_statement(stmt, pre_stmts[i]);
|
||||
if (n) 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.456f;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
n = do_insert(stmt, data);
|
||||
if (n) 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);
|
||||
ok = 1;
|
||||
} while (0);
|
||||
SQLDisconnect(conn);
|
||||
if (!ok) break;
|
||||
ok = 0;
|
||||
for (size_t i=0; i<sizeof(pro_stmts)/sizeof(pro_stmts[0]); ++i) {
|
||||
n = do_statement(stmt, pro_stmts[i]);
|
||||
if (n) break;
|
||||
}
|
||||
ok = 1;
|
||||
} while (0);
|
||||
SQLFreeConnect(conn);
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||
} while (0);
|
||||
SQLDisconnect(conn);
|
||||
SQLFreeConnect(conn);
|
||||
SQLFreeEnv(env);
|
||||
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
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 = 0;
|
||||
#ifdef _MSC_VER
|
||||
n = taosGetline(&line, &len, f);
|
||||
#else
|
||||
n = getline(&line, &len, f);
|
||||
#endif
|
||||
if (n==-1) break;
|
||||
|
||||
const char *p = NULL;
|
||||
do {
|
||||
if (line[0] == '#') break;
|
||||
if (n>0 && line[n-1] == '\n') line[n-1]='\0';
|
||||
if (n>0 && line[n-1] == '\r') line[n-1]='\0';
|
||||
if (n>1 && line[n-2] == '\r') line[n-2]='\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));
|
||||
}
|
||||
if (sqls) {
|
||||
r = test_sqls_in_conn(env, conn, sqls);
|
||||
}
|
||||
SQLDisconnect(conn);
|
||||
SQLFreeConnect(conn);
|
||||
SQLFreeEnv(env);
|
||||
return r ? 1 : 0;
|
||||
}
|
||||
|
||||
void usage(const char *arg0) {
|
||||
fprintf(stdout, "%s usage:\n", arg0);
|
||||
fprintf(stdout, "%s [--dsn <dsn>] [--uid <uid>] [--pwd <pwd>] [--dcs <dcs>] [--sts <sts>]\n", arg0);
|
||||
fprintf(stdout, " --dsn <dsn>: DSN\n");
|
||||
fprintf(stdout, " --uid <uid>: UID\n");
|
||||
fprintf(stdout, " --pwd <pwd>: PWD\n");
|
||||
fprintf(stdout, " --dcs <dcs>: driver connection string\n");
|
||||
fprintf(stdout, " --sts <sts>: file where statements store\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// if (argc==1) {
|
||||
// CHK_TEST(test_env());
|
||||
// CHK_TEST(test1("TAOS_DSN", "root", "taoxsdata"));
|
||||
// D("Done!");
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
const char *dsn = NULL;
|
||||
const char *uid = NULL;
|
||||
const char *pwd = NULL;
|
||||
const char *dcs = NULL; // driver connection string
|
||||
const char *sts = NULL; // statements file
|
||||
for (size_t i=1; i<argc; ++i) {
|
||||
const char *arg = argv[i];
|
||||
if (strcmp(arg, "-h")==0) {
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
if (strcmp(arg, "--dsn")==0) {
|
||||
++i;
|
||||
if (i>=argc) {
|
||||
D("<dsn> expected but got nothing");
|
||||
return 1;
|
||||
}
|
||||
if (dcs) {
|
||||
D("--dcs has already been specified");
|
||||
return 1;
|
||||
}
|
||||
dsn = argv[i];
|
||||
continue;
|
||||
}
|
||||
if (strcmp(arg, "--uid")==0) {
|
||||
++i;
|
||||
if (i>=argc) {
|
||||
D("<uid> expected but got nothing");
|
||||
return 1;
|
||||
}
|
||||
uid = argv[i];
|
||||
continue;
|
||||
}
|
||||
if (strcmp(arg, "--pwd")==0) {
|
||||
++i;
|
||||
if (i>=argc) {
|
||||
D("<pwd> expected but got nothing");
|
||||
return 1;
|
||||
}
|
||||
pwd = argv[i];
|
||||
continue;
|
||||
}
|
||||
if (strcmp(arg, "--dcs")==0) {
|
||||
++i;
|
||||
if (i>=argc) {
|
||||
D("<dcs> expected but got nothing");
|
||||
return 1;
|
||||
}
|
||||
if (dsn || uid || pwd) {
|
||||
D("either of --dsn/--uid/--pwd has already been specified");
|
||||
return 1;
|
||||
}
|
||||
dcs = argv[i];
|
||||
continue;
|
||||
}
|
||||
if (strcmp(arg, "--sts")==0) {
|
||||
++i;
|
||||
if (i>=argc) {
|
||||
D("<sts> expected but got nothing");
|
||||
return 1;
|
||||
}
|
||||
sts = argv[i];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
CHK_TEST(test_sqls(dsn, uid, pwd, dcs, sts));
|
||||
D("Done!");
|
||||
return 0;
|
||||
|
||||
if (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;
|
||||
|
||||
dsn = NULL;
|
||||
uid = NULL;
|
||||
pwd = NULL;
|
||||
connstr = argv[1];
|
||||
sqls = argv[2];
|
||||
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));
|
||||
}
|
||||
|
||||
D("Done!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
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')
|
||||
|
||||
cursor = cnxn.cursor()
|
||||
cursor.execute("SELECT * from db.t")
|
||||
row = cursor.fetchone()
|
||||
while row:
|
||||
print(row)
|
||||
row = cursor.fetchone()
|
||||
cursor.close()
|
||||
#cursor = cnxn.cursor()
|
||||
#cursor.execute("SELECT * from db.t")
|
||||
#row = cursor.fetchone()
|
||||
#while row:
|
||||
# print(row)
|
||||
# row = cursor.fetchone()
|
||||
#cursor.close()
|
||||
|
||||
#cursor = cnxn.cursor()
|
||||
#cursor.execute("""
|
||||
|
@ -36,32 +37,32 @@ cursor.execute("create database db");
|
|||
cursor.close()
|
||||
|
||||
cursor = cnxn.cursor()
|
||||
cursor.execute("create table db.t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), blob nchar(10))");
|
||||
cursor.execute("create table db.mt (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), blob nchar(10))");
|
||||
cursor.close()
|
||||
|
||||
cursor = cnxn.cursor()
|
||||
cursor.execute("insert into db.t values('2020-10-13 06:44:00', 1, 127, 32767, 32768, 32769, 123.456, 789.987, 'hello', 'world')")
|
||||
cursor.execute("insert into db.mt values('2020-10-13 06:44:00', 1, 127, 32767, 32768, 32769, 123.456, 789.987, 'hello', 'world')")
|
||||
cursor.close()
|
||||
|
||||
cursor = cnxn.cursor()
|
||||
cursor.execute("insert into db.t values(?,?,?,?,?,?,?,?,?,?)", "2020-10-13 07:06:00", 0, 127, 32767, 32768, 32769, 123.456, 789.987, "hel后lo", "wo哈rld");
|
||||
cursor.execute("insert into db.mt values(?,?,?,?,?,?,?,?,?,?)", "2020-10-13 07:06:00", 0, 127, 32767, 32768, 32769, 123.456, 789.987, "hel后lo", "wo哈rld");
|
||||
cursor.close()
|
||||
|
||||
cursor = cnxn.cursor()
|
||||
cursor.execute("SELECT * from db.t")
|
||||
cursor.execute("SELECT * from db.mt")
|
||||
row = cursor.fetchone()
|
||||
while row:
|
||||
print(row)
|
||||
row = cursor.fetchone()
|
||||
cursor.close()
|
||||
|
||||
cursor = cnxn.cursor()
|
||||
cursor.execute("drop database if exists db");
|
||||
cursor.close()
|
||||
|
||||
cursor = cnxn.cursor()
|
||||
cursor.execute("create database db");
|
||||
cursor.close()
|
||||
#cursor = cnxn.cursor()
|
||||
#cursor.execute("drop database if exists db");
|
||||
#cursor.close()
|
||||
#
|
||||
#cursor = cnxn.cursor()
|
||||
#cursor.execute("create database db");
|
||||
#cursor.close()
|
||||
|
||||
cursor = cnxn.cursor()
|
||||
cursor.execute("create table db.t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(4), blob nchar(4))");
|
||||
|
@ -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()
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
P:select * from m.t;
|
|
@ -0,0 +1,4 @@
|
|||
P: select * from db.t;
|
||||
P: select * from db.f;
|
||||
P: select * from db.v;
|
||||
P: select * from db.mt;
|
|
@ -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;
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
#include "../src/todbc_log.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <iconv.h>
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static void usage(const char *arg0);
|
||||
static int do_conv(iconv_t cnv, FILE *fin, FILE *fout);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const char *from_enc = "UTF-8";
|
||||
const char *to_enc = "UTF-8";
|
||||
const char *dst_file = NULL;
|
||||
const char *src = NULL;
|
||||
#ifdef _MSC_VER
|
||||
from_enc = "CP936";
|
||||
to_enc = "CP936";
|
||||
#endif
|
||||
for (int i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
if (strcmp(arg, "-h") == 0) {
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
} else if (strcmp(arg, "-f") == 0 ) {
|
||||
i += 1;
|
||||
if (i>=argc) {
|
||||
fprintf(stderr, "expecing <from_enc>, but got nothing\n");
|
||||
return 1;
|
||||
}
|
||||
from_enc = argv[i];
|
||||
continue;
|
||||
} else if (strcmp(arg, "-t") == 0 ) {
|
||||
i += 1;
|
||||
if (i>=argc) {
|
||||
fprintf(stderr, "expecing <to_enc>, but got nothing\n");
|
||||
return 1;
|
||||
}
|
||||
to_enc = argv[i];
|
||||
continue;
|
||||
} else if (strcmp(arg, "-o") == 0 ) {
|
||||
i += 1;
|
||||
if (i>=argc) {
|
||||
fprintf(stderr, "expecing <dst_file>, but got nothing\n");
|
||||
return 1;
|
||||
}
|
||||
dst_file = argv[i];
|
||||
continue;
|
||||
} else if (arg[0]=='-') {
|
||||
fprintf(stderr, "unknown argument: [%s]\n", arg);
|
||||
return 1;
|
||||
} else {
|
||||
if (src) {
|
||||
fprintf(stderr, "does not allow multiple files\n");
|
||||
return 1;
|
||||
}
|
||||
src = arg;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
int r = -1;
|
||||
FILE *fin = src ? fopen(src, "rb") : stdin;
|
||||
FILE *fout = dst_file ? fopen(dst_file, "wb") : stdout;
|
||||
iconv_t cnv = iconv_open(to_enc, from_enc);
|
||||
do {
|
||||
if (!fin) {
|
||||
fprintf(stderr, "failed to open file [%s]\n", src);
|
||||
break;
|
||||
}
|
||||
if (!fout) {
|
||||
fprintf(stderr, "failed to open file [%s]\n", dst_file);
|
||||
break;
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
if (fout == stdout) {
|
||||
r = _setmode(_fileno(fout), _O_BINARY);
|
||||
if (r == -1) {
|
||||
fprintf(stderr, "Cannot set binary mode for output stream: %d[%s]\n", errno, strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cnv == (iconv_t)-1) {
|
||||
fprintf(stderr, "failed to open conv from [%s] to [%s]: [%s]\n", from_enc, to_enc, strerror(errno));
|
||||
break;
|
||||
}
|
||||
r = do_conv(cnv, fin, fout);
|
||||
iconv_close(cnv);
|
||||
cnv = (iconv_t)-1;
|
||||
} while (0);
|
||||
if (fin && fin != stdin) fclose(fin);
|
||||
if (fout && fout != stdout) fclose(fout);
|
||||
return r ? 1 : 0;
|
||||
}
|
||||
|
||||
static void usage(const char *arg0) {
|
||||
fprintf(stderr, "%s -h | [-f <from_enc>] [-t <to_enc>] [-o <dst file>] [file]\n", arg0);
|
||||
return;
|
||||
}
|
||||
|
||||
#define IN_SIZE (64*1024)
|
||||
#define OUT_SIZE (8*IN_SIZE)
|
||||
static int do_conv(iconv_t cnv, FILE *fin, FILE *fout) {
|
||||
int r = 0;
|
||||
char src[IN_SIZE];
|
||||
size_t slen = sizeof(src);
|
||||
char dst[OUT_SIZE];
|
||||
size_t dlen = sizeof(dst);
|
||||
char *start = src;
|
||||
while (!feof(fin)) {
|
||||
slen = (size_t)(src + sizeof(src) - start);
|
||||
size_t n = fread(start, 1, slen, fin);
|
||||
if (n>0) {
|
||||
char *ss = src;
|
||||
size_t sl = n;
|
||||
while (sl) {
|
||||
char *dd = dst;
|
||||
size_t dn = dlen;
|
||||
size_t v = iconv(cnv, &ss, &sl, &dd, &dn);
|
||||
if (v==(size_t)-1) {
|
||||
int err = errno;
|
||||
if (err == EILSEQ) {
|
||||
fprintf(stderr, "failed to convert: [%s]\n", strerror(err));
|
||||
r = -1;
|
||||
break;
|
||||
}
|
||||
if (err == EINVAL) {
|
||||
fprintf(stderr, "[%s]\n", strerror(errno));
|
||||
size_t ava = (size_t)(src + sizeof(src) - ss);
|
||||
memcpy(src, ss, ava);
|
||||
start = ss;
|
||||
} else {
|
||||
fprintf(stderr, "internal logic error: [%s]\n", strerror(errno));
|
||||
r = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
n = fwrite(dst, 1, (size_t)(dd-dst), fout);
|
||||
if (n<dd-dst) {
|
||||
fprintf(stderr, "failed to write: [%s]\n", strerror(errno));
|
||||
r = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r) break;
|
||||
}
|
||||
}
|
||||
return r ? -1 : 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
PROJECT(TDengine)
|
||||
|
||||
IF (TD_LINUX)
|
||||
ADD_EXECUTABLE(todbcinst main.c)
|
||||
TARGET_LINK_LIBRARIES(todbcinst odbc odbcinst)
|
||||
ENDIF ()
|
||||
|
||||
IF (TD_WINDOWS_64)
|
||||
ADD_EXECUTABLE(todbcinst main.c)
|
||||
TARGET_LINK_LIBRARIES(todbcinst odbc32 odbccp32 user32 legacy_stdio_definitions os)
|
||||
INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/todbcinst.exe DESTINATION .)
|
||||
ENDIF ()
|
|
@ -0,0 +1,165 @@
|
|||
#include "../src/todbc_log.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include "os.h"
|
||||
#endif
|
||||
#include <odbcinst.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static void usage(const char *arg0);
|
||||
static int do_install(int i, int argc, char *argv[]);
|
||||
static int do_uninstall(int i, int argc, char *argv[]);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
if (strcmp(arg, "-h") == 0) {
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
} else if (strcmp(arg, "-i") == 0 ) {
|
||||
i = do_install(i + 1, argc, argv);
|
||||
if (i > 0) continue;
|
||||
return i == 0 ? 0 : 1;
|
||||
} else if (strcmp(arg, "-u") == 0 ) {
|
||||
i = do_uninstall(i + 1, argc, argv);
|
||||
if (i > 0) continue;
|
||||
return i == 0 ? 0 : 1;
|
||||
} else {
|
||||
fprintf(stderr, "unknown argument: [%s]\n", arg);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(const char *arg0) {
|
||||
fprintf(stderr, "%s -h | -i -n [TaosDriverName] -p [TaosDriverPath] | -u [-f] -n [TaosDriverName]\n", arg0);
|
||||
return;
|
||||
}
|
||||
|
||||
static int do_install(int i, int argc, char *argv[]) {
|
||||
const char* driverName = NULL;
|
||||
#ifdef _MSC_VER
|
||||
const char* driverFile = "todbc.dll";
|
||||
#else
|
||||
const char* driverFile = "libtodbc.so";
|
||||
#endif
|
||||
const char* driverPath = NULL;
|
||||
for (; i < argc; ++i) {
|
||||
const char *arg = argv[i];
|
||||
if (strcmp(arg, "-n") == 0) {
|
||||
i += 1;
|
||||
if (i >= argc) {
|
||||
fprintf(stderr, "expecting TaosDriverName, but got nothing\n");
|
||||
return -1;
|
||||
}
|
||||
arg = argv[i];
|
||||
if (strstr(arg, "TAOS") != arg) {
|
||||
fprintf(stderr, "TaosDriverName shall begin with 'TAOS': [%s]\n", arg);
|
||||
return -1;
|
||||
}
|
||||
driverName = arg;
|
||||
} else if (strcmp(arg, "-p") == 0) {
|
||||
i += 1;
|
||||
if (i >= argc) {
|
||||
fprintf(stderr, "expecting TaosDriverPath, but got nothing\n");
|
||||
return -1;
|
||||
}
|
||||
driverPath = argv[i];
|
||||
} else {
|
||||
fprintf(stderr, "unknown argument: [%s]\n", arg);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (!driverName) {
|
||||
fprintf(stderr, "TaosDriverName not specified\n");
|
||||
return -1;
|
||||
}
|
||||
if (!driverPath) {
|
||||
fprintf(stderr, "TaosDriverPath not specified\n");
|
||||
return -1;
|
||||
}
|
||||
char buf[8192];
|
||||
snprintf(buf, sizeof(buf), "%s%cDriver=%s%cFileUage=0%cConnectFunctions=YYN%c",
|
||||
driverName, 0, driverFile, 0, 0, 0);
|
||||
BOOL ok = 1;
|
||||
DWORD usageCount = 1;
|
||||
char installed[PATH_MAX + 1];
|
||||
WORD len = 0;
|
||||
ok = SQLInstallDriverEx(buf, driverPath, installed, sizeof(installed), &len, ODBC_INSTALL_INQUIRY, &usageCount);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "failed to query TaosDriverName: [%s]\n", driverName);
|
||||
return -1;
|
||||
}
|
||||
int r = 0;
|
||||
#ifdef _MSC_VER
|
||||
r = stricmp(driverPath, installed);
|
||||
#else
|
||||
r = strcasecmp(driverPath, installed);
|
||||
#endif
|
||||
if (r) {
|
||||
fprintf(stderr, "previously installed TaosDriver [%s] has different target path [%s]\n"
|
||||
"it shall be uninstalled before you can install it to different path [%s]\n",
|
||||
driverName, installed, driverPath);
|
||||
return -1;
|
||||
}
|
||||
ok = SQLInstallDriverEx(buf, driverPath, installed, sizeof(installed), &len, ODBC_INSTALL_COMPLETE, &usageCount);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "failed to install TaosDriverName: [%s][%s]\n", driverName, driverPath);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "ODBC driver [%s] has been installed in [%s], and UsageCount is now [%d]\n",
|
||||
driverName, driverPath, usageCount);
|
||||
return argc;
|
||||
}
|
||||
|
||||
static int do_uninstall(int i, int argc, char *argv[]) {
|
||||
int forceful = 0;
|
||||
const char* driverName = NULL;
|
||||
for (; i < argc; ++i) {
|
||||
const char *arg = argv[i];
|
||||
if (strcmp(arg, "-f") == 0) {
|
||||
forceful = 1;
|
||||
} else if (strcmp(arg, "-n") == 0) {
|
||||
i += 1;
|
||||
if (i >= argc) {
|
||||
fprintf(stderr, "expecting TaosDriverName, but got nothing\n");
|
||||
return -1;
|
||||
}
|
||||
arg = argv[i];
|
||||
if (strstr(arg, "TAOS") != arg) {
|
||||
fprintf(stderr, "TaosDriverName shall begin with 'TAOS': [%s]\n", arg);
|
||||
return -1;
|
||||
}
|
||||
driverName = arg;
|
||||
} else {
|
||||
fprintf(stderr, "unknown argument: [%s]\n", arg);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (!driverName) {
|
||||
fprintf(stderr, "TaosDriverName not specified\n");
|
||||
return -1;
|
||||
}
|
||||
BOOL ok = 1;
|
||||
DWORD usageCount = 1;
|
||||
do {
|
||||
ok = SQLRemoveDriver(driverName, 0, &usageCount);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "failed to remove driver [%s]\n", driverName);
|
||||
return -1;
|
||||
}
|
||||
if (!forceful) {
|
||||
fprintf(stderr, "UsageCount for ODBC driver [%s] is now: [%d]\n", driverName, usageCount);
|
||||
return argc;
|
||||
}
|
||||
} while (usageCount > 0);
|
||||
fprintf(stderr, "ODBC driver [%s] is now fully uninstalled\n", driverName);
|
||||
return argc;
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
_timestamp_converter = _convert_microsecond_to_datetime
|
||||
|
||||
if num_of_rows > 0:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::-1]))
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1]))
|
||||
else:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||
|
||||
|
@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bool row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C tinyint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C smallint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::-1]]
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C int row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bigint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C float row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -74,7 +74,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C double row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -82,7 +82,7 @@ def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C binary row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::-1]]
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]]
|
||||
else:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||
|
||||
|
@ -311,29 +311,24 @@ class CTaosInterface(object):
|
|||
@staticmethod
|
||||
def fetchBlock(result, fields):
|
||||
pblock = ctypes.c_void_p(0)
|
||||
num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||
result, ctypes.byref(pblock))
|
||||
|
||||
if num_of_rows == 0:
|
||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||
if pblock :
|
||||
num_of_rows = 1
|
||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
blocks = [None] * len(fields)
|
||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
for i in range(len(fields)):
|
||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
if fields[i]['type'] not in _CONVERT_FUNC:
|
||||
raise DatabaseError("Invalid data type returned from database")
|
||||
if data is None:
|
||||
blocks[i] = [None]
|
||||
else:
|
||||
blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
else:
|
||||
return None, 0
|
||||
|
||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
blocks = [None] * len(fields)
|
||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
for i in range(len(fields)):
|
||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
if data == None:
|
||||
blocks[i] = [None] * num_of_rows
|
||||
continue
|
||||
|
||||
if fields[i]['type'] not in _CONVERT_FUNC:
|
||||
raise DatabaseError("Invalid data type returned from database")
|
||||
|
||||
blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
|
||||
return blocks, abs(num_of_rows)
|
||||
|
||||
@staticmethod
|
||||
def freeResult(result):
|
||||
CTaosInterface.libtaos.taos_free_result(result)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from .cinterface import CTaosInterface
|
||||
from .error import *
|
||||
from .constants import FieldType
|
||||
import threading
|
||||
|
||||
|
||||
class TDengineCursor(object):
|
||||
|
@ -35,6 +36,7 @@ class TDengineCursor(object):
|
|||
self._block_iter = 0
|
||||
self._affected_rows = 0
|
||||
self._logfile = ""
|
||||
self._threadId = threading.get_ident()
|
||||
|
||||
if connection is not None:
|
||||
self._connection = connection
|
||||
|
@ -42,7 +44,7 @@ class TDengineCursor(object):
|
|||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
def __next__(self):
|
||||
if self._result is None or self._fields is None:
|
||||
raise OperationalError("Invalid use of fetch iterator")
|
||||
|
||||
|
@ -137,7 +139,7 @@ class TDengineCursor(object):
|
|||
else:
|
||||
raise ProgrammingError(
|
||||
CTaosInterface.errStr(
|
||||
self._result ), errno)
|
||||
self._result), errno)
|
||||
|
||||
def executemany(self, operation, seq_of_parameters):
|
||||
"""Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters.
|
||||
|
@ -148,6 +150,8 @@ class TDengineCursor(object):
|
|||
"""Fetch the next row of a query result set, returning a single sequence, or None when no more data is available.
|
||||
"""
|
||||
pass
|
||||
def fetchmany(self):
|
||||
pass
|
||||
|
||||
def istype(self, col, dataType):
|
||||
if (dataType.upper() == "BOOL"):
|
||||
|
@ -180,9 +184,6 @@ class TDengineCursor(object):
|
|||
|
||||
return False
|
||||
|
||||
def fetchmany(self):
|
||||
pass
|
||||
|
||||
def fetchall(self):
|
||||
"""Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation.
|
||||
"""
|
||||
|
@ -201,8 +202,6 @@ class TDengineCursor(object):
|
|||
self._rowcount += num_of_fields
|
||||
for i in range(len(self._fields)):
|
||||
buffer[i].extend(block[i])
|
||||
|
||||
|
||||
return list(map(tuple, zip(*buffer)))
|
||||
|
||||
def nextset(self):
|
||||
|
|
|
@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
_timestamp_converter = _convert_microsecond_to_datetime
|
||||
|
||||
if num_of_rows > 0:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::-1]))
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1]))
|
||||
else:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||
|
||||
|
@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bool row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C tinyint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C smallint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::-1]]
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C int row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bigint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C float row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -74,7 +74,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C double row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -82,7 +82,7 @@ def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C binary row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::-1]]
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]]
|
||||
else:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||
|
||||
|
@ -111,7 +111,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
# except ValueError:
|
||||
# res.append(None)
|
||||
# return res
|
||||
# # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)][::-1]]
|
||||
# # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)][::1]]
|
||||
# else:
|
||||
# return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)]]
|
||||
|
||||
|
@ -308,32 +308,48 @@ class CTaosInterface(object):
|
|||
|
||||
return fields
|
||||
|
||||
# @staticmethod
|
||||
# def fetchBlock(result, fields):
|
||||
# pblock = ctypes.c_void_p(0)
|
||||
# num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||
# result, ctypes.byref(pblock))
|
||||
# if num_of_rows == 0:
|
||||
# return None, 0
|
||||
|
||||
# isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
# blocks = [None] * len(fields)
|
||||
# fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
# fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
# for i in range(len(fields)):
|
||||
# data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
|
||||
# if fields[i]['type'] not in _CONVERT_FUNC:
|
||||
# raise DatabaseError("Invalid data type returned from database")
|
||||
# print('====================',fieldLen[i])
|
||||
# blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
|
||||
# return blocks, abs(num_of_rows)
|
||||
@staticmethod
|
||||
def fetchBlock(result, fields):
|
||||
pblock = ctypes.c_void_p(0)
|
||||
num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||
result, ctypes.byref(pblock))
|
||||
|
||||
if num_of_rows == 0:
|
||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||
if pblock :
|
||||
num_of_rows = 1
|
||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
blocks = [None] * len(fields)
|
||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
for i in range(len(fields)):
|
||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
if fields[i]['type'] not in _CONVERT_FUNC:
|
||||
raise DatabaseError("Invalid data type returned from database")
|
||||
if data is None:
|
||||
blocks[i] = [None]
|
||||
else:
|
||||
blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
else:
|
||||
return None, 0
|
||||
|
||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
blocks = [None] * len(fields)
|
||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
for i in range(len(fields)):
|
||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
if data == None:
|
||||
blocks[i] = [None] * num_of_rows
|
||||
continue
|
||||
|
||||
if fields[i]['type'] not in _CONVERT_FUNC:
|
||||
raise DatabaseError("Invalid data type returned from database")
|
||||
|
||||
blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
|
||||
return blocks, abs(num_of_rows)
|
||||
|
||||
@staticmethod
|
||||
def freeResult(result):
|
||||
CTaosInterface.libtaos.taos_free_result(result)
|
||||
|
|
|
@ -216,7 +216,6 @@ class TDengineCursor(object):
|
|||
self._rowcount += num_of_fields
|
||||
for i in range(len(self._fields)):
|
||||
buffer[i].extend(block[i])
|
||||
|
||||
return list(map(tuple, zip(*buffer)))
|
||||
|
||||
def nextset(self):
|
||||
|
|
|
@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
_timestamp_converter = _convert_microsecond_to_datetime
|
||||
|
||||
if num_of_rows > 0:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::-1]))
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1]))
|
||||
else:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
|
||||
|
||||
|
@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bool row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C tinyint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C smallint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::-1]]
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C int row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bigint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C float row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -74,7 +74,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C double row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -82,7 +82,7 @@ def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C binary row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::-1]]
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]]
|
||||
else:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||
|
||||
|
@ -310,27 +310,23 @@ class CTaosInterface(object):
|
|||
@staticmethod
|
||||
def fetchBlock(result, fields):
|
||||
pblock = ctypes.c_void_p(0)
|
||||
num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||
result, ctypes.byref(pblock))
|
||||
|
||||
if num_of_rows == 0:
|
||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||
if pblock :
|
||||
num_of_rows = 1
|
||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
blocks = [None] * len(fields)
|
||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
for i in range(len(fields)):
|
||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
if fields[i]['type'] not in _CONVERT_FUNC:
|
||||
raise DatabaseError("Invalid data type returned from database")
|
||||
if data is None:
|
||||
blocks[i] = [None]
|
||||
else:
|
||||
blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
else:
|
||||
return None, 0
|
||||
|
||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
blocks = [None] * len(fields)
|
||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
for i in range(len(fields)):
|
||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
if data == None:
|
||||
blocks[i] = [None] * num_of_rows
|
||||
continue
|
||||
|
||||
if fields[i]['type'] not in _CONVERT_FUNC:
|
||||
raise DatabaseError("Invalid data type returned from database")
|
||||
|
||||
blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
|
||||
return blocks, abs(num_of_rows)
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
from .cinterface import CTaosInterface
|
||||
from .error import *
|
||||
from .constants import FieldType
|
||||
import threading
|
||||
|
||||
# querySeqNum = 0
|
||||
|
||||
class TDengineCursor(object):
|
||||
"""Database cursor which is used to manage the context of a fetch operation.
|
||||
|
@ -32,6 +36,8 @@ class TDengineCursor(object):
|
|||
self._block_rows = -1
|
||||
self._block_iter = 0
|
||||
self._affected_rows = 0
|
||||
self._logfile = ""
|
||||
self._threadId = threading.get_ident()
|
||||
|
||||
if connection is not None:
|
||||
self._connection = connection
|
||||
|
@ -39,7 +45,7 @@ class TDengineCursor(object):
|
|||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
def __next__(self):
|
||||
if self._result is None or self._fields is None:
|
||||
raise OperationalError("Invalid use of fetch iterator")
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
_timestamp_converter = _convert_microsecond_to_datetime
|
||||
|
||||
if num_of_rows > 0:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::-1]))
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1]))
|
||||
else:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
|
||||
|
||||
|
@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bool row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C tinyint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C smallint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::-1]]
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C int row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bigint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C float row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -74,7 +74,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C double row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::-1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -82,7 +82,7 @@ def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C binary row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::-1]]
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]]
|
||||
else:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||
|
||||
|
@ -225,6 +225,7 @@ class CTaosInterface(object):
|
|||
|
||||
if connection.value == None:
|
||||
print('connect to TDengine failed')
|
||||
raise ConnectionError("connect to TDengine failed")
|
||||
# sys.exit(1)
|
||||
else:
|
||||
print('connect to TDengine success')
|
||||
|
@ -310,27 +311,23 @@ class CTaosInterface(object):
|
|||
@staticmethod
|
||||
def fetchBlock(result, fields):
|
||||
pblock = ctypes.c_void_p(0)
|
||||
num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||
result, ctypes.byref(pblock))
|
||||
|
||||
if num_of_rows == 0:
|
||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||
if pblock :
|
||||
num_of_rows = 1
|
||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
blocks = [None] * len(fields)
|
||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
for i in range(len(fields)):
|
||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
if fields[i]['type'] not in _CONVERT_FUNC:
|
||||
raise DatabaseError("Invalid data type returned from database")
|
||||
if data is None:
|
||||
blocks[i] = [None]
|
||||
else:
|
||||
blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
else:
|
||||
return None, 0
|
||||
|
||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
blocks = [None] * len(fields)
|
||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
for i in range(len(fields)):
|
||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
if data == None:
|
||||
blocks[i] = [None] * num_of_rows
|
||||
continue
|
||||
|
||||
if fields[i]['type'] not in _CONVERT_FUNC:
|
||||
raise DatabaseError("Invalid data type returned from database")
|
||||
|
||||
blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
|
||||
return blocks, abs(num_of_rows)
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
from .cinterface import CTaosInterface
|
||||
from .error import *
|
||||
from .constants import FieldType
|
||||
import threading
|
||||
|
||||
# querySeqNum = 0
|
||||
|
||||
|
||||
class TDengineCursor(object):
|
||||
"""Database cursor which is used to manage the context of a fetch operation.
|
||||
|
@ -32,6 +37,8 @@ class TDengineCursor(object):
|
|||
self._block_rows = -1
|
||||
self._block_iter = 0
|
||||
self._affected_rows = 0
|
||||
self._logfile = ""
|
||||
self._threadId = threading.get_ident()
|
||||
|
||||
if connection is not None:
|
||||
self._connection = connection
|
||||
|
|
|
@ -24,7 +24,7 @@ int32_t dnodeInitVRead();
|
|||
void dnodeCleanupVRead();
|
||||
void dnodeDispatchToVReadQueue(SRpcMsg *pMsg);
|
||||
void * dnodeAllocVReadQueue(void *pVnode);
|
||||
void dnodeFreeVReadQueue(void *rqueue);
|
||||
void dnodeFreeVReadQueue(void *pRqueue);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -168,7 +168,8 @@ static void *dnodeProcessMReadQueue(void *param) {
|
|||
break;
|
||||
}
|
||||
|
||||
dDebug("%p, msg:%s will be processed in mread queue", pRead->rpcMsg.ahandle, taosMsg[pRead->rpcMsg.msgType]);
|
||||
dDebug("msg:%p, app:%p type:%s will be processed in mread queue", pRead->rpcMsg.ahandle, pRead,
|
||||
taosMsg[pRead->rpcMsg.msgType]);
|
||||
int32_t code = mnodeProcessRead(pRead);
|
||||
dnodeSendRpcMReadRsp(pRead, code);
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ void dnodeDispatchToMWriteQueue(SRpcMsg *pMsg) {
|
|||
dnodeSendRedirectMsg(pMsg, true);
|
||||
} else {
|
||||
SMnodeMsg *pWrite = mnodeCreateMsg(pMsg);
|
||||
dDebug("app:%p:%p, msg:%s is put into mwrite queue:%p", pWrite->rpcMsg.ahandle, pWrite,
|
||||
dDebug("msg:%p, app:%p type:%s is put into mwrite queue:%p", pWrite, pWrite->rpcMsg.ahandle,
|
||||
taosMsg[pWrite->rpcMsg.msgType], tsMWriteQueue);
|
||||
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ void dnodeDispatchToMWriteQueue(SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
static void dnodeFreeMWriteMsg(SMnodeMsg *pWrite) {
|
||||
dDebug("app:%p:%p, msg:%s is freed from mwrite queue:%p", pWrite->rpcMsg.ahandle, pWrite,
|
||||
dDebug("msg:%p, app:%p type:%s is freed from mwrite queue:%p", pWrite, pWrite->rpcMsg.ahandle,
|
||||
taosMsg[pWrite->rpcMsg.msgType], tsMWriteQueue);
|
||||
|
||||
mnodeCleanupMsg(pWrite);
|
||||
|
@ -174,7 +174,7 @@ static void *dnodeProcessMWriteQueue(void *param) {
|
|||
break;
|
||||
}
|
||||
|
||||
dDebug("app:%p:%p, msg:%s will be processed in mwrite queue", pWrite->rpcMsg.ahandle, pWrite,
|
||||
dDebug("msg:%p, app:%p type:%s will be processed in mwrite queue", pWrite, pWrite->rpcMsg.ahandle,
|
||||
taosMsg[pWrite->rpcMsg.msgType]);
|
||||
|
||||
int32_t code = mnodeProcessWrite(pWrite);
|
||||
|
@ -188,13 +188,13 @@ void dnodeReprocessMWriteMsg(void *pMsg) {
|
|||
SMnodeMsg *pWrite = pMsg;
|
||||
|
||||
if (!mnodeIsRunning() || tsMWriteQueue == NULL) {
|
||||
dDebug("app:%p:%p, msg:%s is redirected for mnode not running, retry times:%d", pWrite->rpcMsg.ahandle, pWrite,
|
||||
dDebug("msg:%p, app:%p type:%s is redirected for mnode not running, retry times:%d", pWrite, pWrite->rpcMsg.ahandle,
|
||||
taosMsg[pWrite->rpcMsg.msgType], pWrite->retry);
|
||||
|
||||
dnodeSendRedirectMsg(pMsg, true);
|
||||
dnodeFreeMWriteMsg(pWrite);
|
||||
} else {
|
||||
dDebug("app:%p:%p, msg:%s is reput into mwrite queue:%p, retry times:%d", pWrite->rpcMsg.ahandle, pWrite,
|
||||
dDebug("msg:%p, app:%p type:%s is reput into mwrite queue:%p, retry times:%d", pWrite, pWrite->rpcMsg.ahandle,
|
||||
taosMsg[pWrite->rpcMsg.msgType], tsMWriteQueue, pWrite->retry);
|
||||
|
||||
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
||||
|
|
|
@ -216,7 +216,7 @@ static void *dnodeProcessMgmtQueue(void *param) {
|
|||
}
|
||||
|
||||
pMsg = &pMgmt->rpcMsg;
|
||||
dDebug("%p, msg:%p:%s will be processed", pMsg->ahandle, pMgmt, taosMsg[pMsg->msgType]);
|
||||
dDebug("msg:%p, ahandle:%p type:%s will be processed", pMgmt, pMsg->ahandle, taosMsg[pMsg->msgType]);
|
||||
if (dnodeProcessMgmtMsgFp[pMsg->msgType]) {
|
||||
rsp.code = (*dnodeProcessMgmtMsgFp[pMsg->msgType])(pMsg);
|
||||
} else {
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef struct {
|
|||
pthread_mutex_t mutex;
|
||||
} SVReadWorkerPool;
|
||||
|
||||
static void *dnodeProcessReadQueue(void *param);
|
||||
static void *dnodeProcessReadQueue(void *pWorker);
|
||||
|
||||
// module global variable
|
||||
static SVReadWorkerPool tsVReadWP;
|
||||
|
@ -47,7 +47,7 @@ int32_t dnodeInitVRead() {
|
|||
tsVReadWP.min = tsNumOfCores;
|
||||
tsVReadWP.max = tsNumOfCores * tsNumOfThreadsPerCore;
|
||||
if (tsVReadWP.max <= tsVReadWP.min * 2) tsVReadWP.max = 2 * tsVReadWP.min;
|
||||
tsVReadWP.worker = (SVReadWorker *)calloc(sizeof(SVReadWorker), tsVReadWP.max);
|
||||
tsVReadWP.worker = calloc(sizeof(SVReadWorker), tsVReadWP.max);
|
||||
pthread_mutex_init(&tsVReadWP.mutex, NULL);
|
||||
|
||||
if (tsVReadWP.worker == NULL) return -1;
|
||||
|
@ -85,7 +85,7 @@ void dnodeCleanupVRead() {
|
|||
void dnodeDispatchToVReadQueue(SRpcMsg *pMsg) {
|
||||
int32_t queuedMsgNum = 0;
|
||||
int32_t leftLen = pMsg->contLen;
|
||||
char * pCont = (char *)pMsg->pCont;
|
||||
char * pCont = pMsg->pCont;
|
||||
|
||||
while (leftLen > 0) {
|
||||
SMsgHead *pHead = (SMsgHead *)pCont;
|
||||
|
@ -146,8 +146,8 @@ void *dnodeAllocVReadQueue(void *pVnode) {
|
|||
return queue;
|
||||
}
|
||||
|
||||
void dnodeFreeVReadQueue(void *rqueue) {
|
||||
taosCloseQueue(rqueue);
|
||||
void dnodeFreeVReadQueue(void *pRqueue) {
|
||||
taosCloseQueue(pRqueue);
|
||||
}
|
||||
|
||||
void dnodeSendRpcVReadRsp(void *pVnode, SVReadMsg *pRead, int32_t code) {
|
||||
|
@ -159,14 +159,12 @@ void dnodeSendRpcVReadRsp(void *pVnode, SVReadMsg *pRead, int32_t code) {
|
|||
};
|
||||
|
||||
rpcSendResponse(&rpcRsp);
|
||||
vnodeRelease(pVnode);
|
||||
}
|
||||
|
||||
void dnodeDispatchNonRspMsg(void *pVnode, SVReadMsg *pRead, int32_t code) {
|
||||
vnodeRelease(pVnode);
|
||||
}
|
||||
|
||||
static void *dnodeProcessReadQueue(void *param) {
|
||||
static void *dnodeProcessReadQueue(void *pWorker) {
|
||||
SVReadMsg *pRead;
|
||||
int32_t qtype;
|
||||
void * pVnode;
|
||||
|
@ -177,7 +175,7 @@ static void *dnodeProcessReadQueue(void *param) {
|
|||
break;
|
||||
}
|
||||
|
||||
dDebug("%p, msg:%p:%s will be processed in vread queue, qtype:%d", pRead->rpcAhandle, pRead,
|
||||
dDebug("msg:%p, app:%p type:%s will be processed in vread queue, qtype:%d", pRead, pRead->rpcAhandle,
|
||||
taosMsg[pRead->msgType], qtype);
|
||||
|
||||
int32_t code = vnodeProcessRead(pVnode, pRead);
|
||||
|
@ -193,7 +191,7 @@ static void *dnodeProcessReadQueue(void *param) {
|
|||
}
|
||||
}
|
||||
|
||||
taosFreeQitem(pRead);
|
||||
vnodeFreeFromRQueue(pVnode, pRead);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -205,8 +205,8 @@ static void *dnodeProcessVWriteQueue(void *wparam) {
|
|||
bool forceFsync = false;
|
||||
for (int32_t i = 0; i < numOfMsgs; ++i) {
|
||||
taosGetQitem(pWorker->qall, &qtype, (void **)&pWrite);
|
||||
dTrace("%p, msg:%p:%s will be processed in vwrite queue, qtype:%s hver:%" PRIu64, pWrite->rpcAhandle, pWrite,
|
||||
taosMsg[pWrite->pHead->msgType], qtypeStr[qtype], pWrite->pHead->version);
|
||||
dTrace("msg:%p, app:%p type:%s will be processed in vwrite queue, qtype:%s hver:%" PRIu64, pWrite,
|
||||
pWrite->rpcAhandle, taosMsg[pWrite->pHead->msgType], qtypeStr[qtype], pWrite->pHead->version);
|
||||
|
||||
pWrite->code = vnodeProcessWrite(pVnode, pWrite->pHead, qtype, &pWrite->rspRet);
|
||||
if (pWrite->code <= 0) pWrite->processedCount = 1;
|
||||
|
|
|
@ -57,7 +57,7 @@ void *dnodeAllocVWriteQueue(void *pVnode);
|
|||
void dnodeFreeVWriteQueue(void *pWqueue);
|
||||
void dnodeSendRpcVWriteRsp(void *pVnode, void *pWrite, int32_t code);
|
||||
void *dnodeAllocVReadQueue(void *pVnode);
|
||||
void dnodeFreeVReadQueue(void *rqueue);
|
||||
void dnodeFreeVReadQueue(void *pRqueue);
|
||||
|
||||
int32_t dnodeAllocateMPeerQueue();
|
||||
void dnodeFreeMPeerQueue();
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#define TDENGINE_TAOS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -109,13 +110,14 @@ DLL_EXPORT TAOS_RES *taos_query(TAOS *taos, const char *sql);
|
|||
DLL_EXPORT TAOS_ROW taos_fetch_row(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_result_precision(TAOS_RES *res); // get the time precision of result
|
||||
DLL_EXPORT void taos_free_result(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_field_count(TAOS_RES *tres);
|
||||
DLL_EXPORT int taos_field_count(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_num_fields(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_affected_rows(TAOS_RES *res);
|
||||
DLL_EXPORT TAOS_FIELD *taos_fetch_fields(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_select_db(TAOS *taos, const char *db);
|
||||
DLL_EXPORT int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields);
|
||||
DLL_EXPORT void taos_stop_query(TAOS_RES *res);
|
||||
DLL_EXPORT bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col);
|
||||
|
||||
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows);
|
||||
int taos_validate_sql(TAOS *taos, const char *sql);
|
||||
|
|
|
@ -24,9 +24,9 @@ extern "C" {
|
|||
#include <stdbool.h>
|
||||
|
||||
#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
|
||||
#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
|
||||
|
||||
#define TAOS_SYSTEM_ERROR(code) (0x80ff0000 | (code))
|
||||
|
@ -107,6 +107,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_CONN_KILLED, 0, 0x0215, "Connection
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_SQL_SYNTAX_ERROR, 0, 0x0216, "Syntax error in SQL")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DB_NOT_SELECTED, 0, 0x0217, "Database not specified or available")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TABLE_NAME, 0, 0x0218, "Table does not exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_EXCEED_SQL_LIMIT, 0, 0x0219, "SQL statement too long, check maxSQLLength config")
|
||||
|
||||
// mnode
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_MSG_NOT_PROCESSED, 0, 0x0300, "Message not processed")
|
||||
|
@ -365,20 +366,28 @@ 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")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_NOT_VALID_TS, 0, 0x2111, "not a valid timestamp")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_TOO_LARGE, 0, 0x2112, "src too large")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_BAD_SEQ, 0, 0x2113, "src bad sequence")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_INCOMPLETE, 0, 0x2114, "src incomplete")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_GENERAL, 0, 0x2115, "src general")
|
||||
|
||||
|
||||
#ifdef TAOS_ERROR_C
|
||||
|
|
|
@ -24,18 +24,18 @@ extern "C" {
|
|||
#define TAOS_SYNC_MAX_INDEX 0x7FFFFFFF
|
||||
|
||||
typedef enum _TAOS_SYNC_ROLE {
|
||||
TAOS_SYNC_ROLE_OFFLINE,
|
||||
TAOS_SYNC_ROLE_UNSYNCED,
|
||||
TAOS_SYNC_ROLE_SYNCING,
|
||||
TAOS_SYNC_ROLE_SLAVE,
|
||||
TAOS_SYNC_ROLE_MASTER,
|
||||
TAOS_SYNC_ROLE_OFFLINE = 0,
|
||||
TAOS_SYNC_ROLE_UNSYNCED = 1,
|
||||
TAOS_SYNC_ROLE_SYNCING = 2,
|
||||
TAOS_SYNC_ROLE_SLAVE = 3,
|
||||
TAOS_SYNC_ROLE_MASTER = 4
|
||||
} ESyncRole;
|
||||
|
||||
typedef enum _TAOS_SYNC_STATUS {
|
||||
TAOS_SYNC_STATUS_INIT,
|
||||
TAOS_SYNC_STATUS_START,
|
||||
TAOS_SYNC_STATUS_FILE,
|
||||
TAOS_SYNC_STATUS_CACHE,
|
||||
TAOS_SYNC_STATUS_INIT = 0,
|
||||
TAOS_SYNC_STATUS_START = 1,
|
||||
TAOS_SYNC_STATUS_FILE = 2,
|
||||
TAOS_SYNC_STATUS_CACHE = 3
|
||||
} ESyncStatus;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -23,12 +23,12 @@ extern "C" {
|
|||
#include "twal.h"
|
||||
|
||||
typedef enum _VN_STATUS {
|
||||
TAOS_VN_STATUS_INIT,
|
||||
TAOS_VN_STATUS_READY,
|
||||
TAOS_VN_STATUS_CLOSING,
|
||||
TAOS_VN_STATUS_UPDATING,
|
||||
TAOS_VN_STATUS_RESET,
|
||||
} EVnStatus;
|
||||
TAOS_VN_STATUS_INIT = 0,
|
||||
TAOS_VN_STATUS_READY = 1,
|
||||
TAOS_VN_STATUS_CLOSING = 2,
|
||||
TAOS_VN_STATUS_UPDATING = 3,
|
||||
TAOS_VN_STATUS_RESET = 4,
|
||||
} EVnodeStatus;
|
||||
|
||||
typedef struct {
|
||||
int32_t len;
|
||||
|
@ -81,7 +81,8 @@ void vnodeSetAccess(SVgroupAccess *pAccess, int32_t numOfVnodes);
|
|||
int32_t vnodeInitResources();
|
||||
void vnodeCleanupResources();
|
||||
|
||||
int32_t vnodeWriteToRQueue(void *vparam, void *pCont, int32_t contLen, int8_t qtype, void *rparam);
|
||||
int32_t vnodeWriteToRQueue(void *pVnode, void *pCont, int32_t contLen, int8_t qtype, void *rparam);
|
||||
void vnodeFreeFromRQueue(void *pVnode, SVReadMsg *pRead);
|
||||
int32_t vnodeProcessRead(void *pVnode, SVReadMsg *pRead);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct SMnodeMsg;
|
||||
#include "mnode.h"
|
||||
#include "twal.h"
|
||||
|
||||
typedef enum {
|
||||
SDB_TABLE_CLUSTER = 0,
|
||||
|
@ -36,44 +37,46 @@ typedef enum {
|
|||
} ESdbTable;
|
||||
|
||||
typedef enum {
|
||||
SDB_KEY_STRING,
|
||||
SDB_KEY_INT,
|
||||
SDB_KEY_AUTO,
|
||||
SDB_KEY_VAR_STRING,
|
||||
SDB_KEY_STRING = 0,
|
||||
SDB_KEY_INT = 1,
|
||||
SDB_KEY_AUTO = 2,
|
||||
SDB_KEY_VAR_STRING = 3,
|
||||
} ESdbKey;
|
||||
|
||||
typedef enum {
|
||||
SDB_OPER_GLOBAL,
|
||||
SDB_OPER_LOCAL
|
||||
SDB_OPER_GLOBAL = 0,
|
||||
SDB_OPER_LOCAL = 1
|
||||
} ESdbOper;
|
||||
|
||||
typedef struct SSdbOper {
|
||||
ESdbOper type;
|
||||
int32_t rowSize;
|
||||
int32_t retCode; // for callback in sdb queue
|
||||
int32_t processedCount; // for sync fwd callback
|
||||
int32_t (*reqFp)(struct SMnodeMsg *pMsg);
|
||||
int32_t (*writeCb)(struct SMnodeMsg *pMsg, int32_t code);
|
||||
void * table;
|
||||
void * pObj;
|
||||
void * rowData;
|
||||
struct SMnodeMsg *pMsg;
|
||||
} SSdbOper;
|
||||
typedef struct SSdbRow {
|
||||
ESdbOper type;
|
||||
int32_t processedCount; // for sync fwd callback
|
||||
int32_t code; // for callback in sdb queue
|
||||
int32_t rowSize;
|
||||
void * rowData;
|
||||
void * pObj;
|
||||
void * pTable;
|
||||
SMnodeMsg *pMsg;
|
||||
int32_t (*fpReq)(SMnodeMsg *pMsg);
|
||||
int32_t (*fpRsp)(SMnodeMsg *pMsg, int32_t code);
|
||||
char reserveForSync[16];
|
||||
SWalHead pHead[];
|
||||
} SSdbRow;
|
||||
|
||||
typedef struct {
|
||||
char *tableName;
|
||||
int32_t hashSessions;
|
||||
int32_t maxRowSize;
|
||||
int32_t refCountPos;
|
||||
ESdbTable tableId;
|
||||
char * name;
|
||||
int32_t hashSessions;
|
||||
int32_t maxRowSize;
|
||||
int32_t refCountPos;
|
||||
ESdbTable id;
|
||||
ESdbKey keyType;
|
||||
int32_t (*insertFp)(SSdbOper *pOper);
|
||||
int32_t (*deleteFp)(SSdbOper *pOper);
|
||||
int32_t (*updateFp)(SSdbOper *pOper);
|
||||
int32_t (*encodeFp)(SSdbOper *pOper);
|
||||
int32_t (*decodeFp)(SSdbOper *pDesc);
|
||||
int32_t (*destroyFp)(SSdbOper *pDesc);
|
||||
int32_t (*restoredFp)();
|
||||
int32_t (*fpInsert)(SSdbRow *pRow);
|
||||
int32_t (*fpDelete)(SSdbRow *pRow);
|
||||
int32_t (*fpUpdate)(SSdbRow *pRow);
|
||||
int32_t (*fpEncode)(SSdbRow *pRow);
|
||||
int32_t (*fpDecode)(SSdbRow *pRow);
|
||||
int32_t (*fpDestroy)(SSdbRow *pRow);
|
||||
int32_t (*fpRestored)();
|
||||
} SSdbTableDesc;
|
||||
|
||||
int32_t sdbInit();
|
||||
|
@ -84,20 +87,20 @@ bool sdbIsMaster();
|
|||
bool sdbIsServing();
|
||||
void sdbUpdateMnodeRoles();
|
||||
|
||||
int32_t sdbInsertRow(SSdbOper *pOper);
|
||||
int32_t sdbDeleteRow(SSdbOper *pOper);
|
||||
int32_t sdbUpdateRow(SSdbOper *pOper);
|
||||
int32_t sdbInsertRowImp(SSdbOper *pOper);
|
||||
int32_t sdbInsertRow(SSdbRow *pRow);
|
||||
int32_t sdbDeleteRow(SSdbRow *pRow);
|
||||
int32_t sdbUpdateRow(SSdbRow *pRow);
|
||||
int32_t sdbInsertRowToQueue(SSdbRow *pRow);
|
||||
|
||||
void *sdbGetRow(void *handle, void *key);
|
||||
void *sdbFetchRow(void *handle, void *pIter, void **ppRow);
|
||||
void *sdbGetRow(void *pTable, void *key);
|
||||
void *sdbFetchRow(void *pTable, void *pIter, void **ppRow);
|
||||
void sdbFreeIter(void *pIter);
|
||||
void sdbIncRef(void *thandle, void *pRow);
|
||||
void sdbDecRef(void *thandle, void *pRow);
|
||||
int64_t sdbGetNumOfRows(void *handle);
|
||||
int32_t sdbGetId(void *handle);
|
||||
void sdbIncRef(void *pTable, void *pRow);
|
||||
void sdbDecRef(void *pTable, void *pRow);
|
||||
int64_t sdbGetNumOfRows(void *pTable);
|
||||
int32_t sdbGetId(void *pTable);
|
||||
uint64_t sdbGetVersion();
|
||||
bool sdbCheckRowDeleted(void *thandle, void *pRow);
|
||||
bool sdbCheckRowDeleted(void *pTable, void *pRow);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "taoserror.h"
|
||||
#include "tglobal.h"
|
||||
#include "dnode.h"
|
||||
#include "mnodeDef.h"
|
||||
#include "mnodeInt.h"
|
||||
|
@ -25,36 +26,34 @@
|
|||
#include "mnodeUser.h"
|
||||
#include "mnodeVgroup.h"
|
||||
|
||||
#include "tglobal.h"
|
||||
|
||||
void * tsAcctSdb = NULL;
|
||||
static int32_t tsAcctUpdateSize;
|
||||
static int32_t mnodeCreateRootAcct();
|
||||
|
||||
static int32_t mnodeAcctActionDestroy(SSdbOper *pOper) {
|
||||
SAcctObj *pAcct = pOper->pObj;
|
||||
static int32_t mnodeAcctActionDestroy(SSdbRow *pRow) {
|
||||
SAcctObj *pAcct = pRow->pObj;
|
||||
pthread_mutex_destroy(&pAcct->mutex);
|
||||
tfree(pOper->pObj);
|
||||
tfree(pRow->pObj);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeAcctActionInsert(SSdbOper *pOper) {
|
||||
SAcctObj *pAcct = pOper->pObj;
|
||||
static int32_t mnodeAcctActionInsert(SSdbRow *pRow) {
|
||||
SAcctObj *pAcct = pRow->pObj;
|
||||
memset(&pAcct->acctInfo, 0, sizeof(SAcctInfo));
|
||||
pAcct->acctInfo.accessState = TSDB_VN_ALL_ACCCESS;
|
||||
pthread_mutex_init(&pAcct->mutex, NULL);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeAcctActionDelete(SSdbOper *pOper) {
|
||||
SAcctObj *pAcct = pOper->pObj;
|
||||
static int32_t mnodeAcctActionDelete(SSdbRow *pRow) {
|
||||
SAcctObj *pAcct = pRow->pObj;
|
||||
mnodeDropAllUsers(pAcct);
|
||||
mnodeDropAllDbs(pAcct);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeAcctActionUpdate(SSdbOper *pOper) {
|
||||
SAcctObj *pAcct = pOper->pObj;
|
||||
static int32_t mnodeAcctActionUpdate(SSdbRow *pRow) {
|
||||
SAcctObj *pAcct = pRow->pObj;
|
||||
SAcctObj *pSaved = mnodeGetAcct(pAcct->user);
|
||||
if (pAcct != pSaved) {
|
||||
memcpy(pSaved, pAcct, tsAcctUpdateSize);
|
||||
|
@ -64,19 +63,19 @@ static int32_t mnodeAcctActionUpdate(SSdbOper *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeAcctActionEncode(SSdbOper *pOper) {
|
||||
SAcctObj *pAcct = pOper->pObj;
|
||||
memcpy(pOper->rowData, pAcct, tsAcctUpdateSize);
|
||||
pOper->rowSize = tsAcctUpdateSize;
|
||||
static int32_t mnodeAcctActionEncode(SSdbRow *pRow) {
|
||||
SAcctObj *pAcct = pRow->pObj;
|
||||
memcpy(pRow->rowData, pAcct, tsAcctUpdateSize);
|
||||
pRow->rowSize = tsAcctUpdateSize;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeAcctActionDecode(SSdbOper *pOper) {
|
||||
static int32_t mnodeAcctActionDecode(SSdbRow *pRow) {
|
||||
SAcctObj *pAcct = (SAcctObj *) calloc(1, sizeof(SAcctObj));
|
||||
if (pAcct == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(pAcct, pOper->rowData, tsAcctUpdateSize);
|
||||
pOper->pObj = pAcct;
|
||||
memcpy(pAcct, pRow->rowData, tsAcctUpdateSize);
|
||||
pRow->pObj = pAcct;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -99,29 +98,29 @@ int32_t mnodeInitAccts() {
|
|||
SAcctObj tObj;
|
||||
tsAcctUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
|
||||
|
||||
SSdbTableDesc tableDesc = {
|
||||
.tableId = SDB_TABLE_ACCOUNT,
|
||||
.tableName = "accounts",
|
||||
SSdbTableDesc desc = {
|
||||
.id = SDB_TABLE_ACCOUNT,
|
||||
.name = "accounts",
|
||||
.hashSessions = TSDB_DEFAULT_ACCOUNTS_HASH_SIZE,
|
||||
.maxRowSize = tsAcctUpdateSize,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_STRING,
|
||||
.insertFp = mnodeAcctActionInsert,
|
||||
.deleteFp = mnodeAcctActionDelete,
|
||||
.updateFp = mnodeAcctActionUpdate,
|
||||
.encodeFp = mnodeAcctActionEncode,
|
||||
.decodeFp = mnodeAcctActionDecode,
|
||||
.destroyFp = mnodeAcctActionDestroy,
|
||||
.restoredFp = mnodeAcctActionRestored
|
||||
.fpInsert = mnodeAcctActionInsert,
|
||||
.fpDelete = mnodeAcctActionDelete,
|
||||
.fpUpdate = mnodeAcctActionUpdate,
|
||||
.fpEncode = mnodeAcctActionEncode,
|
||||
.fpDecode = mnodeAcctActionDecode,
|
||||
.fpDestroy = mnodeAcctActionDestroy,
|
||||
.fpRestored = mnodeAcctActionRestored
|
||||
};
|
||||
|
||||
tsAcctSdb = sdbOpenTable(&tableDesc);
|
||||
tsAcctSdb = sdbOpenTable(&desc);
|
||||
if (tsAcctSdb == NULL) {
|
||||
mError("table:%s, failed to create hash", tableDesc.tableName);
|
||||
mError("table:%s, failed to create hash", desc.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mDebug("table:%s, hash is created", tableDesc.tableName);
|
||||
mDebug("table:%s, hash is created", desc.name);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -226,13 +225,13 @@ static int32_t mnodeCreateRootAcct() {
|
|||
pAcct->acctId = sdbGetId(tsAcctSdb);
|
||||
pAcct->createdTime = taosGetTimestampMs();
|
||||
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsAcctSdb,
|
||||
.pObj = pAcct,
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsAcctSdb,
|
||||
.pObj = pAcct,
|
||||
};
|
||||
|
||||
return sdbInsertRow(&oper);
|
||||
return sdbInsertRow(&row);
|
||||
}
|
||||
|
||||
#ifndef _ACCT
|
||||
|
|
|
@ -32,36 +32,36 @@ static int32_t mnodeCreateCluster();
|
|||
static int32_t mnodeGetClusterMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t mnodeRetrieveClusters(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
|
||||
static int32_t mnodeClusterActionDestroy(SSdbOper *pOper) {
|
||||
tfree(pOper->pObj);
|
||||
static int32_t mnodeClusterActionDestroy(SSdbRow *pRow) {
|
||||
tfree(pRow->pObj);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeClusterActionInsert(SSdbOper *pOper) {
|
||||
static int32_t mnodeClusterActionInsert(SSdbRow *pRow) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeClusterActionDelete(SSdbOper *pOper) {
|
||||
static int32_t mnodeClusterActionDelete(SSdbRow *pRow) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeClusterActionUpdate(SSdbOper *pOper) {
|
||||
static int32_t mnodeClusterActionUpdate(SSdbRow *pRow) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeClusterActionEncode(SSdbOper *pOper) {
|
||||
SClusterObj *pCluster = pOper->pObj;
|
||||
memcpy(pOper->rowData, pCluster, tsClusterUpdateSize);
|
||||
pOper->rowSize = tsClusterUpdateSize;
|
||||
static int32_t mnodeClusterActionEncode(SSdbRow *pRow) {
|
||||
SClusterObj *pCluster = pRow->pObj;
|
||||
memcpy(pRow->rowData, pCluster, tsClusterUpdateSize);
|
||||
pRow->rowSize = tsClusterUpdateSize;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeClusterActionDecode(SSdbOper *pOper) {
|
||||
static int32_t mnodeClusterActionDecode(SSdbRow *pRow) {
|
||||
SClusterObj *pCluster = (SClusterObj *) calloc(1, sizeof(SClusterObj));
|
||||
if (pCluster == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(pCluster, pOper->rowData, tsClusterUpdateSize);
|
||||
pOper->pObj = pCluster;
|
||||
memcpy(pCluster, pRow->rowData, tsClusterUpdateSize);
|
||||
pRow->pObj = pCluster;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -84,32 +84,32 @@ int32_t mnodeInitCluster() {
|
|||
SClusterObj tObj;
|
||||
tsClusterUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
|
||||
|
||||
SSdbTableDesc tableDesc = {
|
||||
.tableId = SDB_TABLE_CLUSTER,
|
||||
.tableName = "cluster",
|
||||
SSdbTableDesc desc = {
|
||||
.id = SDB_TABLE_CLUSTER,
|
||||
.name = "cluster",
|
||||
.hashSessions = TSDB_DEFAULT_CLUSTER_HASH_SIZE,
|
||||
.maxRowSize = tsClusterUpdateSize,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_STRING,
|
||||
.insertFp = mnodeClusterActionInsert,
|
||||
.deleteFp = mnodeClusterActionDelete,
|
||||
.updateFp = mnodeClusterActionUpdate,
|
||||
.encodeFp = mnodeClusterActionEncode,
|
||||
.decodeFp = mnodeClusterActionDecode,
|
||||
.destroyFp = mnodeClusterActionDestroy,
|
||||
.restoredFp = mnodeClusterActionRestored
|
||||
.fpInsert = mnodeClusterActionInsert,
|
||||
.fpDelete = mnodeClusterActionDelete,
|
||||
.fpUpdate = mnodeClusterActionUpdate,
|
||||
.fpEncode = mnodeClusterActionEncode,
|
||||
.fpDecode = mnodeClusterActionDecode,
|
||||
.fpDestroy = mnodeClusterActionDestroy,
|
||||
.fpRestored = mnodeClusterActionRestored
|
||||
};
|
||||
|
||||
tsClusterSdb = sdbOpenTable(&tableDesc);
|
||||
tsClusterSdb = sdbOpenTable(&desc);
|
||||
if (tsClusterSdb == NULL) {
|
||||
mError("table:%s, failed to create hash", tableDesc.tableName);
|
||||
mError("table:%s, failed to create hash", desc.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_CLUSTER, mnodeGetClusterMeta);
|
||||
mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_CLUSTER, mnodeRetrieveClusters);
|
||||
|
||||
mDebug("table:%s, hash is created", tableDesc.tableName);
|
||||
mDebug("table:%s, hash is created", desc.name);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -145,13 +145,13 @@ static int32_t mnodeCreateCluster() {
|
|||
mDebug("uid is %s", pCluster->uid);
|
||||
}
|
||||
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsClusterSdb,
|
||||
.pObj = pCluster,
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsClusterSdb,
|
||||
.pObj = pCluster,
|
||||
};
|
||||
|
||||
return sdbInsertRow(&oper);
|
||||
return sdbInsertRow(&row);
|
||||
}
|
||||
|
||||
const char* mnodeGetClusterId() {
|
||||
|
|
|
@ -56,8 +56,8 @@ static void mnodeDestroyDb(SDbObj *pDb) {
|
|||
tfree(pDb);
|
||||
}
|
||||
|
||||
static int32_t mnodeDbActionDestroy(SSdbOper *pOper) {
|
||||
mnodeDestroyDb(pOper->pObj);
|
||||
static int32_t mnodeDbActionDestroy(SSdbRow *pRow) {
|
||||
mnodeDestroyDb(pRow->pObj);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -65,8 +65,8 @@ int64_t mnodeGetDbNum() {
|
|||
return sdbGetNumOfRows(tsDbSdb);
|
||||
}
|
||||
|
||||
static int32_t mnodeDbActionInsert(SSdbOper *pOper) {
|
||||
SDbObj *pDb = pOper->pObj;
|
||||
static int32_t mnodeDbActionInsert(SSdbRow *pRow) {
|
||||
SDbObj *pDb = pRow->pObj;
|
||||
SAcctObj *pAcct = mnodeGetAcct(pDb->acct);
|
||||
|
||||
pthread_mutex_init(&pDb->mutex, NULL);
|
||||
|
@ -91,8 +91,8 @@ static int32_t mnodeDbActionInsert(SSdbOper *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeDbActionDelete(SSdbOper *pOper) {
|
||||
SDbObj *pDb = pOper->pObj;
|
||||
static int32_t mnodeDbActionDelete(SSdbRow *pRow) {
|
||||
SDbObj *pDb = pRow->pObj;
|
||||
SAcctObj *pAcct = mnodeGetAcct(pDb->acct);
|
||||
|
||||
mnodeDropAllChildTables(pDb);
|
||||
|
@ -107,11 +107,11 @@ static int32_t mnodeDbActionDelete(SSdbOper *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeDbActionUpdate(SSdbOper *pOper) {
|
||||
SDbObj *pNew = pOper->pObj;
|
||||
static int32_t mnodeDbActionUpdate(SSdbRow *pRow) {
|
||||
SDbObj *pNew = pRow->pObj;
|
||||
SDbObj *pDb = mnodeGetDb(pNew->name);
|
||||
if (pDb != NULL && pNew != pDb) {
|
||||
memcpy(pDb, pNew, pOper->rowSize);
|
||||
memcpy(pDb, pNew, pRow->rowSize);
|
||||
free(pNew->vgList);
|
||||
free(pNew);
|
||||
}
|
||||
|
@ -120,19 +120,19 @@ static int32_t mnodeDbActionUpdate(SSdbOper *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeDbActionEncode(SSdbOper *pOper) {
|
||||
SDbObj *pDb = pOper->pObj;
|
||||
memcpy(pOper->rowData, pDb, tsDbUpdateSize);
|
||||
pOper->rowSize = tsDbUpdateSize;
|
||||
static int32_t mnodeDbActionEncode(SSdbRow *pRow) {
|
||||
SDbObj *pDb = pRow->pObj;
|
||||
memcpy(pRow->rowData, pDb, tsDbUpdateSize);
|
||||
pRow->rowSize = tsDbUpdateSize;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeDbActionDecode(SSdbOper *pOper) {
|
||||
static int32_t mnodeDbActionDecode(SSdbRow *pRow) {
|
||||
SDbObj *pDb = (SDbObj *) calloc(1, sizeof(SDbObj));
|
||||
if (pDb == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(pDb, pOper->rowData, tsDbUpdateSize);
|
||||
pOper->pObj = pDb;
|
||||
memcpy(pDb, pRow->rowData, tsDbUpdateSize);
|
||||
pRow->pObj = pDb;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -144,23 +144,23 @@ int32_t mnodeInitDbs() {
|
|||
SDbObj tObj;
|
||||
tsDbUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
|
||||
|
||||
SSdbTableDesc tableDesc = {
|
||||
.tableId = SDB_TABLE_DB,
|
||||
.tableName = "dbs",
|
||||
SSdbTableDesc desc = {
|
||||
.id = SDB_TABLE_DB,
|
||||
.name = "dbs",
|
||||
.hashSessions = TSDB_DEFAULT_DBS_HASH_SIZE,
|
||||
.maxRowSize = tsDbUpdateSize,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_STRING,
|
||||
.insertFp = mnodeDbActionInsert,
|
||||
.deleteFp = mnodeDbActionDelete,
|
||||
.updateFp = mnodeDbActionUpdate,
|
||||
.encodeFp = mnodeDbActionEncode,
|
||||
.decodeFp = mnodeDbActionDecode,
|
||||
.destroyFp = mnodeDbActionDestroy,
|
||||
.restoredFp = mnodeDbActionRestored
|
||||
.fpInsert = mnodeDbActionInsert,
|
||||
.fpDelete = mnodeDbActionDelete,
|
||||
.fpUpdate = mnodeDbActionUpdate,
|
||||
.fpEncode = mnodeDbActionEncode,
|
||||
.fpDecode = mnodeDbActionDecode,
|
||||
.fpDestroy = mnodeDbActionDestroy,
|
||||
.fpRestored = mnodeDbActionRestored
|
||||
};
|
||||
|
||||
tsDbSdb = sdbOpenTable(&tableDesc);
|
||||
tsDbSdb = sdbOpenTable(&desc);
|
||||
if (tsDbSdb == NULL) {
|
||||
mError("failed to init db data");
|
||||
return -1;
|
||||
|
@ -412,16 +412,16 @@ static int32_t mnodeCreateDb(SAcctObj *pAcct, SCreateDbMsg *pCreate, SMnodeMsg *
|
|||
pMsg->pDb = pDb;
|
||||
mnodeIncDbRef(pDb);
|
||||
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsDbSdb,
|
||||
.pObj = pDb,
|
||||
.rowSize = sizeof(SDbObj),
|
||||
.pMsg = pMsg,
|
||||
.writeCb = mnodeCreateDbCb
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsDbSdb,
|
||||
.pObj = pDb,
|
||||
.rowSize = sizeof(SDbObj),
|
||||
.pMsg = pMsg,
|
||||
.fpRsp = mnodeCreateDbCb
|
||||
};
|
||||
|
||||
code = sdbInsertRow(&oper);
|
||||
code = sdbInsertRow(&row);
|
||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
mError("db:%s, failed to create, reason:%s", pDb->name, tstrerror(code));
|
||||
pMsg->pDb = NULL;
|
||||
|
@ -440,8 +440,8 @@ bool mnodeCheckIsMonitorDB(char *db, char *monitordb) {
|
|||
}
|
||||
|
||||
#if 0
|
||||
void mnodePrintVgroups(SDbObj *pDb, char *oper) {
|
||||
mInfo("db:%s, vgroup link from head, oper:%s", pDb->name, oper);
|
||||
void mnodePrintVgroups(SDbObj *pDb, char *row) {
|
||||
mInfo("db:%s, vgroup link from head, row:%s", pDb->name, row);
|
||||
SVgObj *pVgroup = pDb->pHead;
|
||||
while (pVgroup != NULL) {
|
||||
mInfo("vgId:%d", pVgroup->vgId);
|
||||
|
@ -807,13 +807,13 @@ static int32_t mnodeSetDbDropping(SDbObj *pDb) {
|
|||
if (pDb->status) return TSDB_CODE_SUCCESS;
|
||||
|
||||
pDb->status = true;
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsDbSdb,
|
||||
.pObj = pDb
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsDbSdb,
|
||||
.pObj = pDb
|
||||
};
|
||||
|
||||
int32_t code = sdbUpdateRow(&oper);
|
||||
int32_t code = sdbUpdateRow(&row);
|
||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
mError("db:%s, failed to set dropping state, reason:%s", pDb->name, tstrerror(code));
|
||||
}
|
||||
|
@ -1019,15 +1019,15 @@ static int32_t mnodeAlterDb(SDbObj *pDb, SAlterDbMsg *pAlter, void *pMsg) {
|
|||
if (memcmp(&newCfg, &pDb->cfg, sizeof(SDbCfg)) != 0) {
|
||||
pDb->cfg = newCfg;
|
||||
pDb->cfgVersion++;
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsDbSdb,
|
||||
.pObj = pDb,
|
||||
.pMsg = pMsg,
|
||||
.writeCb = mnodeAlterDbCb
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsDbSdb,
|
||||
.pObj = pDb,
|
||||
.pMsg = pMsg,
|
||||
.fpRsp = mnodeAlterDbCb
|
||||
};
|
||||
|
||||
code = sdbUpdateRow(&oper);
|
||||
code = sdbUpdateRow(&row);
|
||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
mError("db:%s, failed to alter, reason:%s", pDb->name, tstrerror(code));
|
||||
}
|
||||
|
@ -1071,15 +1071,15 @@ static int32_t mnodeDropDb(SMnodeMsg *pMsg) {
|
|||
SDbObj *pDb = pMsg->pDb;
|
||||
mInfo("db:%s, drop db from sdb", pDb->name);
|
||||
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsDbSdb,
|
||||
.pObj = pDb,
|
||||
.pMsg = pMsg,
|
||||
.writeCb = mnodeDropDbCb
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsDbSdb,
|
||||
.pObj = pDb,
|
||||
.pMsg = pMsg,
|
||||
.fpRsp = mnodeDropDbCb
|
||||
};
|
||||
|
||||
int32_t code = sdbDeleteRow(&oper);
|
||||
int32_t code = sdbDeleteRow(&row);
|
||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
mError("db:%s, failed to drop, reason:%s", pDb->name, tstrerror(code));
|
||||
}
|
||||
|
@ -1134,13 +1134,13 @@ void mnodeDropAllDbs(SAcctObj *pAcct) {
|
|||
|
||||
if (pDb->pAcct == pAcct) {
|
||||
mInfo("db:%s, drop db from sdb for acct:%s is dropped", pDb->name, pAcct->user);
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_LOCAL,
|
||||
.table = tsDbSdb,
|
||||
.pObj = pDb
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_LOCAL,
|
||||
.pTable = tsDbSdb,
|
||||
.pObj = pDb
|
||||
};
|
||||
|
||||
sdbDeleteRow(&oper);
|
||||
sdbDeleteRow(&row);
|
||||
numOfDbs++;
|
||||
}
|
||||
mnodeDecDbRef(pDb);
|
||||
|
|
|
@ -87,13 +87,13 @@ static char* offlineReason[] = {
|
|||
"unknown",
|
||||
};
|
||||
|
||||
static int32_t mnodeDnodeActionDestroy(SSdbOper *pOper) {
|
||||
tfree(pOper->pObj);
|
||||
static int32_t mnodeDnodeActionDestroy(SSdbRow *pRow) {
|
||||
tfree(pRow->pObj);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeDnodeActionInsert(SSdbOper *pOper) {
|
||||
SDnodeObj *pDnode = pOper->pObj;
|
||||
static int32_t mnodeDnodeActionInsert(SSdbRow *pRow) {
|
||||
SDnodeObj *pDnode = pRow->pObj;
|
||||
if (pDnode->status != TAOS_DN_STATUS_DROPPING) {
|
||||
pDnode->status = TAOS_DN_STATUS_OFFLINE;
|
||||
pDnode->lastAccess = tsAccessSquence;
|
||||
|
@ -107,8 +107,8 @@ static int32_t mnodeDnodeActionInsert(SSdbOper *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeDnodeActionDelete(SSdbOper *pOper) {
|
||||
SDnodeObj *pDnode = pOper->pObj;
|
||||
static int32_t mnodeDnodeActionDelete(SSdbRow *pRow) {
|
||||
SDnodeObj *pDnode = pRow->pObj;
|
||||
|
||||
#ifndef _SYNC
|
||||
mnodeDropAllDnodeVgroups(pDnode);
|
||||
|
@ -121,11 +121,11 @@ static int32_t mnodeDnodeActionDelete(SSdbOper *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeDnodeActionUpdate(SSdbOper *pOper) {
|
||||
SDnodeObj *pNew = pOper->pObj;
|
||||
static int32_t mnodeDnodeActionUpdate(SSdbRow *pRow) {
|
||||
SDnodeObj *pNew = pRow->pObj;
|
||||
SDnodeObj *pDnode = mnodeGetDnode(pNew->dnodeId);
|
||||
if (pDnode != NULL && pNew != pDnode) {
|
||||
memcpy(pDnode, pNew, pOper->rowSize);
|
||||
memcpy(pDnode, pNew, pRow->rowSize);
|
||||
free(pNew);
|
||||
}
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
|
@ -134,19 +134,19 @@ static int32_t mnodeDnodeActionUpdate(SSdbOper *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeDnodeActionEncode(SSdbOper *pOper) {
|
||||
SDnodeObj *pDnode = pOper->pObj;
|
||||
memcpy(pOper->rowData, pDnode, tsDnodeUpdateSize);
|
||||
pOper->rowSize = tsDnodeUpdateSize;
|
||||
static int32_t mnodeDnodeActionEncode(SSdbRow *pRow) {
|
||||
SDnodeObj *pDnode = pRow->pObj;
|
||||
memcpy(pRow->rowData, pDnode, tsDnodeUpdateSize);
|
||||
pRow->rowSize = tsDnodeUpdateSize;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeDnodeActionDecode(SSdbOper *pOper) {
|
||||
static int32_t mnodeDnodeActionDecode(SSdbRow *pRow) {
|
||||
SDnodeObj *pDnode = (SDnodeObj *) calloc(1, sizeof(SDnodeObj));
|
||||
if (pDnode == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(pDnode, pOper->rowData, tsDnodeUpdateSize);
|
||||
pOper->pObj = pDnode;
|
||||
memcpy(pDnode, pRow->rowData, tsDnodeUpdateSize);
|
||||
pRow->pObj = pDnode;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -171,23 +171,23 @@ int32_t mnodeInitDnodes() {
|
|||
tsDnodeUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
|
||||
pthread_mutex_init(&tsDnodeEpsMutex, NULL);
|
||||
|
||||
SSdbTableDesc tableDesc = {
|
||||
.tableId = SDB_TABLE_DNODE,
|
||||
.tableName = "dnodes",
|
||||
SSdbTableDesc desc = {
|
||||
.id = SDB_TABLE_DNODE,
|
||||
.name = "dnodes",
|
||||
.hashSessions = TSDB_DEFAULT_DNODES_HASH_SIZE,
|
||||
.maxRowSize = tsDnodeUpdateSize,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_AUTO,
|
||||
.insertFp = mnodeDnodeActionInsert,
|
||||
.deleteFp = mnodeDnodeActionDelete,
|
||||
.updateFp = mnodeDnodeActionUpdate,
|
||||
.encodeFp = mnodeDnodeActionEncode,
|
||||
.decodeFp = mnodeDnodeActionDecode,
|
||||
.destroyFp = mnodeDnodeActionDestroy,
|
||||
.restoredFp = mnodeDnodeActionRestored
|
||||
.fpInsert = mnodeDnodeActionInsert,
|
||||
.fpDelete = mnodeDnodeActionDelete,
|
||||
.fpUpdate = mnodeDnodeActionUpdate,
|
||||
.fpEncode = mnodeDnodeActionEncode,
|
||||
.fpDecode = mnodeDnodeActionDecode,
|
||||
.fpDestroy = mnodeDnodeActionDestroy,
|
||||
.fpRestored = mnodeDnodeActionRestored
|
||||
};
|
||||
|
||||
tsDnodeSdb = sdbOpenTable(&tableDesc);
|
||||
tsDnodeSdb = sdbOpenTable(&desc);
|
||||
if (tsDnodeSdb == NULL) {
|
||||
mError("failed to init dnodes data");
|
||||
return -1;
|
||||
|
@ -296,13 +296,13 @@ void mnodeDecDnodeRef(SDnodeObj *pDnode) {
|
|||
}
|
||||
|
||||
void mnodeUpdateDnode(SDnodeObj *pDnode) {
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsDnodeSdb,
|
||||
.pObj = pDnode
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsDnodeSdb,
|
||||
.pObj = pDnode
|
||||
};
|
||||
|
||||
int32_t code = sdbUpdateRow(&oper);
|
||||
int32_t code = sdbUpdateRow(&row);
|
||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
mError("dnodeId:%d, failed update", pDnode->dnodeId);
|
||||
}
|
||||
|
@ -644,15 +644,15 @@ static int32_t mnodeCreateDnode(char *ep, SMnodeMsg *pMsg) {
|
|||
tstrncpy(pDnode->dnodeEp, ep, TSDB_EP_LEN);
|
||||
taosGetFqdnPortFromEp(ep, pDnode->dnodeFqdn, &pDnode->dnodePort);
|
||||
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsDnodeSdb,
|
||||
.pObj = pDnode,
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsDnodeSdb,
|
||||
.pObj = pDnode,
|
||||
.rowSize = sizeof(SDnodeObj),
|
||||
.pMsg = pMsg
|
||||
.pMsg = pMsg
|
||||
};
|
||||
|
||||
int32_t code = sdbInsertRow(&oper);
|
||||
int32_t code = sdbInsertRow(&row);
|
||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
int dnodeId = pDnode->dnodeId;
|
||||
tfree(pDnode);
|
||||
|
@ -665,14 +665,14 @@ static int32_t mnodeCreateDnode(char *ep, SMnodeMsg *pMsg) {
|
|||
}
|
||||
|
||||
int32_t mnodeDropDnode(SDnodeObj *pDnode, void *pMsg) {
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsDnodeSdb,
|
||||
.pObj = pDnode,
|
||||
.pMsg = pMsg
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsDnodeSdb,
|
||||
.pObj = pDnode,
|
||||
.pMsg = pMsg
|
||||
};
|
||||
|
||||
int32_t code = sdbDeleteRow(&oper);
|
||||
int32_t code = sdbDeleteRow(&row);
|
||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
mError("dnode:%d, failed to drop from cluster, result:%s", pDnode->dnodeId, tstrerror(code));
|
||||
} else {
|
||||
|
@ -1141,7 +1141,7 @@ static int32_t mnodeRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, vo
|
|||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
strcpy(pWrite, mnodeGetMnodeRoleStr(pVgid->role));
|
||||
strcpy(pWrite, syncRole[pVgid->role]);
|
||||
cols++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ void *mnodeCreateMsg(SRpcMsg *pRpcMsg) {
|
|||
|
||||
int32_t mnodeInitMsg(SMnodeMsg *pMsg) {
|
||||
if (pMsg->pUser != NULL) {
|
||||
mDebug("app:%p:%p, user info already inited", pMsg->rpcMsg.ahandle, pMsg);
|
||||
mTrace("msg:%p, app:%p user info already inited", pMsg, pMsg->rpcMsg.ahandle);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,13 +58,13 @@ static int32_t mnodeRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, vo
|
|||
#define mnodeMnodeDestroyLock() pthread_mutex_destroy(&tsMnodeLock)
|
||||
#endif
|
||||
|
||||
static int32_t mnodeMnodeActionDestroy(SSdbOper *pOper) {
|
||||
tfree(pOper->pObj);
|
||||
static int32_t mnodeMnodeActionDestroy(SSdbRow *pRow) {
|
||||
tfree(pRow->pObj);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeMnodeActionInsert(SSdbOper *pOper) {
|
||||
SMnodeObj *pMnode = pOper->pObj;
|
||||
static int32_t mnodeMnodeActionInsert(SSdbRow *pRow) {
|
||||
SMnodeObj *pMnode = pRow->pObj;
|
||||
SDnodeObj *pDnode = mnodeGetDnode(pMnode->mnodeId);
|
||||
if (pDnode == NULL) return TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
|
||||
|
@ -76,8 +76,8 @@ static int32_t mnodeMnodeActionInsert(SSdbOper *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeMnodeActionDelete(SSdbOper *pOper) {
|
||||
SMnodeObj *pMnode = pOper->pObj;
|
||||
static int32_t mnodeMnodeActionDelete(SSdbRow *pRow) {
|
||||
SMnodeObj *pMnode = pRow->pObj;
|
||||
|
||||
SDnodeObj *pDnode = mnodeGetDnode(pMnode->mnodeId);
|
||||
if (pDnode == NULL) return TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
|
@ -88,30 +88,30 @@ static int32_t mnodeMnodeActionDelete(SSdbOper *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeMnodeActionUpdate(SSdbOper *pOper) {
|
||||
SMnodeObj *pMnode = pOper->pObj;
|
||||
static int32_t mnodeMnodeActionUpdate(SSdbRow *pRow) {
|
||||
SMnodeObj *pMnode = pRow->pObj;
|
||||
SMnodeObj *pSaved = mnodeGetMnode(pMnode->mnodeId);
|
||||
if (pMnode != pSaved) {
|
||||
memcpy(pSaved, pMnode, pOper->rowSize);
|
||||
memcpy(pSaved, pMnode, pRow->rowSize);
|
||||
free(pMnode);
|
||||
}
|
||||
mnodeDecMnodeRef(pSaved);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeMnodeActionEncode(SSdbOper *pOper) {
|
||||
SMnodeObj *pMnode = pOper->pObj;
|
||||
memcpy(pOper->rowData, pMnode, tsMnodeUpdateSize);
|
||||
pOper->rowSize = tsMnodeUpdateSize;
|
||||
static int32_t mnodeMnodeActionEncode(SSdbRow *pRow) {
|
||||
SMnodeObj *pMnode = pRow->pObj;
|
||||
memcpy(pRow->rowData, pMnode, tsMnodeUpdateSize);
|
||||
pRow->rowSize = tsMnodeUpdateSize;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeMnodeActionDecode(SSdbOper *pOper) {
|
||||
static int32_t mnodeMnodeActionDecode(SSdbRow *pRow) {
|
||||
SMnodeObj *pMnode = calloc(1, sizeof(SMnodeObj));
|
||||
if (pMnode == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(pMnode, pOper->rowData, tsMnodeUpdateSize);
|
||||
pOper->pObj = pMnode;
|
||||
memcpy(pMnode, pRow->rowData, tsMnodeUpdateSize);
|
||||
pRow->pObj = pMnode;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -137,23 +137,23 @@ int32_t mnodeInitMnodes() {
|
|||
SMnodeObj tObj;
|
||||
tsMnodeUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
|
||||
|
||||
SSdbTableDesc tableDesc = {
|
||||
.tableId = SDB_TABLE_MNODE,
|
||||
.tableName = "mnodes",
|
||||
SSdbTableDesc desc = {
|
||||
.id = SDB_TABLE_MNODE,
|
||||
.name = "mnodes",
|
||||
.hashSessions = TSDB_DEFAULT_MNODES_HASH_SIZE,
|
||||
.maxRowSize = tsMnodeUpdateSize,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_INT,
|
||||
.insertFp = mnodeMnodeActionInsert,
|
||||
.deleteFp = mnodeMnodeActionDelete,
|
||||
.updateFp = mnodeMnodeActionUpdate,
|
||||
.encodeFp = mnodeMnodeActionEncode,
|
||||
.decodeFp = mnodeMnodeActionDecode,
|
||||
.destroyFp = mnodeMnodeActionDestroy,
|
||||
.restoredFp = mnodeMnodeActionRestored
|
||||
.fpInsert = mnodeMnodeActionInsert,
|
||||
.fpDelete = mnodeMnodeActionDelete,
|
||||
.fpUpdate = mnodeMnodeActionUpdate,
|
||||
.fpEncode = mnodeMnodeActionEncode,
|
||||
.fpDecode = mnodeMnodeActionDecode,
|
||||
.fpDestroy = mnodeMnodeActionDestroy,
|
||||
.fpRestored = mnodeMnodeActionRestored
|
||||
};
|
||||
|
||||
tsMnodeSdb = sdbOpenTable(&tableDesc);
|
||||
tsMnodeSdb = sdbOpenTable(&desc);
|
||||
if (tsMnodeSdb == NULL) {
|
||||
mError("failed to init mnodes data");
|
||||
return -1;
|
||||
|
@ -192,10 +192,6 @@ void *mnodeGetNextMnode(void *pIter, SMnodeObj **pMnode) {
|
|||
return sdbFetchRow(tsMnodeSdb, pIter, (void **)pMnode);
|
||||
}
|
||||
|
||||
char *mnodeGetMnodeRoleStr(int32_t role) {
|
||||
return syncRole[role];
|
||||
}
|
||||
|
||||
void mnodeUpdateMnodeEpSet() {
|
||||
mInfo("update mnodes epSet, numOfEps:%d ", mnodeGetMnodesNum());
|
||||
|
||||
|
@ -329,11 +325,11 @@ void mnodeCreateMnode(int32_t dnodeId, char *dnodeEp, bool needConfirm) {
|
|||
pMnode->mnodeId = dnodeId;
|
||||
pMnode->createdTime = taosGetTimestampMs();
|
||||
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsMnodeSdb,
|
||||
.pObj = pMnode,
|
||||
.writeCb = mnodeCreateMnodeCb
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsMnodeSdb,
|
||||
.pObj = pMnode,
|
||||
.fpRsp = mnodeCreateMnodeCb
|
||||
};
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
@ -346,7 +342,7 @@ void mnodeCreateMnode(int32_t dnodeId, char *dnodeEp, bool needConfirm) {
|
|||
return;
|
||||
}
|
||||
|
||||
code = sdbInsertRow(&oper);
|
||||
code = sdbInsertRow(&row);
|
||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
mError("dnode:%d, failed to create mnode, ep:%s reason:%s", dnodeId, dnodeEp, tstrerror(code));
|
||||
tfree(pMnode);
|
||||
|
@ -356,8 +352,8 @@ void mnodeCreateMnode(int32_t dnodeId, char *dnodeEp, bool needConfirm) {
|
|||
void mnodeDropMnodeLocal(int32_t dnodeId) {
|
||||
SMnodeObj *pMnode = mnodeGetMnode(dnodeId);
|
||||
if (pMnode != NULL) {
|
||||
SSdbOper oper = {.type = SDB_OPER_LOCAL, .table = tsMnodeSdb, .pObj = pMnode};
|
||||
sdbDeleteRow(&oper);
|
||||
SSdbRow row = {.type = SDB_OPER_LOCAL, .pTable = tsMnodeSdb, .pObj = pMnode};
|
||||
sdbDeleteRow(&row);
|
||||
mnodeDecMnodeRef(pMnode);
|
||||
}
|
||||
|
||||
|
@ -371,13 +367,13 @@ int32_t mnodeDropMnode(int32_t dnodeId) {
|
|||
return TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsMnodeSdb,
|
||||
.pObj = pMnode
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsMnodeSdb,
|
||||
.pObj = pMnode
|
||||
};
|
||||
|
||||
int32_t code = sdbDeleteRow(&oper);
|
||||
int32_t code = sdbDeleteRow(&row);
|
||||
|
||||
sdbDecRef(tsMnodeSdb, pMnode);
|
||||
|
||||
|
@ -469,7 +465,7 @@ static int32_t mnodeRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, vo
|
|||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
char* roles = mnodeGetMnodeRoleStr(pMnode->role);
|
||||
char* roles = syncRole[pMnode->role];
|
||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, roles, pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ void mnodeAddPeerRspHandle(uint8_t msgType, void (*fp)(SRpcMsg *rpcMsg)) {
|
|||
|
||||
int32_t mnodeProcessPeerReq(SMnodeMsg *pMsg) {
|
||||
if (pMsg->rpcMsg.pCont == NULL) {
|
||||
mError("%p, msg:%s in mpeer queue, content is null", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]);
|
||||
mError("msg:%p, ahandle:%p type:%s in mpeer queue, content is null", pMsg, pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]);
|
||||
return TSDB_CODE_MND_INVALID_MSG_LEN;
|
||||
}
|
||||
|
||||
|
@ -58,8 +58,8 @@ int32_t mnodeProcessPeerReq(SMnodeMsg *pMsg) {
|
|||
rpcRsp->rsp = epSet;
|
||||
rpcRsp->len = sizeof(SRpcEpSet);
|
||||
|
||||
mDebug("%p, msg:%s in mpeer queue will be redirected, numOfEps:%d inUse:%d", pMsg->rpcMsg.ahandle,
|
||||
taosMsg[pMsg->rpcMsg.msgType], epSet->numOfEps, epSet->inUse);
|
||||
mDebug("msg:%p, ahandle:%p type:%s in mpeer queue will be redirected, numOfEps:%d inUse:%d", pMsg,
|
||||
pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType], epSet->numOfEps, epSet->inUse);
|
||||
for (int32_t i = 0; i < epSet->numOfEps; ++i) {
|
||||
if (strcmp(epSet->fqdn[i], tsLocalFqdn) == 0 && htons(epSet->port[i]) == tsServerPort + TSDB_PORT_DNODEDNODE) {
|
||||
epSet->inUse = (i + 1) % epSet->numOfEps;
|
||||
|
@ -73,7 +73,8 @@ int32_t mnodeProcessPeerReq(SMnodeMsg *pMsg) {
|
|||
}
|
||||
|
||||
if (tsMnodeProcessPeerMsgFp[pMsg->rpcMsg.msgType] == NULL) {
|
||||
mError("%p, msg:%s in mpeer queue, not processed", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]);
|
||||
mError("msg:%p, ahandle:%p type:%s in mpeer queue, not processed", pMsg, pMsg->rpcMsg.ahandle,
|
||||
taosMsg[pMsg->rpcMsg.msgType]);
|
||||
return TSDB_CODE_MND_MSG_NOT_PROCESSED;
|
||||
}
|
||||
|
||||
|
@ -82,13 +83,14 @@ int32_t mnodeProcessPeerReq(SMnodeMsg *pMsg) {
|
|||
|
||||
void mnodeProcessPeerRsp(SRpcMsg *pMsg) {
|
||||
if (!sdbIsMaster()) {
|
||||
mError("%p, msg:%s is not processed for it is not master", pMsg->ahandle, taosMsg[pMsg->msgType]);
|
||||
mError("msg:%p, ahandle:%p type:%s is not processed for it is not master", pMsg, pMsg->ahandle,
|
||||
taosMsg[pMsg->msgType]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tsMnodeProcessPeerRspFp[pMsg->msgType]) {
|
||||
(*tsMnodeProcessPeerRspFp[pMsg->msgType])(pMsg);
|
||||
} else {
|
||||
mError("%p, msg:%s is not processed", pMsg->ahandle, taosMsg[pMsg->msgType]);
|
||||
mError("msg:%p, ahandle:%p type:%s is not processed", pMsg, pMsg->ahandle, taosMsg[pMsg->msgType]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ void mnodeAddReadMsgHandle(uint8_t msgType, int32_t (*fp)(SMnodeMsg *pMsg)) {
|
|||
|
||||
int32_t mnodeProcessRead(SMnodeMsg *pMsg) {
|
||||
if (pMsg->rpcMsg.pCont == NULL) {
|
||||
mError("%p, msg:%s in mread queue, content is null", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]);
|
||||
mError("msg:%p, app:%p type:%s in mread queue, content is null", pMsg, pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]);
|
||||
return TSDB_CODE_MND_INVALID_MSG_LEN;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ int32_t mnodeProcessRead(SMnodeMsg *pMsg) {
|
|||
SRpcEpSet *epSet = rpcMallocCont(sizeof(SRpcEpSet));
|
||||
mnodeGetMnodeEpSetForShell(epSet);
|
||||
|
||||
mDebug("%p, msg:%s in mread queue will be redirected, numOfEps:%d inUse:%d", pMsg->rpcMsg.ahandle,
|
||||
mDebug("msg:%p, app:%p type:%s in mread queue will be redirected, numOfEps:%d inUse:%d", pMsg, pMsg->rpcMsg.ahandle,
|
||||
taosMsg[pMsg->rpcMsg.msgType], epSet->numOfEps, epSet->inUse);
|
||||
for (int32_t i = 0; i < epSet->numOfEps; ++i) {
|
||||
if (strcmp(epSet->fqdn[i], tsLocalFqdn) == 0 && htons(epSet->port[i]) == tsServerPort) {
|
||||
|
@ -70,13 +70,15 @@ int32_t mnodeProcessRead(SMnodeMsg *pMsg) {
|
|||
}
|
||||
|
||||
if (tsMnodeProcessReadMsgFp[pMsg->rpcMsg.msgType] == NULL) {
|
||||
mError("%p, msg:%s in mread queue, not processed", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]);
|
||||
mError("msg:%p, app:%p type:%s in mread queue, not processed", pMsg, pMsg->rpcMsg.ahandle,
|
||||
taosMsg[pMsg->rpcMsg.msgType]);
|
||||
return TSDB_CODE_MND_MSG_NOT_PROCESSED;
|
||||
}
|
||||
|
||||
int32_t code = mnodeInitMsg(pMsg);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
mError("%p, msg:%s in mread queue, not processed reason:%s", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType], tstrerror(code));
|
||||
mError("msg:%p, app:%p type:%s in mread queue, not processed reason:%s", pMsg, pMsg->rpcMsg.ahandle,
|
||||
taosMsg[pMsg->rpcMsg.msgType], tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -42,13 +42,13 @@ static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg);
|
|||
static int32_t mnodeProcessDropUserMsg(SMnodeMsg *pMsg);
|
||||
static int32_t mnodeProcessAuthMsg(SMnodeMsg *pMsg);
|
||||
|
||||
static int32_t mnodeUserActionDestroy(SSdbOper *pOper) {
|
||||
tfree(pOper->pObj);
|
||||
static int32_t mnodeUserActionDestroy(SSdbRow *pRow) {
|
||||
tfree(pRow->pObj);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeUserActionInsert(SSdbOper *pOper) {
|
||||
SUserObj *pUser = pOper->pObj;
|
||||
static int32_t mnodeUserActionInsert(SSdbRow *pRow) {
|
||||
SUserObj *pUser = pRow->pObj;
|
||||
SAcctObj *pAcct = mnodeGetAcct(pUser->acct);
|
||||
|
||||
if (pAcct != NULL) {
|
||||
|
@ -62,8 +62,8 @@ static int32_t mnodeUserActionInsert(SSdbOper *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeUserActionDelete(SSdbOper *pOper) {
|
||||
SUserObj *pUser = pOper->pObj;
|
||||
static int32_t mnodeUserActionDelete(SSdbRow *pRow) {
|
||||
SUserObj *pUser = pRow->pObj;
|
||||
SAcctObj *pAcct = mnodeGetAcct(pUser->acct);
|
||||
|
||||
if (pAcct != NULL) {
|
||||
|
@ -74,8 +74,8 @@ static int32_t mnodeUserActionDelete(SSdbOper *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeUserActionUpdate(SSdbOper *pOper) {
|
||||
SUserObj *pUser = pOper->pObj;
|
||||
static int32_t mnodeUserActionUpdate(SSdbRow *pRow) {
|
||||
SUserObj *pUser = pRow->pObj;
|
||||
SUserObj *pSaved = mnodeGetUser(pUser->user);
|
||||
if (pUser != pSaved) {
|
||||
memcpy(pSaved, pUser, tsUserUpdateSize);
|
||||
|
@ -85,19 +85,19 @@ static int32_t mnodeUserActionUpdate(SSdbOper *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeUserActionEncode(SSdbOper *pOper) {
|
||||
SUserObj *pUser = pOper->pObj;
|
||||
memcpy(pOper->rowData, pUser, tsUserUpdateSize);
|
||||
pOper->rowSize = tsUserUpdateSize;
|
||||
static int32_t mnodeUserActionEncode(SSdbRow *pRow) {
|
||||
SUserObj *pUser = pRow->pObj;
|
||||
memcpy(pRow->rowData, pUser, tsUserUpdateSize);
|
||||
pRow->rowSize = tsUserUpdateSize;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeUserActionDecode(SSdbOper *pOper) {
|
||||
static int32_t mnodeUserActionDecode(SSdbRow *pRow) {
|
||||
SUserObj *pUser = (SUserObj *)calloc(1, sizeof(SUserObj));
|
||||
if (pUser == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(pUser, pOper->rowData, tsUserUpdateSize);
|
||||
pOper->pObj = pUser;
|
||||
memcpy(pUser, pRow->rowData, tsUserUpdateSize);
|
||||
pRow->pObj = pUser;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -150,25 +150,25 @@ int32_t mnodeInitUsers() {
|
|||
SUserObj tObj;
|
||||
tsUserUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
|
||||
|
||||
SSdbTableDesc tableDesc = {
|
||||
.tableId = SDB_TABLE_USER,
|
||||
.tableName = "users",
|
||||
SSdbTableDesc desc = {
|
||||
.id = SDB_TABLE_USER,
|
||||
.name = "users",
|
||||
.hashSessions = TSDB_DEFAULT_USERS_HASH_SIZE,
|
||||
.maxRowSize = tsUserUpdateSize,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_STRING,
|
||||
.insertFp = mnodeUserActionInsert,
|
||||
.deleteFp = mnodeUserActionDelete,
|
||||
.updateFp = mnodeUserActionUpdate,
|
||||
.encodeFp = mnodeUserActionEncode,
|
||||
.decodeFp = mnodeUserActionDecode,
|
||||
.destroyFp = mnodeUserActionDestroy,
|
||||
.restoredFp = mnodeUserActionRestored
|
||||
.fpInsert = mnodeUserActionInsert,
|
||||
.fpDelete = mnodeUserActionDelete,
|
||||
.fpUpdate = mnodeUserActionUpdate,
|
||||
.fpEncode = mnodeUserActionEncode,
|
||||
.fpDecode = mnodeUserActionDecode,
|
||||
.fpDestroy = mnodeUserActionDestroy,
|
||||
.fpRestored = mnodeUserActionRestored
|
||||
};
|
||||
|
||||
tsUserSdb = sdbOpenTable(&tableDesc);
|
||||
tsUserSdb = sdbOpenTable(&desc);
|
||||
if (tsUserSdb == NULL) {
|
||||
mError("table:%s, failed to create hash", tableDesc.tableName);
|
||||
mError("table:%s, failed to create hash", desc.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ int32_t mnodeInitUsers() {
|
|||
mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_USER, mnodeRetrieveUsers);
|
||||
mnodeAddPeerMsgHandle(TSDB_MSG_TYPE_DM_AUTH, mnodeProcessAuthMsg);
|
||||
|
||||
mDebug("table:%s, hash is created", tableDesc.tableName);
|
||||
mDebug("table:%s, hash is created", desc.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -205,14 +205,14 @@ void mnodeDecUserRef(SUserObj *pUser) {
|
|||
}
|
||||
|
||||
static int32_t mnodeUpdateUser(SUserObj *pUser, void *pMsg) {
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsUserSdb,
|
||||
.pObj = pUser,
|
||||
.pMsg = pMsg
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsUserSdb,
|
||||
.pObj = pUser,
|
||||
.pMsg = pMsg
|
||||
};
|
||||
|
||||
int32_t code = sdbUpdateRow(&oper);
|
||||
int32_t code = sdbUpdateRow(&row);
|
||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
mError("user:%s, failed to alter by %s, reason:%s", pUser->user, mnodeGetUserFromMsg(pMsg), tstrerror(code));
|
||||
} else {
|
||||
|
@ -259,15 +259,15 @@ int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg) {
|
|||
pUser->superAuth = 1;
|
||||
}
|
||||
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsUserSdb,
|
||||
.pObj = pUser,
|
||||
.rowSize = sizeof(SUserObj),
|
||||
.pMsg = pMsg
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsUserSdb,
|
||||
.pObj = pUser,
|
||||
.rowSize = sizeof(SUserObj),
|
||||
.pMsg = pMsg
|
||||
};
|
||||
|
||||
code = sdbInsertRow(&oper);
|
||||
code = sdbInsertRow(&row);
|
||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
mError("user:%s, failed to create by %s, reason:%s", pUser->user, mnodeGetUserFromMsg(pMsg), tstrerror(code));
|
||||
tfree(pUser);
|
||||
|
@ -279,14 +279,14 @@ int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg) {
|
|||
}
|
||||
|
||||
static int32_t mnodeDropUser(SUserObj *pUser, void *pMsg) {
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsUserSdb,
|
||||
.pObj = pUser,
|
||||
.pMsg = pMsg
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsUserSdb,
|
||||
.pObj = pUser,
|
||||
.pMsg = pMsg
|
||||
};
|
||||
|
||||
int32_t code = sdbDeleteRow(&oper);
|
||||
int32_t code = sdbDeleteRow(&row);
|
||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
mError("user:%s, failed to drop by %s, reason:%s", pUser->user, mnodeGetUserFromMsg(pMsg), tstrerror(code));
|
||||
} else {
|
||||
|
@ -562,12 +562,12 @@ void mnodeDropAllUsers(SAcctObj *pAcct) {
|
|||
if (pUser == NULL) break;
|
||||
|
||||
if (strncmp(pUser->acct, pAcct->user, acctNameLen) == 0) {
|
||||
SSdbOper oper = {
|
||||
.type = SDB_OPER_LOCAL,
|
||||
.table = tsUserSdb,
|
||||
.pObj = pUser,
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_LOCAL,
|
||||
.pTable = tsUserSdb,
|
||||
.pObj = pUser,
|
||||
};
|
||||
sdbDeleteRow(&oper);
|
||||
sdbDeleteRow(&row);
|
||||
numOfUsers++;
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue