Merge branch '3.0' into catalog_dev
This commit is contained in:
commit
3bca16804b
|
@ -12,6 +12,7 @@ debug/
|
|||
release/
|
||||
target/
|
||||
debs/
|
||||
deps/
|
||||
rpms/
|
||||
mac/
|
||||
*.pyc
|
||||
|
@ -100,4 +101,4 @@ TAGS
|
|||
|
||||
contrib/*
|
||||
!contrib/CMakeLists.txt
|
||||
!contrib/test
|
||||
!contrib/test
|
|
@ -10,7 +10,7 @@ set(CMAKE_SUPPORT_DIR "${CMAKE_SOURCE_DIR}/cmake")
|
|||
set(CMAKE_CONTRIB_DIR "${CMAKE_SOURCE_DIR}/contrib")
|
||||
include(${CMAKE_SUPPORT_DIR}/cmake.options)
|
||||
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -gdwarf-2 -msse4.2 -mfma")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -gdwarf-2 -msse4.2 -mfma -g3")
|
||||
|
||||
# contrib
|
||||
add_subdirectory(contrib)
|
||||
|
@ -20,9 +20,13 @@ add_library(api INTERFACE)
|
|||
target_include_directories(api INTERFACE "include/client")
|
||||
|
||||
# src
|
||||
if(${BUILD_TEST})
|
||||
include(CTest)
|
||||
enable_testing()
|
||||
endif(${BUILD_TEST})
|
||||
add_subdirectory(source)
|
||||
|
||||
# docs
|
||||
add_subdirectory(docs)
|
||||
|
||||
# tests (TODO)
|
||||
# tests (TODO)
|
|
@ -73,10 +73,12 @@ typedef struct taosField {
|
|||
#define DLL_EXPORT
|
||||
#endif
|
||||
|
||||
DLL_EXPORT int taos_init();
|
||||
typedef void (*__taos_async_fn_t)(void *param, TAOS_RES *, int code);
|
||||
|
||||
DLL_EXPORT void taos_cleanup(void);
|
||||
DLL_EXPORT int taos_options(TSDB_OPTION option, const void *arg, ...);
|
||||
DLL_EXPORT TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);
|
||||
DLL_EXPORT TAOS *taos_connect_l(const char *ip, int ipLen, const char *user, int userLen, const char *pass, int passLen, const char *db, int dbLen, uint16_t port);
|
||||
DLL_EXPORT TAOS *taos_connect_auth(const char *ip, const char *user, const char *auth, const char *db, uint16_t port);
|
||||
DLL_EXPORT void taos_close(TAOS *taos);
|
||||
|
||||
|
@ -154,14 +156,14 @@ DLL_EXPORT int* taos_fetch_lengths(TAOS_RES *res);
|
|||
// TAOS_RES *taos_list_dbs(TAOS *mysql, const char *wild);
|
||||
|
||||
// TODO: the return value should be `const`
|
||||
DLL_EXPORT char *taos_get_server_info(TAOS *taos);
|
||||
DLL_EXPORT char *taos_get_client_info();
|
||||
DLL_EXPORT char *taos_errstr(TAOS_RES *tres);
|
||||
DLL_EXPORT const char *taos_get_server_info(TAOS *taos);
|
||||
DLL_EXPORT const char *taos_get_client_info();
|
||||
DLL_EXPORT const char *taos_errstr(TAOS_RES *tres);
|
||||
|
||||
DLL_EXPORT int taos_errno(TAOS_RES *tres);
|
||||
|
||||
DLL_EXPORT void taos_query_a(TAOS *taos, const char *sql, void (*fp)(void *param, TAOS_RES *, int code), void *param);
|
||||
DLL_EXPORT void taos_fetch_rows_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, int numOfRows), void *param);
|
||||
DLL_EXPORT void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param);
|
||||
DLL_EXPORT void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param);
|
||||
|
||||
typedef void (*TAOS_SUBSCRIBE_CALLBACK)(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code);
|
||||
DLL_EXPORT TAOS_SUB *taos_subscribe(TAOS* taos, int restart, const char* topic, const char *sql, TAOS_SUBSCRIBE_CALLBACK fp, void *param, int interval);
|
||||
|
|
|
@ -74,9 +74,9 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_COMPACT_DB, "compact-db" )
|
|||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CREATE_FUNCTION, "create-function" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_RETRIEVE_FUNCTION, "retrieve-function" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DROP_FUNCTION, "drop-function" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CREATE_STABLE, "create-stable" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_ALTER_STABLE, "alter-stable" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DROP_STABLE, "drop-stable" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CREATE_STB, "create-stb" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_ALTER_STB, "alter-stb" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DROP_STB, "drop-stb" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_VGROUP_LIST, "vgroup-list" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_KILL_QUERY, "kill-query" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_KILL_STREAM, "kill-stream" )
|
||||
|
@ -94,9 +94,9 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_NETWORK_TEST, "nettest" )
|
|||
// message from vnode to dnode
|
||||
|
||||
// message from mnode to vnode
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CREATE_STABLE_IN, "create-stable" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_ALTER_STABLE_IN, "alter-stable" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DROP_STABLE_IN, "drop-stable" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CREATE_STB_IN, "create-stb-in" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_ALTER_STB_IN, "alter-stb-in" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DROP_STB_IN, "drop-stb-in" )
|
||||
// message from mnode to mnode
|
||||
// message from mnode to qnode
|
||||
// message from mnode to dnode
|
||||
|
@ -159,7 +159,7 @@ typedef enum _mgmt_table {
|
|||
TSDB_MGMT_TABLE_DNODE,
|
||||
TSDB_MGMT_TABLE_MNODE,
|
||||
TSDB_MGMT_TABLE_VGROUP,
|
||||
TSDB_MGMT_TABLE_STABLE,
|
||||
TSDB_MGMT_TABLE_STB,
|
||||
TSDB_MGMT_TABLE_MODULE,
|
||||
TSDB_MGMT_TABLE_QUERIES,
|
||||
TSDB_MGMT_TABLE_STREAMS,
|
||||
|
@ -299,7 +299,7 @@ typedef struct {
|
|||
uint64_t superTableUid;
|
||||
uint64_t createdTime;
|
||||
char tableFname[TSDB_TABLE_FNAME_LEN];
|
||||
char stableFname[TSDB_TABLE_FNAME_LEN];
|
||||
char stbFname[TSDB_TABLE_FNAME_LEN];
|
||||
char data[];
|
||||
} SMDCreateTableMsg;
|
||||
|
||||
|
@ -316,16 +316,23 @@ typedef struct {
|
|||
} SCreateTableMsg;
|
||||
|
||||
typedef struct {
|
||||
int32_t numOfTables;
|
||||
int32_t contLen;
|
||||
} SCMCreateTableMsg;
|
||||
char name[TSDB_TABLE_FNAME_LEN];
|
||||
int8_t igExists;
|
||||
int32_t numOfTags;
|
||||
int32_t numOfColumns;
|
||||
SSchema pSchema[];
|
||||
} SCreateStbMsg;
|
||||
|
||||
typedef struct {
|
||||
char name[TSDB_TABLE_FNAME_LEN];
|
||||
// if user specify DROP STABLE, this flag will be set. And an error will be returned if it is not a super table
|
||||
int8_t supertable;
|
||||
int8_t igNotExists;
|
||||
} SCMDropTableMsg;
|
||||
} SDropStbMsg;
|
||||
|
||||
typedef struct {
|
||||
char name[TSDB_TABLE_FNAME_LEN];
|
||||
int8_t alterType;
|
||||
SSchema schema;
|
||||
} SAlterStbMsg;
|
||||
|
||||
typedef struct {
|
||||
char tableFname[TSDB_TABLE_FNAME_LEN];
|
||||
|
@ -356,6 +363,7 @@ typedef struct {
|
|||
int32_t pid;
|
||||
char app[TSDB_APP_NAME_LEN];
|
||||
char db[TSDB_DB_NAME_LEN];
|
||||
int64_t startTime;
|
||||
} SConnectMsg;
|
||||
|
||||
typedef struct SEpSet {
|
||||
|
@ -366,19 +374,17 @@ typedef struct SEpSet {
|
|||
} SEpSet;
|
||||
|
||||
typedef struct {
|
||||
int32_t acctId;
|
||||
int32_t clusterId;
|
||||
int32_t connId;
|
||||
int8_t superAuth;
|
||||
int8_t readAuth;
|
||||
int8_t writeAuth;
|
||||
int8_t reserved[5];
|
||||
SEpSet epSet;
|
||||
int32_t acctId;
|
||||
uint32_t clusterId;
|
||||
int32_t connId;
|
||||
int8_t superUser;
|
||||
int8_t reserved[5];
|
||||
SEpSet epSet;
|
||||
} SConnectRsp;
|
||||
|
||||
typedef struct {
|
||||
char user[TSDB_USER_LEN];
|
||||
char pass[TSDB_KEY_LEN];
|
||||
char pass[TSDB_PASSWORD_LEN];
|
||||
int32_t maxUsers;
|
||||
int32_t maxDbs;
|
||||
int32_t maxTimeSeries;
|
||||
|
@ -393,7 +399,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
char user[TSDB_USER_LEN];
|
||||
char pass[TSDB_KEY_LEN];
|
||||
char pass[TSDB_PASSWORD_LEN];
|
||||
} SCreateUserMsg, SAlterUserMsg;
|
||||
|
||||
typedef struct {
|
||||
|
@ -668,7 +674,6 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
int32_t statusInterval;
|
||||
int32_t mnodeEqualVnodeNum;
|
||||
int64_t checkTime; // 1970-01-01 00:00:00.000
|
||||
char timezone[TSDB_TIMEZONE_LEN]; // tsTimezone
|
||||
char locale[TSDB_LOCALE_LEN]; // tsLocale
|
||||
|
@ -694,7 +699,7 @@ typedef struct SStatusMsg {
|
|||
int32_t sver;
|
||||
int32_t dnodeId;
|
||||
int32_t clusterId;
|
||||
uint32_t rebootTime; // time stamp for last reboot
|
||||
int64_t rebootTime; // time stamp for last reboot
|
||||
int16_t numOfCores;
|
||||
int16_t numOfSupportMnodes;
|
||||
int16_t numOfSupportVnodes;
|
||||
|
@ -770,7 +775,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
char name[TSDB_TABLE_FNAME_LEN];
|
||||
} SStableInfoMsg;
|
||||
} SStbInfoMsg;
|
||||
|
||||
typedef struct {
|
||||
SMsgHead msgHead;
|
||||
|
@ -815,8 +820,8 @@ typedef struct {
|
|||
} SVgroupsMsg, SVgroupsInfo;
|
||||
|
||||
typedef struct {
|
||||
char tableFname[TSDB_TABLE_FNAME_LEN]; // table id
|
||||
char stableFname[TSDB_TABLE_FNAME_LEN];
|
||||
char tbFname[TSDB_TABLE_FNAME_LEN]; // table id
|
||||
char stbFname[TSDB_TABLE_FNAME_LEN];
|
||||
int32_t numOfTags;
|
||||
int32_t numOfColumns;
|
||||
int8_t precision;
|
||||
|
@ -880,7 +885,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
int32_t dnodeId;
|
||||
char config[128];
|
||||
char config[TSDB_DNODE_CONFIG_LEN];
|
||||
} SCfgDnodeMsg;
|
||||
|
||||
typedef struct {
|
||||
|
@ -973,8 +978,8 @@ typedef struct {
|
|||
char user[TSDB_USER_LEN];
|
||||
char spi;
|
||||
char encrypt;
|
||||
char secret[TSDB_KEY_LEN];
|
||||
char ckey[TSDB_KEY_LEN];
|
||||
char secret[TSDB_PASSWORD_LEN];
|
||||
char ckey[TSDB_PASSWORD_LEN];
|
||||
} SAuthMsg, SAuthRsp;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -544,7 +544,7 @@ void tdDestroyKVRowBuilder(SKVRowBuilder *pBuilder);
|
|||
void tdResetKVRowBuilder(SKVRowBuilder *pBuilder);
|
||||
SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder);
|
||||
|
||||
static FORCE_INLINE int tdAddColToKVRow(SKVRowBuilder *pBuilder, int16_t colId, int8_t type, void *value) {
|
||||
static FORCE_INLINE int tdAddColToKVRow(SKVRowBuilder *pBuilder, int16_t colId, int8_t type, const void *value) {
|
||||
if (pBuilder->nCols >= pBuilder->tCols) {
|
||||
pBuilder->tCols *= 2;
|
||||
SColIdx* pColIdx = (SColIdx *)realloc((void *)(pBuilder->pColIdx), sizeof(SColIdx) * pBuilder->tCols);
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef TDENGINE_TEP_H
|
||||
#define TDENGINE_TEP_H
|
||||
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
|
||||
typedef struct SCorEpSet {
|
||||
int32_t version;
|
||||
SEpSet epSet;
|
||||
} SCorEpSet;
|
||||
|
||||
int taosGetFqdnPortFromEp(const char *ep, char *fqdn, uint16_t *port);
|
||||
bool isEpsetEqual(const SEpSet *s1, const SEpSet *s2);
|
||||
|
||||
void updateEpSet_s(SCorEpSet *pEpSet, SEpSet *pNewEpSet);
|
||||
|
||||
#endif // TDENGINE_TEP_H
|
|
@ -81,8 +81,6 @@ extern int64_t tsMaxRetentWindow;
|
|||
// db parameters in client
|
||||
extern int32_t tsCacheBlockSize;
|
||||
extern int32_t tsBlocksPerVnode;
|
||||
extern int32_t tsMinTablePerVnode;
|
||||
extern int32_t tsMaxTablePerVnode;
|
||||
extern int32_t tsTableIncStepPerVnode;
|
||||
extern int32_t tsMaxVgroupsPerDb;
|
||||
extern int16_t tsDaysPerFile;
|
||||
|
@ -108,22 +106,13 @@ extern int8_t tsEnableBalance;
|
|||
extern int8_t tsAlternativeRole;
|
||||
extern int32_t tsBalanceInterval;
|
||||
extern int32_t tsOfflineThreshold;
|
||||
extern int32_t tsMnodeEqualVnodeNum;
|
||||
extern int8_t tsEnableFlowCtrl;
|
||||
extern int8_t tsEnableSlaveQuery;
|
||||
extern int8_t tsEnableAdjustMaster;
|
||||
|
||||
// restful
|
||||
extern int8_t tsEnableHttpModule;
|
||||
extern int32_t tsRestRowLimit;
|
||||
extern uint16_t tsHttpPort;
|
||||
extern int32_t tsHttpCacheSessions;
|
||||
extern int32_t tsHttpSessionExpire;
|
||||
extern int32_t tsHttpMaxThreads;
|
||||
extern int8_t tsHttpEnableCompress;
|
||||
extern int8_t tsHttpEnableRecordSql;
|
||||
extern int8_t tsTelegrafUseFieldNum;
|
||||
extern int8_t tsHttpDbNameMandatory;
|
||||
|
||||
// mqtt
|
||||
extern int8_t tsEnableMqttModule;
|
||||
|
@ -145,7 +134,6 @@ extern int8_t tsEnableStream;
|
|||
|
||||
// internal
|
||||
extern int8_t tsPrintAuth;
|
||||
extern int8_t tscEmbedded;
|
||||
extern char tsVnodeDir[];
|
||||
extern char tsMnodeDir[];
|
||||
extern int64_t tsTickPerDay[3];
|
||||
|
@ -194,7 +182,7 @@ extern SDiskCfg tsDiskCfg[];
|
|||
#define NEEDTO_COMPRESSS_MSG(size) (tsCompressMsgSize != -1 && (size) > tsCompressMsgSize)
|
||||
|
||||
void taosInitGlobalCfg();
|
||||
int32_t taosCheckGlobalCfg();
|
||||
int32_t taosCheckAndPrintCfg();
|
||||
int32_t taosCfgDynamicOptions(char *msg);
|
||||
bool taosCheckBalanceCfgOptions(const char *option, int32_t *vnodeId, int32_t *dnodeId);
|
||||
void taosAddDataDir(int index, char *v1, int level, int primary);
|
||||
|
|
|
@ -44,10 +44,10 @@ int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision);
|
|||
int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precision);
|
||||
int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char unit, int32_t precision);
|
||||
|
||||
int32_t parseAbsoluteDuration(char* token, int32_t tokenlen, int64_t* ts, char* unit, int32_t timePrecision);
|
||||
int32_t parseAbsoluteDuration(const char* token, int32_t tokenlen, int64_t* ts, char* unit, int32_t timePrecision);
|
||||
int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* duration, char* unit, int32_t timePrecision);
|
||||
|
||||
int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t dayligth);
|
||||
int32_t taosParseTime(const char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t dayligth);
|
||||
void deltaToUtcInitOnce();
|
||||
|
||||
int64_t convertTimePrecision(int64_t time, int32_t fromPrecision, int32_t toPrecision);
|
||||
|
|
|
@ -40,7 +40,7 @@ int32_t toInteger(const char* z, int32_t n, int32_t base, int64_t* value, bool*
|
|||
|
||||
bool taosVariantIsValid(SVariant *pVar);
|
||||
|
||||
void taosVariantCreate(SVariant *pVar, char* z, int32_t n, int32_t type);
|
||||
void taosVariantCreate(SVariant *pVar, const char* z, int32_t n, int32_t type);
|
||||
|
||||
void taosVariantCreateFromBinary(SVariant *pVar, const char *pz, size_t len, uint32_t type);
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ typedef struct {
|
|||
int16_t numOfSupportQnodes;
|
||||
int8_t enableTelem;
|
||||
int32_t statusInterval;
|
||||
int32_t mnodeEqualVnodeNum;
|
||||
float numOfThreadsPerCore;
|
||||
float ratioOfQueryCores;
|
||||
int32_t maxShellConns;
|
||||
|
|
|
@ -47,7 +47,6 @@ typedef struct SMnodeCfg {
|
|||
int32_t sver;
|
||||
int8_t enableTelem;
|
||||
int32_t statusInterval;
|
||||
int32_t mnodeEqualVnodeNum;
|
||||
int32_t shellActivityTimer;
|
||||
char *timezone;
|
||||
char *locale;
|
||||
|
|
|
@ -158,8 +158,8 @@ typedef enum {
|
|||
SDB_USER = 5,
|
||||
SDB_AUTH = 6,
|
||||
SDB_ACCT = 7,
|
||||
SDB_VGROUP = 9,
|
||||
SDB_STABLE = 9,
|
||||
SDB_VGROUP = 8,
|
||||
SDB_STB = 9,
|
||||
SDB_DB = 10,
|
||||
SDB_FUNC = 11,
|
||||
SDB_MAX = 12
|
||||
|
|
|
@ -256,7 +256,7 @@ typedef struct STQ {
|
|||
// the collection of group handle
|
||||
// the handle of kvstore
|
||||
char* path;
|
||||
STqCfg* tqConfig;
|
||||
STqCfg* tqConfig;
|
||||
TqLogReader* tqLogReader;
|
||||
TqMemRef tqMemRef;
|
||||
TqMetaStore* tqMeta;
|
||||
|
|
|
@ -36,6 +36,8 @@ typedef struct SVnodeCfg {
|
|||
struct {
|
||||
/** write buffer size */
|
||||
uint64_t wsize;
|
||||
uint64_t ssize;
|
||||
uint64_t lsize;
|
||||
/** use heap allocator or arena allocator */
|
||||
bool isHeapAllocator;
|
||||
};
|
||||
|
|
|
@ -44,12 +44,12 @@ typedef struct SCatalogReq {
|
|||
bool qNodeRequired; // valid qnode
|
||||
} SCatalogReq;
|
||||
|
||||
typedef struct SCatalogRsp {
|
||||
typedef struct SMetaData {
|
||||
SArray *pTableMeta; // STableMeta array
|
||||
SArray *pVgroupInfo; // SVgroupInfo list
|
||||
SArray *pUdfList; // udf info list
|
||||
SEpSet *pEpSet; // qnode epset list
|
||||
} SCatalogRsp;
|
||||
} SMetaData;
|
||||
|
||||
typedef struct STableComInfo {
|
||||
uint8_t numOfTags; // the number of tags in schema
|
||||
|
@ -135,7 +135,7 @@ int32_t catalogGetTableVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSe
|
|||
* @param pMetaData
|
||||
* @return
|
||||
*/
|
||||
int32_t catalogGetAllMeta(struct SCatalog* pCatalog, const SEpSet* pMgmtEps, const SCatalogReq* pReq, SCatalogRsp* pRsp);
|
||||
int32_t catalogGetAllMeta(struct SCatalog* pCatalog, const SEpSet* pMgmtEps, const SCatalogReq* pReq, SMetaData* pRsp);
|
||||
|
||||
|
||||
int32_t catalogGetQnodeList(struct SCatalog* pCatalog, const SEpSet* pMgmtEps, SEpSet* pQnodeEpSet);
|
||||
|
|
|
@ -131,6 +131,18 @@ struct SInsertStmtInfo;
|
|||
*/
|
||||
bool qIsInsertSql(const char* pStr, size_t length);
|
||||
|
||||
typedef struct SParseContext {
|
||||
const char* pSql; // sql string
|
||||
size_t sqlLen; // length of the sql string
|
||||
int64_t id; // operator id, generated by uuid generator
|
||||
const char* pDbname;
|
||||
const SEpSet* pEpSet;
|
||||
int8_t schemaAttached; // denote if submit block is built with table schema or not
|
||||
|
||||
char* pMsg; // extended error message if exists to help avoid the problem in sql statement.
|
||||
int32_t msgLen; // max length of the msg
|
||||
} SParseContext;
|
||||
|
||||
/**
|
||||
* Parse the sql statement and then return the SQueryStmtInfo as the result of bounded AST.
|
||||
* @param pSql sql string
|
||||
|
@ -141,16 +153,35 @@ bool qIsInsertSql(const char* pStr, size_t length);
|
|||
*/
|
||||
int32_t qParseQuerySql(const char* pStr, size_t length, struct SQueryStmtInfo** pQueryInfo, int64_t id, char* msg, int32_t msgLen);
|
||||
|
||||
typedef enum {
|
||||
PAYLOAD_TYPE_KV = 0,
|
||||
PAYLOAD_TYPE_RAW = 1,
|
||||
} EPayloadType;
|
||||
|
||||
typedef struct SVgDataBlocks {
|
||||
int64_t vgId; // virtual group id
|
||||
int32_t numOfTables; // number of tables in current submit block
|
||||
uint32_t size;
|
||||
char *pData; // SMsgDesc + SSubmitMsg + SSubmitBlk + ...
|
||||
} SVgDataBlocks;
|
||||
|
||||
typedef struct SInsertStmtInfo {
|
||||
SArray* pDataBlocks; // data block for each vgroup, SArray<SVgDataBlocks*>.
|
||||
int8_t schemaAttache; // denote if submit block is built with table schema or not
|
||||
uint8_t payloadType; // EPayloadType. 0: K-V payload for non-prepare insert, 1: rawPayload for prepare insert
|
||||
uint32_t insertType; // insert data from [file|sql statement| bound statement]
|
||||
const char* sql; // current sql statement position
|
||||
} SInsertStmtInfo;
|
||||
|
||||
/**
|
||||
* Parse the insert sql statement.
|
||||
* @param pStr sql string
|
||||
* @param length length of the sql string
|
||||
* @param pInsertParam data in binary format to submit to vnode directly.
|
||||
* @param id operator id, generated by uuid generator.
|
||||
* @param msg extended error message if exists to help avoid the problem in sql statement.
|
||||
* @return
|
||||
* @return data in binary format to submit to vnode directly.
|
||||
*/
|
||||
int32_t qParseInsertSql(const char* pStr, size_t length, struct SInsertStmtInfo** pInsertInfo, int64_t id, char* msg, int32_t msgLen);
|
||||
int32_t qParseInsertSql(SParseContext* pContext, struct SInsertStmtInfo** pInfo);
|
||||
|
||||
/**
|
||||
* Convert a normal sql statement to only query tags information to enable that the subscribe client can be aware quickly of the true vgroup ids that
|
||||
|
|
|
@ -29,11 +29,6 @@ extern "C" {
|
|||
|
||||
extern int tsRpcHeadSize;
|
||||
|
||||
typedef struct SRpcCorEpSet {
|
||||
int32_t version;
|
||||
SEpSet epSet;
|
||||
} SRpcCorEpSet;
|
||||
|
||||
typedef struct SRpcConnInfo {
|
||||
uint32_t clientIp;
|
||||
uint16_t clientPort;
|
||||
|
|
|
@ -32,12 +32,49 @@ extern int32_t wDebugFlag;
|
|||
#define wDebug(...) { if (wDebugFlag & DEBUG_DEBUG) { taosPrintLog("WAL ", wDebugFlag, __VA_ARGS__); }}
|
||||
#define wTrace(...) { if (wDebugFlag & DEBUG_TRACE) { taosPrintLog("WAL ", wDebugFlag, __VA_ARGS__); }}
|
||||
|
||||
#define WAL_PREFIX "wal"
|
||||
#define WAL_PREFIX_LEN 3
|
||||
#define WAL_NOSUFFIX_LEN 20
|
||||
#define WAL_SUFFIX_AT (WAL_NOSUFFIX_LEN+1)
|
||||
#define WAL_LOG_SUFFIX "log"
|
||||
#define WAL_INDEX_SUFFIX "idx"
|
||||
#define WAL_REFRESH_MS 1000
|
||||
#define WAL_MAX_SIZE (TSDB_MAX_WAL_SIZE + sizeof(SWalHead) + 16)
|
||||
#define WAL_PATH_LEN (TSDB_FILENAME_LEN + 12)
|
||||
#define WAL_FILE_LEN (WAL_PATH_LEN + 32)
|
||||
|
||||
#define WAL_IDX_ENTRY_SIZE (sizeof(int64_t)*2)
|
||||
#define WAL_CUR_POS_WRITABLE 1
|
||||
#define WAL_CUR_FILE_WRITABLE 2
|
||||
#define WAL_CUR_FAILED 4
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef enum {
|
||||
TAOS_WAL_NOLOG = 0,
|
||||
TAOS_WAL_WRITE = 1,
|
||||
TAOS_WAL_FSYNC = 2
|
||||
} EWalType;
|
||||
|
||||
typedef struct SWalReadHead {
|
||||
int8_t sver;
|
||||
uint8_t msgType;
|
||||
int8_t reserved[2];
|
||||
int32_t len;
|
||||
//int64_t ingestTs; //not implemented
|
||||
int64_t version;
|
||||
char body[];
|
||||
} SWalReadHead;
|
||||
|
||||
typedef struct {
|
||||
int32_t vgId;
|
||||
int32_t fsyncPeriod; // millisecond
|
||||
int32_t retentionPeriod; // secs
|
||||
int32_t rollPeriod; // secs
|
||||
int64_t retentionSize;
|
||||
int64_t segSize;
|
||||
EWalType level; // wal level
|
||||
} SWalCfg;
|
||||
|
||||
typedef struct {
|
||||
//union {
|
||||
//uint32_t info;
|
||||
|
@ -47,87 +84,53 @@ typedef struct {
|
|||
//uint32_t reserved : 24;
|
||||
//};
|
||||
//};
|
||||
int8_t sver;
|
||||
uint8_t msgType;
|
||||
int8_t reserved[2];
|
||||
int32_t len;
|
||||
int64_t version;
|
||||
uint32_t signature;
|
||||
uint32_t cksumHead;
|
||||
uint32_t cksumBody;
|
||||
char cont[];
|
||||
SWalReadHead head;
|
||||
} SWalHead;
|
||||
|
||||
typedef struct {
|
||||
int32_t vgId;
|
||||
int32_t fsyncPeriod; // millisecond
|
||||
int32_t rollPeriod;
|
||||
int64_t segSize;
|
||||
EWalType walLevel; // wal level
|
||||
} SWalCfg;
|
||||
|
||||
#define WAL_PREFIX "wal"
|
||||
#define WAL_PREFIX_LEN 3
|
||||
#define WAL_NOSUFFIX_LEN 20
|
||||
#define WAL_SUFFIX_AT (WAL_NOSUFFIX_LEN+1)
|
||||
#define WAL_LOG_SUFFIX "log"
|
||||
#define WAL_INDEX_SUFFIX "idx"
|
||||
#define WAL_REFRESH_MS 1000
|
||||
#define WAL_MAX_SIZE (TSDB_MAX_WAL_SIZE + sizeof(SWalHead) + 16)
|
||||
#define WAL_SIGNATURE ((uint32_t)(0xFAFBFDFEUL))
|
||||
#define WAL_PATH_LEN (TSDB_FILENAME_LEN + 12)
|
||||
#define WAL_FILE_LEN (WAL_PATH_LEN + 32)
|
||||
//#define WAL_FILE_NUM 1 // 3
|
||||
#define WAL_FILESET_MAX 128
|
||||
|
||||
#define WAL_IDX_ENTRY_SIZE (sizeof(int64_t)*2)
|
||||
#define WAL_CUR_POS_WRITABLE 1
|
||||
#define WAL_CUR_FILE_WRITABLE 2
|
||||
#define WAL_CUR_FAILED 4
|
||||
typedef struct SWalVer {
|
||||
int64_t firstVer;
|
||||
int64_t verInSnapshotting;
|
||||
int64_t snapshotVer;
|
||||
int64_t commitVer;
|
||||
int64_t lastVer;
|
||||
} SWalVer;
|
||||
|
||||
typedef struct SWal {
|
||||
// cfg
|
||||
int32_t vgId;
|
||||
int32_t fsyncPeriod; // millisecond
|
||||
int32_t rollPeriod; // second
|
||||
int64_t segSize;
|
||||
int64_t retentionSize;
|
||||
int32_t retentionPeriod;
|
||||
EWalType level;
|
||||
//total size
|
||||
int64_t totSize;
|
||||
//fsync seq
|
||||
int32_t fsyncSeq;
|
||||
//reference
|
||||
int64_t refId;
|
||||
//write tfd
|
||||
int64_t writeLogTfd;
|
||||
int64_t writeIdxTfd;
|
||||
//read tfd
|
||||
int64_t readLogTfd;
|
||||
int64_t readIdxTfd;
|
||||
//current version
|
||||
int64_t curVersion;
|
||||
//wal lifecycle
|
||||
int64_t firstVersion;
|
||||
int64_t snapshotVersion;
|
||||
int64_t commitVersion;
|
||||
int64_t lastVersion;
|
||||
//roll status
|
||||
int64_t lastRollSeq;
|
||||
SWalCfg cfg;
|
||||
SWalVer vers;
|
||||
//file set
|
||||
int32_t writeCur;
|
||||
int32_t readCur;
|
||||
int64_t writeLogTfd;
|
||||
int64_t writeIdxTfd;
|
||||
SArray* fileInfoSet;
|
||||
//ctl
|
||||
int32_t curStatus;
|
||||
int32_t fsyncSeq;
|
||||
int64_t totSize;
|
||||
int64_t refId;
|
||||
int64_t lastRollSeq;
|
||||
pthread_mutex_t mutex;
|
||||
//path
|
||||
char path[WAL_PATH_LEN];
|
||||
//reusable write head
|
||||
SWalHead head;
|
||||
SWalHead writeHead;
|
||||
} SWal; // WAL HANDLE
|
||||
|
||||
typedef struct SWalReadHandle {
|
||||
SWal* pWal;
|
||||
int64_t readLogTfd;
|
||||
int64_t readIdxTfd;
|
||||
int64_t curFileFirstVer;
|
||||
int64_t curVersion;
|
||||
int64_t capacity;
|
||||
int64_t status; //if cursor valid
|
||||
SWalHead* pHead;
|
||||
} SWalReadHandle;
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef int32_t (*FWalWrite)(void *ahandle, void *pHead);
|
||||
|
||||
// module initialization
|
||||
|
@ -148,10 +151,15 @@ int32_t walCommit(SWal *, int64_t ver);
|
|||
// truncate after
|
||||
int32_t walRollback(SWal *, int64_t ver);
|
||||
// notify that previous logs can be pruned safely
|
||||
int32_t walTakeSnapshot(SWal *, int64_t ver);
|
||||
int32_t walBeginTakeSnapshot(SWal *, int64_t ver);
|
||||
int32_t walEndTakeSnapshot(SWal *);
|
||||
//int32_t walDataCorrupted(SWal*);
|
||||
|
||||
// read
|
||||
SWalReadHandle* walOpenReadHandle(SWal *);
|
||||
void walCloseReadHandle(SWalReadHandle *);
|
||||
int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver);
|
||||
|
||||
int32_t walRead(SWal *, SWalHead **, int64_t ver);
|
||||
int32_t walReadWithFp(SWal *, FWalWrite writeFp, int64_t verStart, int32_t readNum);
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ int64_t taosGetPthreadId(pthread_t thread);
|
|||
void taosResetPthread(pthread_t* thread);
|
||||
bool taosComparePthread(pthread_t first, pthread_t second);
|
||||
int32_t taosGetPId();
|
||||
int32_t taosGetCurrentAPPName(char* name, int32_t* len);
|
||||
int32_t taosGetAppName(char* name, int32_t* len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -38,11 +38,11 @@ extern "C" {
|
|||
(dst)[(size)-1] = 0; \
|
||||
} while (0)
|
||||
|
||||
int64_t taosStr2int64(char *str);
|
||||
int64_t taosStr2int64(const char *str);
|
||||
|
||||
// USE_LIBICONV
|
||||
int32_t taosUcs4ToMbs(void *ucs4, int32_t ucs4_max_len, char *mbs);
|
||||
bool taosMbsToUcs4(char *mbs, size_t mbs_len, char *ucs4, int32_t ucs4_max_len, int32_t *len);
|
||||
bool taosMbsToUcs4(const char *mbs, size_t mbs_len, char *ucs4, int32_t ucs4_max_len, int32_t *len);
|
||||
int32_t tasoUcs4Compare(void *f1_ucs4, void *f2_ucs4, int32_t bytes, int8_t ncharSize);
|
||||
bool taosValidateEncodec(const char *encodec);
|
||||
char * taosCharsetReplace(char *charsetstr);
|
||||
|
|
|
@ -153,22 +153,23 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_SDB_INVALID_DATA_LEN TAOS_DEF_ERROR_CODE(0, 0x032A)
|
||||
#define TSDB_CODE_SDB_INVALID_DATA_CONTENT TAOS_DEF_ERROR_CODE(0, 0x032B)
|
||||
|
||||
#define TSDB_CODE_MND_DNODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0330) //"DNode already exists")
|
||||
#define TSDB_CODE_MND_DNODE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0331) //"DNode does not exist")
|
||||
// mnode-dnode
|
||||
#define TSDB_CODE_MND_DNODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0330)
|
||||
#define TSDB_CODE_MND_DNODE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0331)
|
||||
#define TSDB_CODE_MND_NO_ENOUGH_DNODES TAOS_DEF_ERROR_CODE(0, 0x0332)
|
||||
#define TSDB_CODE_MND_INVALID_CLUSTER_CFG TAOS_DEF_ERROR_CODE(0, 0x0333)
|
||||
#define TSDB_CODE_MND_INVALID_CLUSTER_ID TAOS_DEF_ERROR_CODE(0, 0x0334)
|
||||
#define TSDB_CODE_MND_INVALID_DNODE_CFG TAOS_DEF_ERROR_CODE(0, 0x0335)
|
||||
#define TSDB_CODE_MND_INVALID_DNODE_EP TAOS_DEF_ERROR_CODE(0, 0x0336)
|
||||
#define TSDB_CODE_MND_INVALID_DNODE_ID TAOS_DEF_ERROR_CODE(0, 0x0337)
|
||||
|
||||
// mnode-vgroup
|
||||
#define TSDB_CODE_MND_VGROUP_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0332) //"VGroup does not exist")
|
||||
#define TSDB_CODE_MND_NO_REMOVE_MASTER TAOS_DEF_ERROR_CODE(0, 0x0333) //"Master DNode cannot be removed")
|
||||
#define TSDB_CODE_MND_NO_ENOUGH_DNODES TAOS_DEF_ERROR_CODE(0, 0x0334) //"Out of DNodes")
|
||||
#define TSDB_CODE_MND_CLUSTER_CFG_INCONSISTENT TAOS_DEF_ERROR_CODE(0, 0x0335) //"Cluster cfg inconsistent")
|
||||
#define TSDB_CODE_MND_INVALID_DNODE_CFG_OPTION TAOS_DEF_ERROR_CODE(0, 0x0336) //"Invalid dnode cfg option")
|
||||
#define TSDB_CODE_MND_BALANCE_ENABLED TAOS_DEF_ERROR_CODE(0, 0x0337) //"Balance already enabled")
|
||||
#define TSDB_CODE_MND_VGROUP_NOT_IN_DNODE TAOS_DEF_ERROR_CODE(0, 0x0338) //"Vgroup not in dnode")
|
||||
#define TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE TAOS_DEF_ERROR_CODE(0, 0x0339) //"Vgroup already in dnode")
|
||||
#define TSDB_CODE_MND_DNODE_NOT_FREE TAOS_DEF_ERROR_CODE(0, 0x033A) //"Dnode not avaliable")
|
||||
#define TSDB_CODE_MND_INVALID_CLUSTER_ID TAOS_DEF_ERROR_CODE(0, 0x033B) //"Cluster id not match")
|
||||
#define TSDB_CODE_MND_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x033C) //"Cluster not ready")
|
||||
#define TSDB_CODE_MND_DNODE_ID_NOT_CONFIGURED TAOS_DEF_ERROR_CODE(0, 0x033D) //"Dnode Id not configured")
|
||||
#define TSDB_CODE_MND_DNODE_EP_NOT_CONFIGURED TAOS_DEF_ERROR_CODE(0, 0x033E) //"Dnode Ep not configured")
|
||||
|
||||
// mnode-acct
|
||||
#define TSDB_CODE_MND_ACCT_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0340) //"Account already exists")
|
||||
#define TSDB_CODE_MND_ACCT_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0341) //"Invalid account")
|
||||
#define TSDB_CODE_MND_INVALID_ACCT_OPTION TAOS_DEF_ERROR_CODE(0, 0x0342) //"Invalid account options")
|
||||
|
@ -184,8 +185,18 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_MND_MNODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0348) //"Mnode already exists")
|
||||
#define TSDB_CODE_MND_MNODE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0349) //"Mnode not there")
|
||||
|
||||
// mnode-table
|
||||
#define TSDB_CODE_MND_TABLE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0360) //"Table already exists")
|
||||
// mnode-stable
|
||||
#define TSDB_CODE_MND_STB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0360)
|
||||
#define TSDB_CODE_MND_STB_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0360)
|
||||
#define TSDB_CODE_MND_STB_INVALID_IGEXIST TAOS_DEF_ERROR_CODE(0, 0x0360)
|
||||
#define TSDB_CODE_MND_STB_INVALID_COLS_NUM TAOS_DEF_ERROR_CODE(0, 0x0360)
|
||||
#define TSDB_CODE_MND_STB_INVALID_TAGS_NUM TAOS_DEF_ERROR_CODE(0, 0x0360)
|
||||
#define TSDB_CODE_MND_STB_INVALID_COL_TYPE TAOS_DEF_ERROR_CODE(0, 0x0360)
|
||||
#define TSDB_CODE_MND_STB_INVALID_COL_ID TAOS_DEF_ERROR_CODE(0, 0x0360)
|
||||
#define TSDB_CODE_MND_STB_INVALID_COL_BYTES TAOS_DEF_ERROR_CODE(0, 0x0360)
|
||||
#define TSDB_CODE_MND_STB_INVALID_COL_NAME TAOS_DEF_ERROR_CODE(0, 0x0360)
|
||||
|
||||
|
||||
#define TSDB_CODE_MND_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0361) //"Table name too long")
|
||||
#define TSDB_CODE_MND_INVALID_TABLE_NAME TAOS_DEF_ERROR_CODE(0, 0x0362) //"Table does not exist")
|
||||
#define TSDB_CODE_MND_INVALID_TABLE_TYPE TAOS_DEF_ERROR_CODE(0, 0x0363) //"Invalid table type in tsdb")
|
||||
|
|
|
@ -43,6 +43,13 @@ typedef struct SArray {
|
|||
*/
|
||||
void* taosArrayInit(size_t size, size_t elemSize);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param tsize
|
||||
* @return
|
||||
*/
|
||||
int32_t taosArrayEnsureCap(SArray* pArray, size_t tsize);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pArray
|
||||
|
@ -153,6 +160,13 @@ void taosArraySet(SArray* pArray, size_t index, void* pData);
|
|||
*/
|
||||
void taosArrayPopFrontBatch(SArray* pArray, size_t cnt);
|
||||
|
||||
/**
|
||||
* remove some data entry from front
|
||||
* @param pArray
|
||||
* @param cnt
|
||||
*/
|
||||
void taosArrayPopTailBatch(SArray* pArray, size_t cnt);
|
||||
|
||||
/**
|
||||
* remove data entry of the given index
|
||||
* @param pArray
|
||||
|
@ -213,6 +227,14 @@ void taosArraySortString(SArray* pArray, __compar_fn_t comparFn);
|
|||
*/
|
||||
void* taosArraySearch(const SArray* pArray, const void* key, __compar_fn_t comparFn, int flags);
|
||||
|
||||
/**
|
||||
* search the array, return index of the element
|
||||
* @param pArray
|
||||
* @param compar
|
||||
* @param key
|
||||
*/
|
||||
int32_t taosArraySearchIdx(const SArray* pArray, const void* key, __compar_fn_t comparFn, int flags);
|
||||
|
||||
/**
|
||||
* search the array
|
||||
* @param pArray
|
||||
|
|
|
@ -39,7 +39,7 @@ static FORCE_INLINE int taosCalcChecksumAppend(TSCKSUM csi, uint8_t *stream, uin
|
|||
}
|
||||
|
||||
static FORCE_INLINE int taosCheckChecksum(const uint8_t *stream, uint32_t ssize, TSCKSUM checksum) {
|
||||
return (checksum == (*crc32c)(0, stream, (size_t)ssize));
|
||||
return (checksum != (*crc32c)(0, stream, (size_t)ssize));
|
||||
}
|
||||
|
||||
static FORCE_INLINE int taosCheckChecksumWhole(const uint8_t *stream, uint32_t ssize) {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TSDB_CFG_MAX_NUM 123
|
||||
#define TSDB_CFG_MAX_NUM 115
|
||||
#define TSDB_CFG_PRINT_LEN 23
|
||||
#define TSDB_CFG_OPTION_LEN 24
|
||||
#define TSDB_CFG_VALUE_LEN 41
|
||||
|
@ -83,11 +83,11 @@ extern int32_t tsGlobalConfigNum;
|
|||
extern char * tsCfgStatusStr[];
|
||||
|
||||
void taosReadGlobalLogCfg();
|
||||
int32_t taosReadGlobalCfg();
|
||||
void taosPrintGlobalCfg();
|
||||
int32_t taosReadCfgFromFile();
|
||||
void taosPrintCfg();
|
||||
void taosDumpGlobalCfg();
|
||||
|
||||
void taosInitConfigOption(SGlobalCfg cfg);
|
||||
void taosAddConfigOption(SGlobalCfg cfg);
|
||||
SGlobalCfg *taosGetConfigOption(const char *option);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -161,7 +161,7 @@ do { \
|
|||
|
||||
#define TSDB_NODE_NAME_LEN 64
|
||||
#define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string
|
||||
#define TSDB_DB_NAME_LEN 33
|
||||
#define TSDB_DB_NAME_LEN 65
|
||||
#define TSDB_FULL_DB_NAME_LEN (TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN)
|
||||
|
||||
#define TSDB_FUNC_NAME_LEN 65
|
||||
|
@ -193,7 +193,7 @@ do { \
|
|||
#define TSDB_MAX_TAG_CONDITIONS 1024
|
||||
|
||||
#define TSDB_AUTH_LEN 16
|
||||
#define TSDB_KEY_LEN 16
|
||||
#define TSDB_PASSWORD_LEN 32
|
||||
#define TSDB_VERSION_LEN 12
|
||||
#define TSDB_LABEL_LEN 8
|
||||
|
||||
|
@ -209,6 +209,8 @@ do { \
|
|||
#define TSDB_STEP_NAME_LEN 32
|
||||
#define TSDB_STEP_DESC_LEN 128
|
||||
|
||||
#define TSDB_DNODE_CONFIG_LEN 128
|
||||
|
||||
#define TSDB_MQTT_HOSTNAME_LEN 64
|
||||
#define TSDB_MQTT_PORT_LEN 8
|
||||
#define TSDB_MQTT_USER_LEN 24
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* 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 _TD_UTIL_TDLIST_H_
|
||||
#define _TD_UTIL_TDLIST_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Single linked list
|
||||
#define TD_SLIST_NODE(TYPE) \
|
||||
struct { \
|
||||
struct TYPE *sl_next_; \
|
||||
}
|
||||
|
||||
#define TD_SLIST(TYPE) \
|
||||
struct { \
|
||||
struct TYPE *sl_head_; \
|
||||
int sl_neles_; \
|
||||
}
|
||||
|
||||
#define TD_SLIST_HEAD(sl) ((sl)->sl_head_)
|
||||
#define TD_SLIST_NELES(sl) ((sl)->sl_neles_)
|
||||
#define TD_SLIST_NODE_NEXT(sln) ((sln)->sl_next_)
|
||||
|
||||
#define tSListInit(sl) \
|
||||
do { \
|
||||
(sl)->sl_head_ = NULL; \
|
||||
(sl)->sl_neles_ = 0; \
|
||||
} while (0)
|
||||
|
||||
#define tSListPush(sl, sln) \
|
||||
do { \
|
||||
TD_SLIST_NODE_NEXT(sln) = TD_SLIST_HEAD(sl); \
|
||||
TD_SLIST_HEAD(sl) = (sln); \
|
||||
TD_SLIST_NELES(sl) += 1; \
|
||||
} while (0)
|
||||
|
||||
#define tSListPop(sl) \
|
||||
do { \
|
||||
TD_SLIST_HEAD(sl) = TD_SLIST_NODE_NEXT(TD_SLIST_HEAD(sl)); \
|
||||
TD_SLIST_NELES(sl) -= 1; \
|
||||
} while (0)
|
||||
|
||||
// Double linked list
|
||||
#define TD_DLIST_NODE(TYPE) \
|
||||
struct { \
|
||||
TYPE *dl_prev_; \
|
||||
TYPE *dl_next_; \
|
||||
}
|
||||
|
||||
#define TD_DLIST(TYPE) \
|
||||
struct { \
|
||||
struct TYPE *dl_head_; \
|
||||
struct TYPE *dl_tail_; \
|
||||
int dl_neles_; \
|
||||
}
|
||||
|
||||
#define TD_DLIST_NODE_PREV(dln) ((dln)->dl_prev_)
|
||||
#define TD_DLIST_NODE_NEXT(dln) ((dln)->dl_next_)
|
||||
#define TD_DLIST_HEAD(dl) ((dl)->dl_head_)
|
||||
#define TD_DLIST_TAIL(dl) ((dl)->dl_tail_)
|
||||
#define TD_DLIST_NELES(dl) ((dl)->dl_neles_)
|
||||
|
||||
#define tDListInit(dl) \
|
||||
do { \
|
||||
TD_DLIST_HEAD(dl) = TD_DLIST_TAIL(dl) = NULL; \
|
||||
TD_DLIST_NELES(dl) = 0; \
|
||||
} while (0)
|
||||
|
||||
#define tDListAppend(dl, dln) \
|
||||
do { \
|
||||
if (TD_DLIST_HEAD(dl) == NULL) { \
|
||||
TD_DLIST_NODE_PREV(dln) = TD_DLIST_NODE_NEXT(dln) = NULL; \
|
||||
TD_DLIST_HEAD(dl) = TD_DLIST_TAIL(dl) = (dln); \
|
||||
} else { \
|
||||
TD_DLIST_NODE_PREV(dln) = TD_DLIST_TAIL(dl); \
|
||||
TD_DLIST_NODE_NEXT(dln) = NULL; \
|
||||
TD_DLIST_NODE_NEXT(TD_DLIST_TAIL(dl)) = (dln); \
|
||||
TD_DLIST_TAIL(dl) = (dln); \
|
||||
} \
|
||||
TD_DLIST_NELES(dl) += 1; \
|
||||
} while (0)
|
||||
|
||||
#define tDListPrepend(dl, dln) \
|
||||
do { \
|
||||
if (TD_DLIST_HEAD(dl) == NULL) { \
|
||||
TD_DLIST_NODE_PREV(dln) = TD_DLIST_NODE_NEXT(dln) = NULL; \
|
||||
TD_DLIST_HEAD(dl) = TD_DLIST_TAIL(dl) = (dln); \
|
||||
} else { \
|
||||
TD_DLIST_NODE_PREV(dln) = NULL; \
|
||||
TD_DLIST_NODE_NEXT(dln) = TD_DLIST_HEAD(dl); \
|
||||
TD_DLIST_NODE_PREV(TD_DLIST_HEAD(dl)) = (dln); \
|
||||
TD_DLIST_HEAD(dl) = (dln); \
|
||||
} \
|
||||
TD_DLIST_NELES(dl) += 1; \
|
||||
} while (0)
|
||||
|
||||
#define tDListPop(dl, dln) \
|
||||
do { \
|
||||
if (TD_DLIST_HEAD(dl) == (dln)) { \
|
||||
TD_DLIST_HEAD(dl) = TD_DLIST_NODE_NEXT(dln); \
|
||||
} \
|
||||
if (TD_DLIST_TAIL(dl) == (dln)) { \
|
||||
TD_DLIST_TAIL(dl) = TD_DLIST_NODE_PREV(dln); \
|
||||
} \
|
||||
if (TD_DLIST_NODE_PREV(dln) != NULL) { \
|
||||
TD_DLIST_NODE_NEXT(TD_DLIST_NODE_PREV(dln)) = TD_DLIST_NODE_NEXT(dln); \
|
||||
} \
|
||||
if (TD_DLIST_NODE_NEXT(dln) != NULL) { \
|
||||
TD_DLIST_NODE_PREV(TD_DLIST_NODE_NEXT(dln)) = TD_DLIST_NODE_PREV(dln); \
|
||||
} \
|
||||
TD_DLIST_NELES(dl) -= 1; \
|
||||
TD_DLIST_NODE_PREV(dln) = TD_DLIST_NODE_NEXT(dln) = NULL; \
|
||||
} while (0)
|
||||
|
||||
#if 0
|
||||
// List iterator
|
||||
#define TD_LIST_FITER 0
|
||||
#define TD_LIST_BITER 1
|
||||
#define TD_LIST_ITER(S) \
|
||||
struct { \
|
||||
int it_dir_; \
|
||||
S * it_next_; \
|
||||
S * it_ptr_; \
|
||||
TD_DLIST(S) * it_list_; \
|
||||
}
|
||||
|
||||
#define tlistIterInit(it, l, dir) \
|
||||
(it)->it_dir_ = (dir); \
|
||||
(it)->it_list_ = l; \
|
||||
if ((dir) == TD_LIST_FITER) { \
|
||||
(it)->it_next_ = (l)->dl_head_; \
|
||||
} else { \
|
||||
(it)->it_next_ = (l)->dl_tail_; \
|
||||
}
|
||||
|
||||
#define tlistIterNext(it) \
|
||||
({ \
|
||||
(it)->it_ptr_ = (it)->it_next_; \
|
||||
if ((it)->it_next_ != NULL) { \
|
||||
if ((it)->it_dir_ == TD_LIST_FITER) { \
|
||||
(it)->it_next_ = (it)->it_next_->next_; \
|
||||
} else { \
|
||||
(it)->it_next_ = (it)->it_next_->prev_; \
|
||||
} \
|
||||
} \
|
||||
(it)->it_ptr_; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_UTIL_TDLIST_H_*/
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 _TD_UTIL_MACRO_H_
|
||||
#define _TD_UTIL_MACRO_H_
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Module init/clear MACRO definitions
|
||||
#define TD_MOD_UNINITIALIZED 0
|
||||
#define TD_MOD_INITIALIZED 1
|
||||
|
||||
#define TD_MOD_UNCLEARD 0
|
||||
#define TD_MOD_CLEARD 1
|
||||
|
||||
#define TD_DEF_MOD_INIT_FLAG(MOD) static int8_t MOD##InitFlag = TD_MOD_UNINITIALIZED
|
||||
#define TD_DEF_MOD_CLEAR_FLAG(MOD) static int8_t MOD##ClearFlag = TD_MOD_UNCLEARD
|
||||
|
||||
#define TD_CHECK_AND_SET_MODE_INIT(MOD) \
|
||||
atomic_val_compare_exchange_8(&(MOD##InitFlag), TD_MOD_UNINITIALIZED, TD_MOD_INITIALIZED)
|
||||
|
||||
#define TD_CHECK_AND_SET_MOD_CLEAR(MOD) atomic_val_compare_exchange_8(&(MOD##ClearFlag), TD_MOD_UNCLEARD, TD_MOD_CLEARD)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_UTIL_MACRO_H_*/
|
|
@ -29,7 +29,7 @@ int32_t strdequote(char *src);
|
|||
int32_t strndequote(char *dst, const char *z, int32_t len);
|
||||
int32_t strRmquote(char *z, int32_t len);
|
||||
size_t strtrim(char *src);
|
||||
char *strnchr(char *haystack, char needle, int32_t len, bool skipquote);
|
||||
char *strnchr(const char *haystack, char needle, int32_t len, bool skipquote);
|
||||
char **strsplit(char *src, const char *delim, int32_t *num);
|
||||
char *strtolower(char *dst, const char *src);
|
||||
char *strntolower(char *dst, const char *src, int32_t n);
|
||||
|
@ -45,14 +45,25 @@ char *taosIpStr(uint32_t ipInt);
|
|||
uint32_t ip2uint(const char *const ip_addr);
|
||||
void taosIp2String(uint32_t ip, char *str);
|
||||
void taosIpPort2String(uint32_t ip, uint16_t port, char *str);
|
||||
int32_t taosGetFqdnPortFromEp(const char *ep, char *fqdn, uint16_t *port);
|
||||
|
||||
static FORCE_INLINE void taosEncryptPass(uint8_t *inBuf, size_t inLen, char *target) {
|
||||
T_MD5_CTX context;
|
||||
tMD5Init(&context);
|
||||
tMD5Update(&context, inBuf, (unsigned int)inLen);
|
||||
tMD5Final(&context);
|
||||
memcpy(target, context.digest, TSDB_KEY_LEN);
|
||||
memcpy(target, context.digest, tListLen(context.digest));
|
||||
}
|
||||
|
||||
static FORCE_INLINE void taosEncryptPass_c(uint8_t *inBuf, size_t len, char *target) {
|
||||
T_MD5_CTX context;
|
||||
tMD5Init(&context);
|
||||
tMD5Update(&context, inBuf, (unsigned int)len);
|
||||
tMD5Final(&context);
|
||||
|
||||
sprintf(target, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", context.digest[0], context.digest[1], context.digest[2],
|
||||
context.digest[3], context.digest[4], context.digest[5], context.digest[6], context.digest[7],
|
||||
context.digest[8], context.digest[9], context.digest[10], context.digest[11], context.digest[12],
|
||||
context.digest[13], context.digest[14], context.digest[15]);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -2,10 +2,14 @@ aux_source_directory(src CLIENT_SRC)
|
|||
add_library(taos ${CLIENT_SRC})
|
||||
target_include_directories(
|
||||
taos
|
||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
|
||||
PUBLIC "${CMAKE_SOURCE_DIR}/include/client"
|
||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
|
||||
)
|
||||
target_link_libraries(
|
||||
taos
|
||||
PRIVATE common
|
||||
INTERFACE api
|
||||
PRIVATE os util common transport parser
|
||||
)
|
||||
|
||||
ADD_SUBDIRECTORY(test)
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* 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 TDENGINE_CLIENTINT_H
|
||||
#define TDENGINE_CLIENTINT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "taos.h"
|
||||
#include "taosmsg.h"
|
||||
#include "thash.h"
|
||||
#include "tlist.h"
|
||||
#include "trpc.h"
|
||||
#include "tdef.h"
|
||||
#include "tmsgtype.h"
|
||||
#include "tep.h"
|
||||
|
||||
typedef struct SQueryExecMetric {
|
||||
int64_t start; // start timestamp
|
||||
int64_t parsed; // start to parse
|
||||
int64_t send; // start to send to server
|
||||
int64_t rsp; // receive response from server
|
||||
} SQueryExecMetric;
|
||||
|
||||
typedef struct SInstanceActivity {
|
||||
uint64_t numOfInsertsReq;
|
||||
uint64_t numOfInsertRows;
|
||||
uint64_t insertElapsedTime;
|
||||
uint64_t insertBytes; // submit to tsdb since launched.
|
||||
|
||||
uint64_t fetchBytes;
|
||||
uint64_t queryElapsedTime;
|
||||
uint64_t numOfSlowQueries;
|
||||
uint64_t totalRequests;
|
||||
uint64_t currentRequests; // the number of SRequestObj
|
||||
} SInstanceActivity;
|
||||
|
||||
typedef struct SHeartBeatInfo {
|
||||
void *pTimer; // timer, used to send request msg to mnode
|
||||
} SHeartBeatInfo;
|
||||
|
||||
typedef struct SAppInstInfo {
|
||||
int64_t numOfConns;
|
||||
SCorEpSet mgmtEp;
|
||||
SInstanceActivity summary;
|
||||
SList *pConnList; // STscObj linked list
|
||||
uint32_t clusterId;
|
||||
void *pTransporter;
|
||||
} SAppInstInfo;
|
||||
|
||||
typedef struct SAppInfo {
|
||||
int64_t startTime;
|
||||
char appName[TSDB_APP_NAME_LEN];
|
||||
char *ep;
|
||||
int32_t pid;
|
||||
int32_t numOfThreads;
|
||||
SHeartBeatInfo hb;
|
||||
SHashObj *pInstMap;
|
||||
} SAppInfo;
|
||||
|
||||
typedef struct STscObj {
|
||||
char user[TSDB_USER_LEN];
|
||||
char pass[TSDB_PASSWORD_LEN];
|
||||
char acctId[TSDB_ACCT_ID_LEN];
|
||||
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||
uint32_t connId;
|
||||
uint64_t id; // ref ID returned by taosAddRef
|
||||
// struct SSqlObj *sqlList;
|
||||
void *pTransporter;
|
||||
pthread_mutex_t mutex; // used to protect the operation on db
|
||||
int32_t numOfReqs; // number of sqlObj from this tscObj
|
||||
SAppInstInfo *pAppInfo;
|
||||
} STscObj;
|
||||
|
||||
typedef struct SReqBody {
|
||||
tsem_t rspSem; // not used now
|
||||
void* fp;
|
||||
void* param;
|
||||
} SRequestBody;
|
||||
|
||||
typedef struct SRequestObj {
|
||||
uint64_t requestId;
|
||||
int32_t type; // request type
|
||||
STscObj *pTscObj;
|
||||
SQueryExecMetric metric;
|
||||
char *sqlstr; // sql string
|
||||
SRequestBody body;
|
||||
int64_t self;
|
||||
char *msgBuf;
|
||||
int32_t code;
|
||||
void *pInfo; // sql parse info, generated by parser module
|
||||
} SRequestObj;
|
||||
|
||||
typedef struct SRequestMsgBody {
|
||||
int32_t msgType;
|
||||
void *pData;
|
||||
int32_t msgLen;
|
||||
uint64_t requestId;
|
||||
uint64_t requestObjRefId;
|
||||
} SRequestMsgBody;
|
||||
|
||||
extern SAppInfo appInfo;
|
||||
extern int32_t tscReqRef;
|
||||
extern void *tscQhandle;
|
||||
extern int32_t tscConnRef;
|
||||
|
||||
extern int (*tscBuildMsg[TSDB_SQL_MAX])(SRequestObj *pRequest, SRequestMsgBody *pMsg);
|
||||
extern int (*handleRequestRspFp[TSDB_SQL_MAX])(SRequestObj *pRequest, const char* pMsg, int32_t msgLen);
|
||||
|
||||
int taos_init();
|
||||
|
||||
void* createTscObj(const char* user, const char* auth, const char *ip, uint32_t port, SAppInstInfo* pAppInfo);
|
||||
void destroyTscObj(void*pObj);
|
||||
|
||||
void* createRequest(STscObj* pObj, __taos_async_fn_t fp, void* param, int32_t type);
|
||||
void destroyRequest(SRequestObj* pRequest);
|
||||
|
||||
TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass, const char *auth, const char *db, uint16_t port);
|
||||
|
||||
void taos_init_imp(void);
|
||||
int taos_options_imp(TSDB_OPTION option, const char *str);
|
||||
|
||||
void* openTransporter(const char *user, const char *auth);
|
||||
|
||||
void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet);
|
||||
void initMsgHandleFp();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TDENGINE_CLIENTINT_H
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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 TDENGINE_TSCLOG_H
|
||||
#define TDENGINE_TSCLOG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "tlog.h"
|
||||
|
||||
#define tscFatal(...) do { if (cDebugFlag & DEBUG_FATAL) { taosPrintLog("TSC FATAL ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscError(...) do { if (cDebugFlag & DEBUG_ERROR) { taosPrintLog("TSC ERROR ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscWarn(...) do { if (cDebugFlag & DEBUG_WARN) { taosPrintLog("TSC WARN ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscInfo(...) do { if (cDebugFlag & DEBUG_INFO) { taosPrintLog("TSC ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscDebug(...) do { if (cDebugFlag & DEBUG_DEBUG) { taosPrintLog("TSC ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscTrace(...) do { if (cDebugFlag & DEBUG_TRACE) { taosPrintLog("TSC ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscDebugL(...) do { if (cDebugFlag & DEBUG_DEBUG) { taosPrintLongString("TSC ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -13,14 +13,51 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//#include "taos.h"
|
||||
#include "os.h"
|
||||
#include "tdef.h"
|
||||
#include "tglobal.h"
|
||||
#include "clientInt.h"
|
||||
#include "tscLog.h"
|
||||
|
||||
//TAOS_RES *taos_query(TAOS *taos, const char *sql) {
|
||||
//
|
||||
//}
|
||||
#include "taosmsg.h"
|
||||
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
|
||||
int32_t p = (port != 0)? port:tsServerPort;
|
||||
|
||||
int taos_init() { return 0; }
|
||||
void taos_cleanup(void) {}
|
||||
tscDebug("try to connect to %s:%u, user:%s db:%s", ip, p, user, db);
|
||||
if (user == NULL) {
|
||||
user = TSDB_DEFAULT_USER;
|
||||
}
|
||||
|
||||
if (pass == NULL) {
|
||||
pass = TSDB_DEFAULT_PASS;
|
||||
}
|
||||
|
||||
return taos_connect_internal(ip, user, pass, NULL, db, p);
|
||||
}
|
||||
|
||||
TAOS *taos_connect_auth(const char *ip, const char *user, const char *auth, const char *db, uint16_t port) {
|
||||
tscDebug("try to connect to %s:%u by auth, user:%s db:%s", ip, port, user, db);
|
||||
if (user == NULL) {
|
||||
user = TSDB_DEFAULT_USER;
|
||||
}
|
||||
|
||||
if (auth == NULL) {
|
||||
tscError("No auth info is given, failed to connect to server");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return taos_connect_internal(ip, user, NULL, auth, db, port);
|
||||
}
|
||||
|
||||
TAOS *taos_connect_l(const char *ip, int ipLen, const char *user, int userLen, const char *pass, int passLen, const char *db, int dbLen, uint16_t port) {
|
||||
char ipStr[TSDB_EP_LEN] = {0};
|
||||
char dbStr[TSDB_DB_NAME_LEN] = {0};
|
||||
char userStr[TSDB_USER_LEN] = {0};
|
||||
char passStr[TSDB_PASSWORD_LEN] = {0};
|
||||
|
||||
strncpy(ipStr, ip, MIN(TSDB_EP_LEN - 1, ipLen));
|
||||
strncpy(userStr, user, MIN(TSDB_USER_LEN - 1, userLen));
|
||||
strncpy(passStr, pass, MIN(TSDB_PASSWORD_LEN - 1, passLen));
|
||||
strncpy(dbStr, db, MIN(TSDB_DB_NAME_LEN - 1, dbLen));
|
||||
return taos_connect(ipStr, userStr, passStr, dbStr, port);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,283 @@
|
|||
#include <tpagedfile.h>
|
||||
#include "clientInt.h"
|
||||
#include "tdef.h"
|
||||
#include "tep.h"
|
||||
#include "tglobal.h"
|
||||
#include "tmsgtype.h"
|
||||
#include "tref.h"
|
||||
#include "tscLog.h"
|
||||
|
||||
static int32_t initEpSetFromCfg(const char *firstEp, const char *secondEp, SCorEpSet *pEpSet);
|
||||
static int32_t buildConnectMsg(SRequestObj *pRequest, SRequestMsgBody* pMsgBody);
|
||||
static void destroyConnectMsg(SRequestMsgBody* pMsgBody);
|
||||
|
||||
static int32_t sendMsgToServer(void *pTransporter, SEpSet* epSet, const SRequestMsgBody *pBody, int64_t* pTransporterId);
|
||||
|
||||
static bool stringLengthCheck(const char* str, size_t maxsize) {
|
||||
if (str == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t len = strlen(str);
|
||||
if (len <= 0 || len > maxsize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool validateUserName(const char* user) {
|
||||
return stringLengthCheck(user, TSDB_USER_LEN - 1);
|
||||
}
|
||||
|
||||
static bool validatePassword(const char* passwd) {
|
||||
return stringLengthCheck(passwd, TSDB_PASSWORD_LEN - 1);
|
||||
}
|
||||
|
||||
static bool validateDbName(const char* db) {
|
||||
return stringLengthCheck(db, TSDB_DB_NAME_LEN - 1);
|
||||
}
|
||||
|
||||
static char* getClusterKey(const char* user, const char* auth, const char* ip, int32_t port) {
|
||||
char key[512] = {0};
|
||||
snprintf(key, sizeof(key), "%s:%s:%s:%d", user, auth, ip, port);
|
||||
return strdup(key);
|
||||
}
|
||||
|
||||
static STscObj* taosConnectImpl(const char *ip, const char *user, const char *auth, const char *db, uint16_t port, __taos_async_fn_t fp, void *param, SAppInstInfo* pAppInfo);
|
||||
|
||||
TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass, const char *auth, const char *db, uint16_t port) {
|
||||
if (taos_init() != TSDB_CODE_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!validateUserName(user)) {
|
||||
terrno = TSDB_CODE_TSC_INVALID_USER_LENGTH;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char tmp[TSDB_DB_NAME_LEN] = {0};
|
||||
if (db != NULL) {
|
||||
if(!validateDbName(db)) {
|
||||
terrno = TSDB_CODE_TSC_INVALID_DB_LENGTH;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tstrncpy(tmp, db, sizeof(tmp));
|
||||
strdequote(tmp);
|
||||
}
|
||||
|
||||
char secretEncrypt[32] = {0};
|
||||
if (auth == NULL) {
|
||||
if (!validatePassword(pass)) {
|
||||
terrno = TSDB_CODE_TSC_INVALID_PASS_LENGTH;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
taosEncryptPass_c((uint8_t *)pass, strlen(pass), secretEncrypt);
|
||||
} else {
|
||||
tstrncpy(secretEncrypt, auth, tListLen(secretEncrypt));
|
||||
}
|
||||
|
||||
SCorEpSet epSet = {0};
|
||||
if (ip) {
|
||||
if (initEpSetFromCfg(ip, NULL, &epSet) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (port) {
|
||||
epSet.epSet.port[0] = port;
|
||||
}
|
||||
} else {
|
||||
if (initEpSetFromCfg(tsFirst, tsSecond, &epSet) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char* key = getClusterKey(user, secretEncrypt, ip, port);
|
||||
|
||||
SAppInstInfo* pInst = taosHashGet(appInfo.pInstMap, key, strlen(key));
|
||||
if (pInst == NULL) {
|
||||
pInst = calloc(1, sizeof(struct SAppInstInfo));
|
||||
|
||||
pInst->mgmtEp = epSet;
|
||||
pInst->pTransporter = openTransporter(user, secretEncrypt);
|
||||
|
||||
taosHashPut(appInfo.pInstMap, key, strlen(key), &pInst, POINTER_BYTES);
|
||||
}
|
||||
|
||||
return taosConnectImpl(ip, user, &secretEncrypt[0], db, port, NULL, NULL, pInst);
|
||||
}
|
||||
|
||||
int initEpSetFromCfg(const char *firstEp, const char *secondEp, SCorEpSet *pEpSet) {
|
||||
pEpSet->version = 0;
|
||||
|
||||
// init mgmt ip set
|
||||
SEpSet *mgmtEpSet = &(pEpSet->epSet);
|
||||
mgmtEpSet->numOfEps = 0;
|
||||
mgmtEpSet->inUse = 0;
|
||||
|
||||
if (firstEp && firstEp[0] != 0) {
|
||||
if (strlen(firstEp) >= TSDB_EP_LEN) {
|
||||
terrno = TSDB_CODE_TSC_INVALID_FQDN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
taosGetFqdnPortFromEp(firstEp, mgmtEpSet->fqdn[0], &(mgmtEpSet->port[0]));
|
||||
mgmtEpSet->numOfEps++;
|
||||
}
|
||||
|
||||
if (secondEp && secondEp[0] != 0) {
|
||||
if (strlen(secondEp) >= TSDB_EP_LEN) {
|
||||
terrno = TSDB_CODE_TSC_INVALID_FQDN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
taosGetFqdnPortFromEp(secondEp, mgmtEpSet->fqdn[mgmtEpSet->numOfEps], &(mgmtEpSet->port[mgmtEpSet->numOfEps]));
|
||||
mgmtEpSet->numOfEps++;
|
||||
}
|
||||
|
||||
if (mgmtEpSet->numOfEps == 0) {
|
||||
terrno = TSDB_CODE_TSC_INVALID_FQDN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STscObj* taosConnectImpl(const char *ip, const char *user, const char *auth, const char *db, uint16_t port, __taos_async_fn_t fp, void *param, SAppInstInfo* pAppInfo) {
|
||||
STscObj *pTscObj = createTscObj(user, auth, ip, port, pAppInfo);
|
||||
if (NULL == pTscObj) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return pTscObj;
|
||||
}
|
||||
|
||||
SRequestObj *pRequest = createRequest(pTscObj, fp, param, TSDB_SQL_CONNECT);
|
||||
if (pRequest == NULL) {
|
||||
destroyTscObj(pTscObj);
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SRequestMsgBody body = {0};
|
||||
buildConnectMsg(pRequest, &body);
|
||||
|
||||
int64_t transporterId = 0;
|
||||
sendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &body, &transporterId);
|
||||
|
||||
tsem_wait(&pRequest->body.rspSem);
|
||||
destroyConnectMsg(&body);
|
||||
|
||||
if (pRequest->code != TSDB_CODE_SUCCESS) {
|
||||
const char *errorMsg = (pRequest->code == TSDB_CODE_RPC_FQDN_ERROR) ? taos_errstr(pRequest) : tstrerror(terrno);
|
||||
printf("failed to connect to server, reason: %s\n\n", errorMsg);
|
||||
|
||||
destroyRequest(pRequest);
|
||||
taos_close(pTscObj);
|
||||
pTscObj = NULL;
|
||||
} else {
|
||||
tscDebug("0x%"PRIx64" connection is opening, connId:%d, dnodeConn:%p", pTscObj->id, pTscObj->connId, pTscObj->pTransporter);
|
||||
destroyRequest(pRequest);
|
||||
}
|
||||
|
||||
return pTscObj;
|
||||
}
|
||||
|
||||
static int32_t buildConnectMsg(SRequestObj *pRequest, SRequestMsgBody* pMsgBody) {
|
||||
pMsgBody->msgType = TSDB_MSG_TYPE_CONNECT;
|
||||
pMsgBody->msgLen = sizeof(SConnectMsg);
|
||||
pMsgBody->requestObjRefId = pRequest->self;
|
||||
|
||||
SConnectMsg *pConnect = calloc(1, sizeof(SConnectMsg));
|
||||
if (pConnect == NULL) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO refactor full_name
|
||||
char *db; // ugly code to move the space
|
||||
|
||||
STscObj *pObj = pRequest->pTscObj;
|
||||
pthread_mutex_lock(&pObj->mutex);
|
||||
db = strstr(pObj->db, TS_PATH_DELIMITER);
|
||||
|
||||
db = (db == NULL) ? pObj->db : db + 1;
|
||||
tstrncpy(pConnect->db, db, sizeof(pConnect->db));
|
||||
pthread_mutex_unlock(&pObj->mutex);
|
||||
|
||||
pConnect->pid = htonl(appInfo.pid);
|
||||
pConnect->startTime = htobe64(appInfo.startTime);
|
||||
tstrncpy(pConnect->app, appInfo.appName, tListLen(pConnect->app));
|
||||
|
||||
pMsgBody->pData = pConnect;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void destroyConnectMsg(SRequestMsgBody* pMsgBody) {
|
||||
assert(pMsgBody != NULL);
|
||||
tfree(pMsgBody->pData);
|
||||
}
|
||||
|
||||
int32_t sendMsgToServer(void *pTransporter, SEpSet* epSet, const SRequestMsgBody *pBody, int64_t* pTransporterId) {
|
||||
char *pMsg = rpcMallocCont(pBody->msgLen);
|
||||
if (NULL == pMsg) {
|
||||
tscError("0x%"PRIx64" msg:%s malloc failed", pBody->requestId, taosMsg[pBody->msgType]);
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(pMsg, pBody->pData, pBody->msgLen);
|
||||
SRpcMsg rpcMsg = {
|
||||
.msgType = pBody->msgType,
|
||||
.pCont = pMsg,
|
||||
.contLen = pBody->msgLen,
|
||||
.ahandle = (void*) pBody->requestObjRefId,
|
||||
.handle = NULL,
|
||||
.code = 0
|
||||
};
|
||||
|
||||
rpcSendRequest(pTransporter, epSet, &rpcMsg, pTransporterId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) {
|
||||
int64_t requestRefId = (int64_t)pMsg->ahandle;
|
||||
|
||||
SRequestObj *pRequest = (SRequestObj *)taosAcquireRef(tscReqRef, requestRefId);
|
||||
if (pRequest == NULL) {
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(pRequest->self == requestRefId);
|
||||
pRequest->metric.rsp = taosGetTimestampMs();
|
||||
|
||||
pRequest->code = pMsg->code;
|
||||
|
||||
STscObj *pTscObj = pRequest->pTscObj;
|
||||
if (pEpSet) {
|
||||
if (!isEpsetEqual(&pTscObj->pAppInfo->mgmtEp.epSet, pEpSet)) {
|
||||
updateEpSet_s(&pTscObj->pAppInfo->mgmtEp, pEpSet);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* There is not response callback function for submit response.
|
||||
* The actual inserted number of points is the first number.
|
||||
*/
|
||||
if (pMsg->code == TSDB_CODE_SUCCESS) {
|
||||
tscDebug("0x%" PRIx64 " message:%s, code:%s rspLen:%d, elapsed:%"PRId64 " ms", pRequest->requestId, taosMsg[pMsg->msgType],
|
||||
tstrerror(pMsg->code), pMsg->contLen, pRequest->metric.rsp - pRequest->metric.start);
|
||||
if (handleRequestRspFp[pRequest->type]) {
|
||||
pMsg->code = (*handleRequestRspFp[pRequest->type])(pRequest, pMsg->pCont, pMsg->contLen);
|
||||
}
|
||||
} else {
|
||||
tscError("0x%" PRIx64 " SQL cmd:%s, code:%s rspLen:%d", pRequest->requestId, taosMsg[pMsg->msgType],
|
||||
tstrerror(pMsg->code), pMsg->contLen);
|
||||
}
|
||||
|
||||
taosReleaseRef(tscReqRef, requestRefId);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
|
||||
sem_post(&pRequest->body.rspSem);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,85 @@
|
|||
#include "clientInt.h"
|
||||
#include "trpc.h"
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tcache.h"
|
||||
#include "tconfig.h"
|
||||
#include "tglobal.h"
|
||||
#include "tnote.h"
|
||||
#include "tref.h"
|
||||
#include "tscLog.h"
|
||||
#include "tsched.h"
|
||||
#include "ttime.h"
|
||||
#include "ttimezone.h"
|
||||
|
||||
#define TSC_VAR_NOT_RELEASE 1
|
||||
#define TSC_VAR_RELEASED 0
|
||||
|
||||
static int32_t sentinel = TSC_VAR_NOT_RELEASE;
|
||||
static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
|
||||
|
||||
extern int32_t tscInitRes;
|
||||
|
||||
int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
||||
static int32_t lock = 0;
|
||||
|
||||
for (int i = 1; atomic_val_compare_exchange_32(&lock, 0, 1) != 0; ++i) {
|
||||
if (i % 1000 == 0) {
|
||||
tscInfo("haven't acquire lock after spin %d times.", i);
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
|
||||
int ret = taos_options_imp(option, (const char*)arg);
|
||||
|
||||
atomic_store_32(&lock, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int taos_init() {
|
||||
pthread_once(&tscinit, taos_init_imp);
|
||||
return tscInitRes;
|
||||
}
|
||||
|
||||
// this function may be called by user or system, or by both simultaneously.
|
||||
void taos_cleanup(void) {
|
||||
tscDebug("start to cleanup client environment");
|
||||
|
||||
if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t id = tscReqRef;
|
||||
tscReqRef = -1;
|
||||
taosCloseRef(id);
|
||||
|
||||
void* p = tscQhandle;
|
||||
tscQhandle = NULL;
|
||||
taosCleanUpScheduler(p);
|
||||
|
||||
id = tscConnRef;
|
||||
tscConnRef = -1;
|
||||
taosCloseRef(id);
|
||||
|
||||
rpcCleanup();
|
||||
taosCloseLog();
|
||||
}
|
||||
|
||||
void taos_close(TAOS* taos) {
|
||||
if (taos == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
STscObj *pTscObj = (STscObj *)taos;
|
||||
tscDebug("0x%"PRIx64" try to close connection, numOfReq:%d", pTscObj->id, pTscObj->numOfReqs);
|
||||
|
||||
taosRemoveRef(tscConnRef, pTscObj->id);
|
||||
}
|
||||
|
||||
const char *taos_errstr(TAOS_RES *res) {
|
||||
|
||||
}
|
||||
|
||||
void taos_free_result(TAOS_RES *res) {
|
||||
|
||||
}
|
|
@ -0,0 +1,471 @@
|
|||
/*
|
||||
* 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 "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tcache.h"
|
||||
#include "tconfig.h"
|
||||
#include "tglobal.h"
|
||||
#include "tnote.h"
|
||||
#include "tref.h"
|
||||
#include "tscLog.h"
|
||||
#include "tsched.h"
|
||||
#include "ttime.h"
|
||||
#include "trpc.h"
|
||||
#include "ttimezone.h"
|
||||
#include "clientInt.h"
|
||||
|
||||
#define TSC_VAR_NOT_RELEASE 1
|
||||
#define TSC_VAR_RELEASED 0
|
||||
|
||||
SAppInfo appInfo;
|
||||
int32_t tscReqRef = -1;
|
||||
int32_t tscConnRef = -1;
|
||||
void *tscQhandle = NULL;
|
||||
|
||||
int32_t tsNumOfThreads = 1;
|
||||
volatile int32_t tscInitRes = 0;
|
||||
|
||||
static void registerRequest(SRequestObj* pRequest) {
|
||||
STscObj *pTscObj = (STscObj *)taosAcquireRef(tscConnRef, pRequest->pTscObj->id);
|
||||
assert(pTscObj != NULL);
|
||||
|
||||
// connection has been released already, abort creating request.
|
||||
pRequest->self = taosAddRef(tscReqRef, pRequest);
|
||||
|
||||
int32_t num = atomic_add_fetch_32(&pTscObj->numOfReqs, 1);
|
||||
|
||||
if (pTscObj->pAppInfo) {
|
||||
SInstanceActivity *pActivity = &pTscObj->pAppInfo->summary;
|
||||
|
||||
int32_t total = atomic_add_fetch_32(&pActivity->totalRequests, 1);
|
||||
int32_t currentInst = atomic_add_fetch_32(&pActivity->currentRequests, 1);
|
||||
tscDebug("0x%" PRIx64 " new Request from connObj:0x%" PRIx64 ", current:%d, app current:%d, total:%d", pRequest->self,
|
||||
pRequest->pTscObj->id, num, currentInst, total);
|
||||
}
|
||||
}
|
||||
|
||||
static void deregisterRequest(SRequestObj* pRequest) {
|
||||
assert(pRequest != NULL);
|
||||
|
||||
STscObj* pTscObj = pRequest->pTscObj;
|
||||
SInstanceActivity* pActivity = &pTscObj->pAppInfo->summary;
|
||||
|
||||
int32_t currentInst = atomic_sub_fetch_32(&pActivity->currentRequests, 1);
|
||||
int32_t num = atomic_sub_fetch_32(&pTscObj->numOfReqs, 1);
|
||||
|
||||
tscDebug("0x%"PRIx64" free Request from connObj: 0x%"PRIx64", current:%d, app current:%d", pRequest->self, pTscObj->id, num, currentInst);
|
||||
taosReleaseRef(tscConnRef, pTscObj->id);
|
||||
}
|
||||
|
||||
static void tscInitLogFile() {
|
||||
taosReadGlobalLogCfg();
|
||||
if (mkdir(tsLogDir, 0755) != 0 && errno != EEXIST) {
|
||||
printf("failed to create log dir:%s\n", tsLogDir);
|
||||
}
|
||||
|
||||
const char *defaultLogFileNamePrefix = "taoslog";
|
||||
const int32_t maxLogFileNum = 10;
|
||||
|
||||
char temp[128] = {0};
|
||||
sprintf(temp, "%s/%s", tsLogDir, defaultLogFileNamePrefix);
|
||||
if (taosInitLog(temp, tsNumOfLogLines, maxLogFileNum) < 0) {
|
||||
printf("failed to open log file in directory:%s\n", tsLogDir);
|
||||
}
|
||||
}
|
||||
|
||||
void closeTransporter(STscObj* pTscObj) {
|
||||
if (pTscObj == NULL || pTscObj->pTransporter == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
tscDebug("free transporter:%p in connObj: 0x%"PRIx64, pTscObj->pTransporter, pTscObj->id);
|
||||
rpcClose(pTscObj->pTransporter);
|
||||
pTscObj->pTransporter = NULL;
|
||||
}
|
||||
|
||||
// TODO refactor
|
||||
void* openTransporter(const char *user, const char *auth) {
|
||||
SRpcInit rpcInit;
|
||||
memset(&rpcInit, 0, sizeof(rpcInit));
|
||||
rpcInit.localPort = 0;
|
||||
rpcInit.label = "TSC";
|
||||
rpcInit.numOfThreads = tsNumOfThreads;
|
||||
rpcInit.cfp = processMsgFromServer;
|
||||
rpcInit.sessions = tsMaxConnections;
|
||||
rpcInit.connType = TAOS_CONN_CLIENT;
|
||||
rpcInit.user = (char *)user;
|
||||
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
||||
rpcInit.ckey = "key";
|
||||
// rpcInit.spi = 1;
|
||||
rpcInit.secret = (char *)auth;
|
||||
|
||||
void* pDnodeConn = rpcOpen(&rpcInit);
|
||||
if (pDnodeConn == NULL) {
|
||||
tscError("failed to init connection to server");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pDnodeConn;
|
||||
}
|
||||
|
||||
void destroyTscObj(void *pObj) {
|
||||
STscObj *pTscObj = pObj;
|
||||
|
||||
atomic_sub_fetch_64(&pTscObj->pAppInfo->numOfConns, 1);
|
||||
tscDebug("connObj 0x%"PRIx64" destroyed, totalConn:%"PRId64, pTscObj->id, pTscObj->pAppInfo->numOfConns);
|
||||
|
||||
closeTransporter(pTscObj);
|
||||
pthread_mutex_destroy(&pTscObj->mutex);
|
||||
tfree(pTscObj);
|
||||
}
|
||||
|
||||
void* createTscObj(const char* user, const char* auth, const char *ip, uint32_t port, SAppInstInfo* pAppInfo) {
|
||||
STscObj *pObj = (STscObj *)calloc(1, sizeof(STscObj));
|
||||
if (NULL == pObj) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pObj->pAppInfo = pAppInfo;
|
||||
if (pAppInfo != NULL) {
|
||||
pObj->pTransporter = pAppInfo->pTransporter;
|
||||
}
|
||||
|
||||
tstrncpy(pObj->user, user, sizeof(pObj->user));
|
||||
memcpy(pObj->pass, auth, TSDB_PASSWORD_LEN);
|
||||
|
||||
pthread_mutex_init(&pObj->mutex, NULL);
|
||||
pObj->id = taosAddRef(tscConnRef, pObj);
|
||||
|
||||
tscDebug("connObj created, 0x%"PRIx64, pObj->id);
|
||||
return pObj;
|
||||
}
|
||||
|
||||
void* createRequest(STscObj* pObj, __taos_async_fn_t fp, void* param, int32_t type) {
|
||||
assert(pObj != NULL);
|
||||
|
||||
SRequestObj *pRequest = (SRequestObj *)calloc(1, sizeof(SRequestObj));
|
||||
if (NULL == pRequest) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO generated request uuid
|
||||
pRequest->requestId = 0;
|
||||
|
||||
pRequest->metric.start = taosGetTimestampMs();
|
||||
|
||||
pRequest->type = type;
|
||||
pRequest->pTscObj = pObj;
|
||||
pRequest->body.fp = fp;
|
||||
pRequest->body.param = param;
|
||||
tsem_init(&pRequest->body.rspSem, 0, 0);
|
||||
|
||||
registerRequest(pRequest);
|
||||
return pRequest;
|
||||
}
|
||||
|
||||
static void doDestroyRequest(void* p) {
|
||||
assert(p != NULL);
|
||||
SRequestObj* pRequest = (SRequestObj*)p;
|
||||
|
||||
assert(RID_VALID(pRequest->self));
|
||||
|
||||
tfree(pRequest->msgBuf);
|
||||
tfree(pRequest->sqlstr);
|
||||
tfree(pRequest->pInfo);
|
||||
|
||||
deregisterRequest(pRequest);
|
||||
tfree(pRequest);
|
||||
}
|
||||
|
||||
void destroyRequest(SRequestObj* pRequest) {
|
||||
if (pRequest == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
taosReleaseRef(tscReqRef, pRequest->self);
|
||||
}
|
||||
|
||||
void taos_init_imp(void) {
|
||||
// In the APIs of other program language, taos_cleanup is not available yet.
|
||||
// So, to make sure taos_cleanup will be invoked to clean up the allocated resource to suppress the valgrind warning.
|
||||
atexit(taos_cleanup);
|
||||
|
||||
errno = TSDB_CODE_SUCCESS;
|
||||
srand(taosGetTimestampSec());
|
||||
|
||||
deltaToUtcInitOnce();
|
||||
taosInitGlobalCfg();
|
||||
taosReadCfgFromFile();
|
||||
|
||||
tscInitLogFile();
|
||||
if (taosCheckAndPrintCfg()) {
|
||||
tscInitRes = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
taosInitNotes();
|
||||
initMsgHandleFp();
|
||||
|
||||
rpcInit();
|
||||
|
||||
tscDebug("starting to initialize TAOS driver, local ep: %s", tsLocalEp);
|
||||
|
||||
taosSetCoreDump(true);
|
||||
|
||||
double factor = 4.0;
|
||||
int32_t numOfThreads = MAX((int)(tsNumOfCores * tsNumOfThreadsPerCore / factor), 2);
|
||||
|
||||
int32_t queueSize = tsMaxConnections * 2;
|
||||
tscQhandle = taosInitScheduler(queueSize, numOfThreads, "tsc");
|
||||
if (NULL == tscQhandle) {
|
||||
tscError("failed to init task queue");
|
||||
tscInitRes = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
tscDebug("client task queue is initialized, numOfThreads: %d", numOfThreads);
|
||||
tscConnRef = taosOpenRef(200, destroyTscObj);
|
||||
tscReqRef = taosOpenRef(40960, doDestroyRequest);
|
||||
|
||||
taosGetAppName(appInfo.appName, NULL);
|
||||
appInfo.pid = taosGetPId();
|
||||
appInfo.startTime = taosGetTimestampMs();
|
||||
appInfo.pInstMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
|
||||
|
||||
tscDebug("client is initialized successfully");
|
||||
}
|
||||
|
||||
int taos_options_imp(TSDB_OPTION option, const char *str) {
|
||||
SGlobalCfg *cfg = NULL;
|
||||
|
||||
switch (option) {
|
||||
case TSDB_OPTION_CONFIGDIR:
|
||||
cfg = taosGetConfigOption("configDir");
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
|
||||
tstrncpy(configDir, str, TSDB_FILENAME_LEN);
|
||||
cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
|
||||
tscInfo("set config file directory:%s", str);
|
||||
} else {
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, str, tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case TSDB_OPTION_SHELL_ACTIVITY_TIMER:
|
||||
cfg = taosGetConfigOption("shellActivityTimer");
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
|
||||
tsShellActivityTimer = atoi(str);
|
||||
if (tsShellActivityTimer < 1) tsShellActivityTimer = 1;
|
||||
if (tsShellActivityTimer > 3600) tsShellActivityTimer = 3600;
|
||||
cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
|
||||
tscInfo("set shellActivityTimer:%d", tsShellActivityTimer);
|
||||
} else {
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %d", cfg->option, str, tsCfgStatusStr[cfg->cfgStatus], *(int32_t *)cfg->ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case TSDB_OPTION_LOCALE: { // set locale
|
||||
cfg = taosGetConfigOption("locale");
|
||||
assert(cfg != NULL);
|
||||
|
||||
size_t len = strlen(str);
|
||||
if (len == 0 || len > TSDB_LOCALE_LEN) {
|
||||
tscInfo("Invalid locale:%s, use default", str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
|
||||
char sep = '.';
|
||||
|
||||
if (strlen(tsLocale) == 0) { // locale does not set yet
|
||||
char* defaultLocale = setlocale(LC_CTYPE, "");
|
||||
|
||||
// The locale of the current OS does not be set correctly, so the default locale cannot be acquired.
|
||||
// The launch of current system will abort soon.
|
||||
if (defaultLocale == NULL) {
|
||||
tscError("failed to get default locale, please set the correct locale in current OS");
|
||||
return -1;
|
||||
}
|
||||
|
||||
tstrncpy(tsLocale, defaultLocale, TSDB_LOCALE_LEN);
|
||||
}
|
||||
|
||||
// set the user specified locale
|
||||
char *locale = setlocale(LC_CTYPE, str);
|
||||
|
||||
if (locale != NULL) { // failed to set the user specified locale
|
||||
tscInfo("locale set, prev locale:%s, new locale:%s", tsLocale, locale);
|
||||
cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
|
||||
} else { // set the user specified locale failed, use default LC_CTYPE as current locale
|
||||
locale = setlocale(LC_CTYPE, tsLocale);
|
||||
tscInfo("failed to set locale:%s, current locale:%s", str, tsLocale);
|
||||
}
|
||||
|
||||
tstrncpy(tsLocale, locale, TSDB_LOCALE_LEN);
|
||||
|
||||
char *charset = strrchr(tsLocale, sep);
|
||||
if (charset != NULL) {
|
||||
charset += 1;
|
||||
|
||||
charset = taosCharsetReplace(charset);
|
||||
|
||||
if (taosValidateEncodec(charset)) {
|
||||
if (strlen(tsCharset) == 0) {
|
||||
tscInfo("charset set:%s", charset);
|
||||
} else {
|
||||
tscInfo("charset changed from %s to %s", tsCharset, charset);
|
||||
}
|
||||
|
||||
tstrncpy(tsCharset, charset, TSDB_LOCALE_LEN);
|
||||
cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
|
||||
|
||||
} else {
|
||||
tscInfo("charset:%s is not valid in locale, charset remains:%s", charset, tsCharset);
|
||||
}
|
||||
|
||||
free(charset);
|
||||
} else { // it may be windows system
|
||||
tscInfo("charset remains:%s", tsCharset);
|
||||
}
|
||||
} else {
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, str, tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_OPTION_CHARSET: {
|
||||
/* set charset will override the value of charset, assigned during system locale changed */
|
||||
cfg = taosGetConfigOption("charset");
|
||||
assert(cfg != NULL);
|
||||
|
||||
size_t len = strlen(str);
|
||||
if (len == 0 || len > TSDB_LOCALE_LEN) {
|
||||
tscInfo("failed to set charset:%s", str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
|
||||
if (taosValidateEncodec(str)) {
|
||||
if (strlen(tsCharset) == 0) {
|
||||
tscInfo("charset is set:%s", str);
|
||||
} else {
|
||||
tscInfo("charset changed from %s to %s", tsCharset, str);
|
||||
}
|
||||
|
||||
tstrncpy(tsCharset, str, TSDB_LOCALE_LEN);
|
||||
cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
|
||||
} else {
|
||||
tscInfo("charset:%s not valid", str);
|
||||
}
|
||||
} else {
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, str, tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_OPTION_TIMEZONE:
|
||||
cfg = taosGetConfigOption("timezone");
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
|
||||
tstrncpy(tsTimezone, str, TSDB_TIMEZONE_LEN);
|
||||
tsSetTimeZone();
|
||||
cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
|
||||
tscDebug("timezone set:%s, input:%s by taos_options", tsTimezone, str);
|
||||
} else {
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, str, tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// TODO return the correct error code to client in the format for taos_errstr()
|
||||
tscError("Invalid option %d", option);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#include "cJSON.h"
|
||||
static setConfRet taos_set_config_imp(const char *config){
|
||||
setConfRet ret = {SET_CONF_RET_SUCC, {0}};
|
||||
static bool setConfFlag = false;
|
||||
if (setConfFlag) {
|
||||
ret.retCode = SET_CONF_RET_ERR_ONLY_ONCE;
|
||||
strcpy(ret.retMsg, "configuration can only set once");
|
||||
return ret;
|
||||
}
|
||||
taosInitGlobalCfg();
|
||||
cJSON *root = cJSON_Parse(config);
|
||||
if (root == NULL){
|
||||
ret.retCode = SET_CONF_RET_ERR_JSON_PARSE;
|
||||
strcpy(ret.retMsg, "parse json error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int size = cJSON_GetArraySize(root);
|
||||
if(!cJSON_IsObject(root) || size == 0) {
|
||||
ret.retCode = SET_CONF_RET_ERR_JSON_INVALID;
|
||||
strcpy(ret.retMsg, "json content is invalid, must be not empty object");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(size >= 1000) {
|
||||
ret.retCode = SET_CONF_RET_ERR_TOO_LONG;
|
||||
strcpy(ret.retMsg, "json object size is too long");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for(int i = 0; i < size; i++){
|
||||
cJSON *item = cJSON_GetArrayItem(root, i);
|
||||
if(!item) {
|
||||
ret.retCode = SET_CONF_RET_ERR_INNER;
|
||||
strcpy(ret.retMsg, "inner error");
|
||||
return ret;
|
||||
}
|
||||
if(!taosReadConfigOption(item->string, item->valuestring, NULL, NULL, TAOS_CFG_CSTATUS_OPTION, TSDB_CFG_CTYPE_B_CLIENT)){
|
||||
ret.retCode = SET_CONF_RET_ERR_PART;
|
||||
if (strlen(ret.retMsg) == 0){
|
||||
snprintf(ret.retMsg, RET_MSG_LENGTH, "part error|%s", item->string);
|
||||
}else{
|
||||
int tmp = RET_MSG_LENGTH - 1 - (int)strlen(ret.retMsg);
|
||||
size_t leftSize = tmp >= 0 ? tmp : 0;
|
||||
strncat(ret.retMsg, "|", leftSize);
|
||||
tmp = RET_MSG_LENGTH - 1 - (int)strlen(ret.retMsg);
|
||||
leftSize = tmp >= 0 ? tmp : 0;
|
||||
strncat(ret.retMsg, item->string, leftSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
cJSON_Delete(root);
|
||||
setConfFlag = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
setConfRet taos_set_config(const char *config){
|
||||
pthread_mutex_lock(&setConfMutex);
|
||||
setConfRet ret = taos_set_config_imp(config);
|
||||
pthread_mutex_unlock(&setConfMutex);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
MESSAGE(STATUS "build parser unit test")
|
||||
|
||||
# GoogleTest requires at least C++11
|
||||
SET(CMAKE_CXX_STANDARD 11)
|
||||
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
|
||||
|
||||
ADD_EXECUTABLE(clientTest ${SOURCE_LIST})
|
||||
TARGET_LINK_LIBRARIES(
|
||||
clientTest
|
||||
PUBLIC os util common transport gtest taos
|
||||
)
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(
|
||||
clientTest
|
||||
PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/client/"
|
||||
PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/client/inc"
|
||||
)
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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 <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include "tglobal.h"
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
|
||||
#include "taos.h"
|
||||
|
||||
namespace {
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
TEST(testCase, driverInit_Test) {
|
||||
TAOS* pConn = taos_connect("ubuntu", "root", "taosdata", NULL, 0);
|
||||
assert(pConn != NULL);
|
||||
|
||||
taos_close(pConn);
|
||||
}
|
|
@ -24,12 +24,11 @@ extern "C" {
|
|||
#include "tlog.h"
|
||||
|
||||
extern int32_t cDebugFlag;
|
||||
extern int8_t tscEmbedded;
|
||||
|
||||
#define tscFatal(...) do { if (cDebugFlag & DEBUG_FATAL) { taosPrintLog("TSC FATAL ", tscEmbedded ? 255 : cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscError(...) do { if (cDebugFlag & DEBUG_ERROR) { taosPrintLog("TSC ERROR ", tscEmbedded ? 255 : cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscWarn(...) do { if (cDebugFlag & DEBUG_WARN) { taosPrintLog("TSC WARN ", tscEmbedded ? 255 : cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscInfo(...) do { if (cDebugFlag & DEBUG_INFO) { taosPrintLog("TSC ", tscEmbedded ? 255 : cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscFatal(...) do { if (cDebugFlag & DEBUG_FATAL) { taosPrintLog("TSC FATAL ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscError(...) do { if (cDebugFlag & DEBUG_ERROR) { taosPrintLog("TSC ERROR ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscWarn(...) do { if (cDebugFlag & DEBUG_WARN) { taosPrintLog("TSC WARN ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscInfo(...) do { if (cDebugFlag & DEBUG_INFO) { taosPrintLog("TSC ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscDebug(...) do { if (cDebugFlag & DEBUG_DEBUG) { taosPrintLog("TSC ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscTrace(...) do { if (cDebugFlag & DEBUG_TRACE) { taosPrintLog("TSC ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
#define tscDebugL(...) do { if (cDebugFlag & DEBUG_DEBUG) { taosPrintLongString("TSC ", cDebugFlag, __VA_ARGS__); }} while(0)
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
#include "tep.h"
|
||||
#include "tglobal.h"
|
||||
#include "tlockfree.h"
|
||||
|
||||
int taosGetFqdnPortFromEp(const char *ep, char *fqdn, uint16_t *port) {
|
||||
*port = 0;
|
||||
strcpy(fqdn, ep);
|
||||
|
||||
char *temp = strchr(fqdn, ':');
|
||||
if (temp) {
|
||||
*temp = 0;
|
||||
*port = atoi(temp+1);
|
||||
}
|
||||
|
||||
if (*port == 0) {
|
||||
*port = tsServerPort;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool isEpsetEqual(const SEpSet *s1, const SEpSet *s2) {
|
||||
if (s1->numOfEps != s2->numOfEps || s1->inUse != s2->inUse) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < s1->numOfEps; i++) {
|
||||
if (s1->port[i] != s2->port[i]
|
||||
|| strncmp(s1->fqdn[i], s2->fqdn[i], TSDB_FQDN_LEN) != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void updateEpSet_s(SCorEpSet *pEpSet, SEpSet *pNewEpSet) {
|
||||
taosCorBeginWrite(&pEpSet->version);
|
||||
pEpSet->epSet = *pNewEpSet;
|
||||
taosCorEndWrite(&pEpSet->version);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -82,18 +82,18 @@ void deltaToUtcInitOnce() {
|
|||
}
|
||||
|
||||
static int64_t parseFraction(char* str, char** end, int32_t timePrec);
|
||||
static int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim);
|
||||
static int32_t parseTimeWithTz(const char* timestr, int64_t* time, int32_t timePrec, char delim);
|
||||
static int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec);
|
||||
static int32_t parseLocaltimeDst(char* timestr, int64_t* time, int32_t timePrec);
|
||||
static char* forwardToTimeStringEnd(char* str);
|
||||
static bool checkTzPresent(char *str, int32_t len);
|
||||
static bool checkTzPresent(const char *str, int32_t len);
|
||||
|
||||
static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t timePrec) = {
|
||||
parseLocaltime,
|
||||
parseLocaltimeDst
|
||||
};
|
||||
|
||||
int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) {
|
||||
int32_t taosParseTime(const char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) {
|
||||
/* parse datatime string in with tz */
|
||||
if (strnchr(timestr, 'T', len, false) != NULL) {
|
||||
return parseTimeWithTz(timestr, time, timePrec, 'T');
|
||||
|
@ -104,7 +104,7 @@ int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePre
|
|||
}
|
||||
}
|
||||
|
||||
bool checkTzPresent(char *str, int32_t len) {
|
||||
bool checkTzPresent(const char *str, int32_t len) {
|
||||
char *seg = forwardToTimeStringEnd(str);
|
||||
int32_t seg_len = len - (int32_t)(seg - str);
|
||||
|
||||
|
@ -237,7 +237,7 @@ int32_t parseTimezone(char* str, int64_t* tzOffset) {
|
|||
* 2013-04-12T15:52:01+0800
|
||||
* 2013-04-12T15:52:01.123+0800
|
||||
*/
|
||||
int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim) {
|
||||
int32_t parseTimeWithTz(const char* timestr, int64_t* time, int32_t timePrec, char delim) {
|
||||
|
||||
int64_t factor = (timePrec == TSDB_TIME_PRECISION_MILLI) ? 1000 :
|
||||
(timePrec == TSDB_TIME_PRECISION_MICRO ? 1000000 : 1000000000);
|
||||
|
@ -432,7 +432,7 @@ static int32_t getDuration(int64_t val, char unit, int64_t* result, int32_t time
|
|||
* d - Days (24 hours)
|
||||
* w - Weeks (7 days)
|
||||
*/
|
||||
int32_t parseAbsoluteDuration(char* token, int32_t tokenlen, int64_t* duration, char* unit, int32_t timePrecision) {
|
||||
int32_t parseAbsoluteDuration(const char* token, int32_t tokenlen, int64_t* duration, char* unit, int32_t timePrecision) {
|
||||
errno = 0;
|
||||
char* endPtr = NULL;
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ int32_t toInteger(const char* z, int32_t n, int32_t base, int64_t* value, bool*
|
|||
return 0;
|
||||
}
|
||||
|
||||
void taosVariantCreate(SVariant *pVar, char* z, int32_t n, int32_t type) {
|
||||
void taosVariantCreate(SVariant *pVar, const char* z, int32_t n, int32_t type) {
|
||||
int32_t ret = 0;
|
||||
memset(pVar, 0, sizeof(SVariant));
|
||||
|
||||
|
|
|
@ -112,12 +112,12 @@ int dmnReadConfig(const char *path) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (taosReadGlobalCfg() != 0) {
|
||||
if (taosReadCfgFromFile() != 0) {
|
||||
uError("failed to read global config");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (taosCheckGlobalCfg() != 0) {
|
||||
if (taosCheckAndPrintCfg() != 0) {
|
||||
uError("failed to check global config");
|
||||
return -1;
|
||||
}
|
||||
|
@ -142,7 +142,6 @@ void dmnInitOption(SDnodeOpt *pOption) {
|
|||
pOption->numOfSupportVnodes = 1;
|
||||
pOption->numOfSupportQnodes = 1;
|
||||
pOption->statusInterval = tsStatusInterval;
|
||||
pOption->mnodeEqualVnodeNum = tsMnodeEqualVnodeNum;
|
||||
pOption->numOfThreadsPerCore = tsNumOfThreadsPerCore;
|
||||
pOption->ratioOfQueryCores = tsRatioOfQueryCores;
|
||||
pOption->maxShellConns = tsMaxShellConns;
|
||||
|
|
|
@ -31,6 +31,7 @@ int32_t dndGetClusterId(SDnode *pDnode);
|
|||
void dndGetDnodeEp(SDnode *pDnode, int32_t dnodeId, char *pEp, char *pFqdn, uint16_t *pPort);
|
||||
void dndGetMnodeEpSet(SDnode *pDnode, SEpSet *pEpSet);
|
||||
void dndSendRedirectMsg(SDnode *pDnode, SRpcMsg *pMsg);
|
||||
void dndSendStatusMsg(SDnode *pDnode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -58,7 +58,8 @@ typedef struct {
|
|||
int32_t dnodeId;
|
||||
int32_t dropped;
|
||||
int32_t clusterId;
|
||||
uint32_t rebootTime;
|
||||
int64_t rebootTime;
|
||||
int8_t statusSent;
|
||||
SEpSet mnodeEpSet;
|
||||
char *file;
|
||||
SHashObj *dnodeHash;
|
||||
|
@ -111,6 +112,7 @@ typedef struct SDnode {
|
|||
EStat stat;
|
||||
SDnodeOpt opt;
|
||||
SDnodeDir dir;
|
||||
FileFd lockFd;
|
||||
SDnodeMgmt dmgmt;
|
||||
SMnodeMgmt mmgmt;
|
||||
SVnodesMgmt vmgmt;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "dndDnode.h"
|
||||
#include "dndTransport.h"
|
||||
#include "dndVnodes.h"
|
||||
#include "tep.h"
|
||||
|
||||
int32_t dndGetDnodeId(SDnode *pDnode) {
|
||||
SDnodeMgmt *pMgmt = &pDnode->dmgmt;
|
||||
|
@ -281,9 +282,8 @@ PRASE_DNODE_OVER:
|
|||
if (pMgmt->dnodeEps == NULL) {
|
||||
pMgmt->dnodeEps = calloc(1, sizeof(SDnodeEps) + sizeof(SDnodeEp));
|
||||
pMgmt->dnodeEps->num = 1;
|
||||
pMgmt->dnodeEps->eps[0].isMnode = 1;
|
||||
pMgmt->dnodeEps->eps[0].port = pDnode->opt.serverPort;
|
||||
tstrncpy(pMgmt->dnodeEps->eps[0].fqdn, pDnode->opt.localFqdn, TSDB_FQDN_LEN);
|
||||
pMgmt->dnodeEps->eps[0].isMnode = 1;
|
||||
taosGetFqdnPortFromEp(pDnode->opt.firstEp, pMgmt->dnodeEps->eps[0].fqdn, &pMgmt->dnodeEps->eps[0].port);
|
||||
}
|
||||
|
||||
dndResetDnodes(pDnode, pMgmt->dnodeEps);
|
||||
|
@ -335,7 +335,7 @@ static int32_t dndWriteDnodes(SDnode *pDnode) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void dndSendStatusMsg(SDnode *pDnode) {
|
||||
void dndSendStatusMsg(SDnode *pDnode) {
|
||||
int32_t contLen = sizeof(SStatusMsg) + TSDB_MAX_VNODES * sizeof(SVnodeLoad);
|
||||
|
||||
SStatusMsg *pStatus = rpcMallocCont(contLen);
|
||||
|
@ -349,7 +349,7 @@ static void dndSendStatusMsg(SDnode *pDnode) {
|
|||
pStatus->sver = htonl(pDnode->opt.sver);
|
||||
pStatus->dnodeId = htonl(pMgmt->dnodeId);
|
||||
pStatus->clusterId = htonl(pMgmt->clusterId);
|
||||
pStatus->rebootTime = htonl(pMgmt->rebootTime);
|
||||
pStatus->rebootTime = htobe64(pMgmt->rebootTime);
|
||||
pStatus->numOfCores = htons(pDnode->opt.numOfCores);
|
||||
pStatus->numOfSupportMnodes = htons(pDnode->opt.numOfCores);
|
||||
pStatus->numOfSupportVnodes = htons(pDnode->opt.numOfCores);
|
||||
|
@ -357,7 +357,6 @@ static void dndSendStatusMsg(SDnode *pDnode) {
|
|||
tstrncpy(pStatus->dnodeEp, pDnode->opt.localEp, TSDB_EP_LEN);
|
||||
|
||||
pStatus->clusterCfg.statusInterval = htonl(pDnode->opt.statusInterval);
|
||||
pStatus->clusterCfg.mnodeEqualVnodeNum = htonl(pDnode->opt.mnodeEqualVnodeNum);
|
||||
pStatus->clusterCfg.checkTime = 0;
|
||||
char timestr[32] = "1970-01-01 00:00:00.00";
|
||||
(void)taosParseTime(timestr, &pStatus->clusterCfg.checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0);
|
||||
|
@ -371,6 +370,9 @@ static void dndSendStatusMsg(SDnode *pDnode) {
|
|||
contLen = sizeof(SStatusMsg) + pStatus->vnodeLoads.num * sizeof(SVnodeLoad);
|
||||
|
||||
SRpcMsg rpcMsg = {.pCont = pStatus, .contLen = contLen, .msgType = TSDB_MSG_TYPE_STATUS};
|
||||
pMgmt->statusSent = 1;
|
||||
|
||||
dTrace("pDnode:%p, send status msg to mnode", pDnode);
|
||||
dndSendMsgToMnode(pDnode, &rpcMsg);
|
||||
}
|
||||
|
||||
|
@ -383,7 +385,7 @@ static void dndUpdateDnodeCfg(SDnode *pDnode, SDnodeCfg *pCfg) {
|
|||
pMgmt->dnodeId = pCfg->dnodeId;
|
||||
pMgmt->clusterId = pCfg->clusterId;
|
||||
pMgmt->dropped = pCfg->dropped;
|
||||
(void)dndWriteDnodes(pDnode);
|
||||
dndWriteDnodes(pDnode);
|
||||
taosWUnLockLatch(&pMgmt->latch);
|
||||
}
|
||||
}
|
||||
|
@ -409,11 +411,16 @@ static void dndUpdateDnodeEps(SDnode *pDnode, SDnodeEps *pDnodeEps) {
|
|||
}
|
||||
|
||||
static void dndProcessStatusRsp(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||
SDnodeMgmt *pMgmt = &pDnode->dmgmt;
|
||||
|
||||
if (pEpSet && pEpSet->numOfEps > 0) {
|
||||
dndUpdateMnodeEpSet(pDnode, pEpSet);
|
||||
}
|
||||
|
||||
if (pMsg->code != TSDB_CODE_SUCCESS) return;
|
||||
if (pMsg->code != TSDB_CODE_SUCCESS) {
|
||||
pMgmt->statusSent = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
SStatusRsp *pRsp = pMsg->pCont;
|
||||
SDnodeCfg *pCfg = &pRsp->dnodeCfg;
|
||||
|
@ -421,7 +428,10 @@ static void dndProcessStatusRsp(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|||
pCfg->clusterId = htonl(pCfg->clusterId);
|
||||
dndUpdateDnodeCfg(pDnode, pCfg);
|
||||
|
||||
if (pCfg->dropped) return;
|
||||
if (pCfg->dropped) {
|
||||
pMgmt->statusSent = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
SDnodeEps *pDnodeEps = &pRsp->dnodeEps;
|
||||
pDnodeEps->num = htonl(pDnodeEps->num);
|
||||
|
@ -431,6 +441,7 @@ static void dndProcessStatusRsp(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|||
}
|
||||
|
||||
dndUpdateDnodeEps(pDnode, pDnodeEps);
|
||||
pMgmt->statusSent = 0;
|
||||
}
|
||||
|
||||
static void dndProcessAuthRsp(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { assert(1); }
|
||||
|
@ -438,13 +449,12 @@ static void dndProcessAuthRsp(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { a
|
|||
static void dndProcessGrantRsp(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { assert(1); }
|
||||
|
||||
static void dndProcessConfigDnodeReq(SDnode *pDnode, SRpcMsg *pMsg) {
|
||||
dDebug("config msg is received");
|
||||
dError("config msg is received, but not supported yet");
|
||||
SCfgDnodeMsg *pCfg = pMsg->pCont;
|
||||
|
||||
int32_t code = TSDB_CODE_OPS_NOT_SUPPORT;
|
||||
SRpcMsg rspMsg = {.handle = pMsg->handle, .pCont = NULL, .contLen = 0, .code = code};
|
||||
rpcSendResponse(&rspMsg);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
}
|
||||
|
||||
static void dndProcessStartupReq(SDnode *pDnode, SRpcMsg *pMsg) {
|
||||
|
@ -457,18 +467,18 @@ static void dndProcessStartupReq(SDnode *pDnode, SRpcMsg *pMsg) {
|
|||
|
||||
SRpcMsg rpcRsp = {.handle = pMsg->handle, .pCont = pStartup, .contLen = sizeof(SStartupMsg)};
|
||||
rpcSendResponse(&rpcRsp);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
}
|
||||
|
||||
static void *dnodeThreadRoutine(void *param) {
|
||||
SDnode *pDnode = param;
|
||||
int32_t ms = pDnode->opt.statusInterval * 1000;
|
||||
SDnode *pDnode = param;
|
||||
SDnodeMgmt *pMgmt = &pDnode->dmgmt;
|
||||
int32_t ms = pDnode->opt.statusInterval * 1000;
|
||||
|
||||
while (true) {
|
||||
taosMsleep(ms);
|
||||
pthread_testcancel();
|
||||
taosMsleep(ms);
|
||||
|
||||
if (dndGetStat(pDnode) == DND_STAT_RUNNING) {
|
||||
if (dndGetStat(pDnode) == DND_STAT_RUNNING && !pMgmt->statusSent) {
|
||||
dndSendStatusMsg(pDnode);
|
||||
}
|
||||
}
|
||||
|
@ -478,7 +488,7 @@ int32_t dndInitDnode(SDnode *pDnode) {
|
|||
SDnodeMgmt *pMgmt = &pDnode->dmgmt;
|
||||
|
||||
pMgmt->dnodeId = 0;
|
||||
pMgmt->rebootTime = taosGetTimestampSec();
|
||||
pMgmt->rebootTime = taosGetTimestampMs();
|
||||
pMgmt->dropped = 0;
|
||||
pMgmt->clusterId = 0;
|
||||
|
||||
|
@ -556,8 +566,10 @@ void dndProcessDnodeReq(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|||
dError("RPC %p, dnode req:%s not processed", pMsg->handle, taosMsg[pMsg->msgType]);
|
||||
SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_MSG_NOT_PROCESSED};
|
||||
rpcSendResponse(&rspMsg);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
}
|
||||
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
pMsg->pCont = NULL;
|
||||
}
|
||||
|
||||
void dndProcessDnodeRsp(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||
|
@ -574,4 +586,7 @@ void dndProcessDnodeRsp(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|||
default:
|
||||
dError("RPC %p, dnode rsp:%s not processed", pMsg->handle, taosMsg[pMsg->msgType]);
|
||||
}
|
||||
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
pMsg->pCont = NULL;
|
||||
}
|
||||
|
|
|
@ -334,7 +334,6 @@ static void dndInitMnodeOption(SDnode *pDnode, SMnodeOpt *pOption) {
|
|||
pOption->cfg.sver = pDnode->opt.sver;
|
||||
pOption->cfg.enableTelem = pDnode->opt.enableTelem;
|
||||
pOption->cfg.statusInterval = pDnode->opt.statusInterval;
|
||||
pOption->cfg.mnodeEqualVnodeNum = pDnode->opt.mnodeEqualVnodeNum;
|
||||
pOption->cfg.shellActivityTimer = pDnode->opt.shellActivityTimer;
|
||||
pOption->cfg.timezone = pDnode->opt.timezone;
|
||||
pOption->cfg.charset = pDnode->opt.charset;
|
||||
|
@ -560,9 +559,12 @@ static void dndProcessMnodeMgmtQueue(SDnode *pDnode, SRpcMsg *pMsg) {
|
|||
break;
|
||||
}
|
||||
|
||||
SRpcMsg rsp = {.code = code, .handle = pMsg->handle};
|
||||
rpcSendResponse(&rsp);
|
||||
if (pMsg->msgType & 1u) {
|
||||
SRpcMsg rsp = {.code = code, .handle = pMsg->handle};
|
||||
rpcSendResponse(&rsp);
|
||||
}
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
pMsg->pCont = NULL;
|
||||
taosFreeQitem(pMsg);
|
||||
}
|
||||
|
||||
|
@ -646,9 +648,12 @@ void dndProcessMnodeMgmtMsg(SDnode *pDnode, SRpcMsg *pRpcMsg, SEpSet *pEpSet) {
|
|||
|
||||
SRpcMsg *pMsg = taosAllocateQitem(sizeof(SRpcMsg));
|
||||
if (pMsg == NULL || taosWriteQitem(pMgmt->pMgmtQ, pMsg) != 0) {
|
||||
SRpcMsg rsp = {.handle = pRpcMsg->handle, .code = TSDB_CODE_OUT_OF_MEMORY};
|
||||
rpcSendResponse(&rsp);
|
||||
if (pRpcMsg->msgType & 1u) {
|
||||
SRpcMsg rsp = {.handle = pRpcMsg->handle, .code = TSDB_CODE_OUT_OF_MEMORY};
|
||||
rpcSendResponse(&rsp);
|
||||
}
|
||||
rpcFreeCont(pRpcMsg->pCont);
|
||||
pRpcMsg->pCont = NULL;
|
||||
taosFreeQitem(pMsg);
|
||||
}
|
||||
}
|
||||
|
@ -657,9 +662,12 @@ void dndProcessMnodeWriteMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|||
SMnodeMgmt *pMgmt = &pDnode->mmgmt;
|
||||
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||
if (pMnode == NULL || dndWriteMnodeMsgToQueue(pMnode, pMgmt->pWriteQ, pMsg) != 0) {
|
||||
SRpcMsg rsp = {.handle = pMsg->handle, .code = terrno};
|
||||
rpcSendResponse(&rsp);
|
||||
if (pMsg->msgType & 1u) {
|
||||
SRpcMsg rsp = {.handle = pMsg->handle, .code = terrno};
|
||||
rpcSendResponse(&rsp);
|
||||
}
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
pMsg->pCont = NULL;
|
||||
}
|
||||
|
||||
dndReleaseMnode(pDnode, pMnode);
|
||||
|
@ -669,9 +677,12 @@ void dndProcessMnodeSyncMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|||
SMnodeMgmt *pMgmt = &pDnode->mmgmt;
|
||||
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||
if (pMnode == NULL || dndWriteMnodeMsgToQueue(pMnode, pMgmt->pSyncQ, pMsg) != 0) {
|
||||
SRpcMsg rsp = {.handle = pMsg->handle, .code = terrno};
|
||||
rpcSendResponse(&rsp);
|
||||
if (pMsg->msgType & 1u) {
|
||||
SRpcMsg rsp = {.handle = pMsg->handle, .code = terrno};
|
||||
rpcSendResponse(&rsp);
|
||||
}
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
pMsg->pCont = NULL;
|
||||
}
|
||||
|
||||
dndReleaseMnode(pDnode, pMnode);
|
||||
|
@ -681,9 +692,12 @@ void dndProcessMnodeReadMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|||
SMnodeMgmt *pMgmt = &pDnode->mmgmt;
|
||||
SMnode *pMnode = dndAcquireMnode(pDnode);
|
||||
if (pMnode == NULL || dndWriteMnodeMsgToQueue(pMnode, pMgmt->pReadQ, pMsg) != 0) {
|
||||
SRpcMsg rsp = {.handle = pMsg->handle, .code = terrno};
|
||||
rpcSendResponse(&rsp);
|
||||
if (pMsg->msgType & 1u) {
|
||||
SRpcMsg rsp = {.handle = pMsg->handle, .code = terrno};
|
||||
rpcSendResponse(&rsp);
|
||||
}
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
pMsg->pCont = NULL;
|
||||
}
|
||||
|
||||
dndReleaseMnode(pDnode, pMnode);
|
||||
|
|
|
@ -69,9 +69,9 @@ static void dndInitMsgFp(STransMgmt *pMgmt) {
|
|||
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_FUNCTION] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_RETRIEVE_FUNCTION] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_FUNCTION] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_STABLE] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_STABLE] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_STABLE] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_STB] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_STB] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_STB] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_VGROUP_LIST] = dndProcessMnodeReadMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_KILL_QUERY] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_KILL_STREAM] = dndProcessMnodeWriteMsg;
|
||||
|
@ -84,12 +84,12 @@ static void dndInitMsgFp(STransMgmt *pMgmt) {
|
|||
pMgmt->msgFp[TSDB_MSG_TYPE_NETWORK_TEST] = dndProcessDnodeReq;
|
||||
|
||||
// message from mnode to vnode
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_STABLE_IN] = dndProcessVnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_STABLE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_STABLE_IN] = dndProcessVnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_STABLE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_STABLE_IN] = dndProcessVnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_STABLE_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_STB_IN] = dndProcessVnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_STB_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_STB_IN] = dndProcessVnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_STB_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_STB_IN] = dndProcessVnodeWriteMsg;
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_DROP_STB_IN_RSP] = dndProcessMnodeWriteMsg;
|
||||
|
||||
// message from mnode to dnode
|
||||
pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_VNODE_IN] = dndProcessVnodeMgmtMsg;
|
||||
|
@ -130,7 +130,7 @@ static void dndProcessResponse(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|||
|
||||
if (dndGetStat(pDnode) == DND_STAT_STOPPED) {
|
||||
if (pMsg == NULL || pMsg->pCont == NULL) return;
|
||||
dTrace("RPC %p, rsp:%s app:%p is ignored since dnode is stopping", pMsg->handle, taosMsg[msgType], pMsg->ahandle);
|
||||
dTrace("RPC %p, rsp:%s is ignored since dnode is stopping", pMsg->handle, taosMsg[msgType]);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
return;
|
||||
}
|
||||
|
@ -138,12 +138,11 @@ static void dndProcessResponse(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|||
DndMsgFp fp = pMgmt->msgFp[msgType];
|
||||
if (fp != NULL) {
|
||||
(*fp)(pDnode, pMsg, pEpSet);
|
||||
dTrace("RPC %p, rsp:%s app:%p is processed, code:0x%0X", pMsg->handle, taosMsg[msgType], pMsg->ahandle,
|
||||
pMsg->code & 0XFFFF);
|
||||
dTrace("RPC %p, rsp:%s is processed, code:0x%0X", pMsg->handle, taosMsg[msgType], pMsg->code & 0XFFFF);
|
||||
} else {
|
||||
dError("RPC %p, rsp:%s app:%p not processed", pMsg->handle, taosMsg[msgType], pMsg->ahandle);
|
||||
dError("RPC %p, rsp:%s not processed", pMsg->handle, taosMsg[msgType]);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
}
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
}
|
||||
|
||||
static int32_t dndInitClient(SDnode *pDnode) {
|
||||
|
@ -236,18 +235,18 @@ static void dndSendMsgToMnodeRecv(SDnode *pDnode, SRpcMsg *pRpcMsg, SRpcMsg *pRp
|
|||
static int32_t dndAuthInternalMsg(SDnode *pDnode, char *user, char *spi, char *encrypt, char *secret, char *ckey) {
|
||||
if (strcmp(user, INTERNAL_USER) == 0) {
|
||||
// A simple temporary implementation
|
||||
char pass[32] = {0};
|
||||
char pass[TSDB_PASSWORD_LEN] = {0};
|
||||
taosEncryptPass((uint8_t *)(INTERNAL_SECRET), strlen(INTERNAL_SECRET), pass);
|
||||
memcpy(secret, pass, TSDB_KEY_LEN);
|
||||
memcpy(secret, pass, TSDB_PASSWORD_LEN);
|
||||
*spi = 0;
|
||||
*encrypt = 0;
|
||||
*ckey = 0;
|
||||
return 0;
|
||||
} else if (strcmp(user, TSDB_NETTEST_USER) == 0) {
|
||||
// A simple temporary implementation
|
||||
char pass[32] = {0};
|
||||
char pass[TSDB_PASSWORD_LEN] = {0};
|
||||
taosEncryptPass((uint8_t *)(TSDB_NETTEST_USER), strlen(TSDB_NETTEST_USER), pass);
|
||||
memcpy(secret, pass, TSDB_KEY_LEN);
|
||||
memcpy(secret, pass, TSDB_PASSWORD_LEN);
|
||||
*spi = 0;
|
||||
*encrypt = 0;
|
||||
*ckey = 0;
|
||||
|
@ -289,8 +288,8 @@ static int32_t dndRetrieveUserAuthInfo(void *parent, char *user, char *spi, char
|
|||
dError("user:%s, failed to get user auth from other mnodes since %s", user, terrstr());
|
||||
} else {
|
||||
SAuthRsp *pRsp = rpcRsp.pCont;
|
||||
memcpy(secret, pRsp->secret, TSDB_KEY_LEN);
|
||||
memcpy(ckey, pRsp->ckey, TSDB_KEY_LEN);
|
||||
memcpy(secret, pRsp->secret, TSDB_PASSWORD_LEN);
|
||||
memcpy(ckey, pRsp->ckey, TSDB_PASSWORD_LEN);
|
||||
*spi = pRsp->spi;
|
||||
*encrypt = pRsp->encrypt;
|
||||
dDebug("user:%s, success to get user auth from other mnodes", user);
|
||||
|
@ -369,4 +368,4 @@ void dndSendMsgToMnode(SDnode *pDnode, SRpcMsg *pMsg) {
|
|||
SEpSet epSet = {0};
|
||||
dndGetMnodeEpSet(pDnode, &epSet);
|
||||
dndSendMsgToDnode(pDnode, &epSet, pMsg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,30 +55,31 @@ void dndGetStartup(SDnode *pDnode, SStartupMsg *pStartup) {
|
|||
pStartup->finished = (dndGetStat(pDnode) == DND_STAT_RUNNING);
|
||||
}
|
||||
|
||||
static int32_t dndCheckRunning(char *dataDir) {
|
||||
static FileFd dndCheckRunning(char *dataDir) {
|
||||
char filepath[PATH_MAX] = {0};
|
||||
snprintf(filepath, sizeof(filepath), "%s/.running", dataDir);
|
||||
|
||||
FileFd fd = taosOpenFileCreateWriteTrunc(filepath);
|
||||
if (fd < 0) {
|
||||
dError("failed to lock file:%s since %s, quit", filepath, strerror(errno));
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to lock file:%s since %s, quit", filepath, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t ret = taosLockFile(fd);
|
||||
if (ret != 0) {
|
||||
dError("failed to lock file:%s since %s, quit", filepath, strerror(errno));
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to lock file:%s since %s, quit", filepath, terrstr());
|
||||
taosCloseFile(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int32_t dndInitEnv(SDnode *pDnode, SDnodeOpt *pOption) {
|
||||
if (dndCheckRunning(pOption->dataDir) != 0) {
|
||||
pDnode->lockFd = dndCheckRunning(pOption->dataDir);
|
||||
if (pDnode->lockFd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -133,6 +134,12 @@ static void dndCleanupEnv(SDnode *pDnode) {
|
|||
tfree(pDnode->dir.dnode);
|
||||
}
|
||||
|
||||
if (pDnode->lockFd >= 0) {
|
||||
taosUnLockFile(pDnode->lockFd);
|
||||
taosCloseFile(pDnode->lockFd);
|
||||
pDnode->lockFd = 0;
|
||||
}
|
||||
|
||||
taosStopCacheRefreshWorker();
|
||||
}
|
||||
|
||||
|
@ -194,13 +201,16 @@ SDnode *dndInit(SDnodeOpt *pOption) {
|
|||
}
|
||||
|
||||
dndSetStat(pDnode, DND_STAT_RUNNING);
|
||||
dndSendStatusMsg(pDnode);
|
||||
dndReportStartup(pDnode, "TDengine", "initialized successfully");
|
||||
dInfo("TDengine is initialized successfully");
|
||||
dInfo("TDengine is initialized successfully, pDnode:%p", pDnode);
|
||||
|
||||
return pDnode;
|
||||
}
|
||||
|
||||
void dndCleanup(SDnode *pDnode) {
|
||||
if (pDnode == NULL) return;
|
||||
|
||||
if (dndGetStat(pDnode) == DND_STAT_STOPPED) {
|
||||
dError("dnode is shutting down");
|
||||
return;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# add_subdirectory(acct)
|
||||
# add_subdirectory(cluster)
|
||||
add_subdirectory(dnode)
|
||||
# add_subdirectory(profile)
|
||||
# add_subdirectory(show)
|
||||
add_subdirectory(user)
|
||||
|
|
|
@ -33,7 +33,7 @@ class DndTestAcct : public ::testing::Test {
|
|||
}
|
||||
|
||||
static void TearDownTestSuite() {
|
||||
dropServer(pServer);
|
||||
stopServer(pServer);
|
||||
dropClient(pClient);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ class DndTestCluster : public ::testing::Test {
|
|||
}
|
||||
|
||||
static void TearDownTestSuite() {
|
||||
dropServer(pServer);
|
||||
stopServer(pServer);
|
||||
dropClient(pClient);
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ TEST_F(DndTestCluster, ShowCluster) {
|
|||
|
||||
EXPECT_NE(pRsp->showId, 0);
|
||||
EXPECT_EQ(pMeta->contLen, 0);
|
||||
EXPECT_STREQ(pMeta->tableFname, "show cluster");
|
||||
EXPECT_STREQ(pMeta->tbFname, "show cluster");
|
||||
EXPECT_EQ(pMeta->numOfTags, 0);
|
||||
EXPECT_EQ(pMeta->precision, 0);
|
||||
EXPECT_EQ(pMeta->tableType, 0);
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
add_executable(dndTestDnode "")
|
||||
|
||||
target_sources(dndTestDnode
|
||||
PRIVATE
|
||||
"dnode.cpp"
|
||||
"../sut/deploy.cpp"
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
dndTestDnode
|
||||
PUBLIC dnode
|
||||
PUBLIC util
|
||||
PUBLIC os
|
||||
PUBLIC gtest_main
|
||||
)
|
||||
|
||||
target_include_directories(dndTestDnode
|
||||
PUBLIC
|
||||
"${CMAKE_SOURCE_DIR}/include/server/dnode/mgmt"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../inc"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../sut"
|
||||
)
|
||||
|
||||
enable_testing()
|
||||
|
||||
add_test(
|
||||
NAME dndTestDnode
|
||||
COMMAND dndTestDnode
|
||||
)
|
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
* 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 "deploy.h"
|
||||
|
||||
class DndTestDnode : public ::testing::Test {
|
||||
public:
|
||||
static SServer* CreateServer(const char* path, const char* fqdn, uint16_t port, const char* firstEp) {
|
||||
SServer* pServer = createServer(path, fqdn, port, firstEp);
|
||||
ASSERT(pServer);
|
||||
return pServer;
|
||||
}
|
||||
|
||||
static void SetUpTestSuite() {
|
||||
initLog("/tmp/dndTestDnode");
|
||||
|
||||
const char* fqdn = "localhost";
|
||||
const char* firstEp = "localhost:9521";
|
||||
pServer1 = CreateServer("/tmp/dndTestDnode1", fqdn, 9521, firstEp);
|
||||
pServer2 = CreateServer("/tmp/dndTestDnode2", fqdn, 9522, firstEp);
|
||||
pServer3 = CreateServer("/tmp/dndTestDnode3", fqdn, 9523, firstEp);
|
||||
pServer4 = CreateServer("/tmp/dndTestDnode4", fqdn, 9524, firstEp);
|
||||
pServer5 = CreateServer("/tmp/dndTestDnode5", fqdn, 9525, firstEp);
|
||||
pClient = createClient("root", "taosdata", fqdn, 9521);
|
||||
taosMsleep(300);
|
||||
}
|
||||
|
||||
static void TearDownTestSuite() {
|
||||
stopServer(pServer1);
|
||||
stopServer(pServer2);
|
||||
stopServer(pServer3);
|
||||
stopServer(pServer4);
|
||||
stopServer(pServer5);
|
||||
dropClient(pClient);
|
||||
pServer1 = NULL;
|
||||
pServer2 = NULL;
|
||||
pServer3 = NULL;
|
||||
pServer4 = NULL;
|
||||
pServer5 = NULL;
|
||||
pClient = NULL;
|
||||
}
|
||||
|
||||
static SServer* pServer1;
|
||||
static SServer* pServer2;
|
||||
static SServer* pServer3;
|
||||
static SServer* pServer4;
|
||||
static SServer* pServer5;
|
||||
static SClient* pClient;
|
||||
|
||||
public:
|
||||
void SetUp() override {}
|
||||
void TearDown() override {}
|
||||
|
||||
void SendTheCheckShowMetaMsg(int8_t showType, const char* showName, int32_t columns) {
|
||||
SShowMsg* pShow = (SShowMsg*)rpcMallocCont(sizeof(SShowMsg));
|
||||
pShow->type = showType;
|
||||
strcpy(pShow->db, "");
|
||||
|
||||
SRpcMsg showRpcMsg = {0};
|
||||
showRpcMsg.pCont = pShow;
|
||||
showRpcMsg.contLen = sizeof(SShowMsg);
|
||||
showRpcMsg.msgType = TSDB_MSG_TYPE_SHOW;
|
||||
|
||||
sendMsg(pClient, &showRpcMsg);
|
||||
ASSERT_NE(pClient->pRsp, nullptr);
|
||||
ASSERT_EQ(pClient->pRsp->code, 0);
|
||||
ASSERT_NE(pClient->pRsp->pCont, nullptr);
|
||||
|
||||
SShowRsp* pShowRsp = (SShowRsp*)pClient->pRsp->pCont;
|
||||
ASSERT_NE(pShowRsp, nullptr);
|
||||
pShowRsp->showId = htonl(pShowRsp->showId);
|
||||
pMeta = &pShowRsp->tableMeta;
|
||||
pMeta->numOfTags = htons(pMeta->numOfTags);
|
||||
pMeta->numOfColumns = htons(pMeta->numOfColumns);
|
||||
pMeta->sversion = htons(pMeta->sversion);
|
||||
pMeta->tversion = htons(pMeta->tversion);
|
||||
pMeta->tuid = htobe64(pMeta->tuid);
|
||||
pMeta->suid = htobe64(pMeta->suid);
|
||||
|
||||
showId = pShowRsp->showId;
|
||||
|
||||
EXPECT_NE(pShowRsp->showId, 0);
|
||||
EXPECT_STREQ(pMeta->tbFname, showName);
|
||||
EXPECT_EQ(pMeta->numOfTags, 0);
|
||||
EXPECT_EQ(pMeta->numOfColumns, columns);
|
||||
EXPECT_EQ(pMeta->precision, 0);
|
||||
EXPECT_EQ(pMeta->tableType, 0);
|
||||
EXPECT_EQ(pMeta->update, 0);
|
||||
EXPECT_EQ(pMeta->sversion, 0);
|
||||
EXPECT_EQ(pMeta->tversion, 0);
|
||||
EXPECT_EQ(pMeta->tuid, 0);
|
||||
EXPECT_EQ(pMeta->suid, 0);
|
||||
}
|
||||
|
||||
void CheckSchema(int32_t index, int8_t type, int32_t bytes, const char* name) {
|
||||
SSchema* pSchema = &pMeta->pSchema[index];
|
||||
pSchema->bytes = htons(pSchema->bytes);
|
||||
EXPECT_EQ(pSchema->colId, 0);
|
||||
EXPECT_EQ(pSchema->type, type);
|
||||
EXPECT_EQ(pSchema->bytes, bytes);
|
||||
EXPECT_STREQ(pSchema->name, name);
|
||||
}
|
||||
|
||||
void SendThenCheckShowRetrieveMsg(int32_t rows) {
|
||||
SRetrieveTableMsg* pRetrieve = (SRetrieveTableMsg*)rpcMallocCont(sizeof(SRetrieveTableMsg));
|
||||
pRetrieve->showId = htonl(showId);
|
||||
pRetrieve->free = 0;
|
||||
|
||||
SRpcMsg retrieveRpcMsg = {0};
|
||||
retrieveRpcMsg.pCont = pRetrieve;
|
||||
retrieveRpcMsg.contLen = sizeof(SRetrieveTableMsg);
|
||||
retrieveRpcMsg.msgType = TSDB_MSG_TYPE_SHOW_RETRIEVE;
|
||||
|
||||
sendMsg(pClient, &retrieveRpcMsg);
|
||||
|
||||
ASSERT_NE(pClient->pRsp, nullptr);
|
||||
ASSERT_EQ(pClient->pRsp->code, 0);
|
||||
ASSERT_NE(pClient->pRsp->pCont, nullptr);
|
||||
|
||||
pRetrieveRsp = (SRetrieveTableRsp*)pClient->pRsp->pCont;
|
||||
ASSERT_NE(pRetrieveRsp, nullptr);
|
||||
pRetrieveRsp->numOfRows = htonl(pRetrieveRsp->numOfRows);
|
||||
pRetrieveRsp->offset = htobe64(pRetrieveRsp->offset);
|
||||
pRetrieveRsp->useconds = htobe64(pRetrieveRsp->useconds);
|
||||
pRetrieveRsp->compLen = htonl(pRetrieveRsp->compLen);
|
||||
|
||||
EXPECT_EQ(pRetrieveRsp->numOfRows, rows);
|
||||
EXPECT_EQ(pRetrieveRsp->offset, 0);
|
||||
EXPECT_EQ(pRetrieveRsp->useconds, 0);
|
||||
// EXPECT_EQ(pRetrieveRsp->completed, completed);
|
||||
EXPECT_EQ(pRetrieveRsp->precision, TSDB_TIME_PRECISION_MILLI);
|
||||
EXPECT_EQ(pRetrieveRsp->compressed, 0);
|
||||
EXPECT_EQ(pRetrieveRsp->reserved, 0);
|
||||
EXPECT_EQ(pRetrieveRsp->compLen, 0);
|
||||
|
||||
pData = pRetrieveRsp->data;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
void CheckInt16(int16_t val) {
|
||||
int16_t data = *((int16_t*)(pData + pos));
|
||||
pos += sizeof(int16_t);
|
||||
EXPECT_EQ(data, val);
|
||||
}
|
||||
|
||||
void CheckInt64(int64_t val) {
|
||||
int64_t data = *((int64_t*)(pData + pos));
|
||||
pos += sizeof(int64_t);
|
||||
EXPECT_EQ(data, val);
|
||||
}
|
||||
|
||||
void CheckTimestamp() {
|
||||
int64_t data = *((int64_t*)(pData + pos));
|
||||
pos += sizeof(int64_t);
|
||||
EXPECT_GT(data, 0);
|
||||
}
|
||||
|
||||
void CheckBinary(const char* val, int32_t len) {
|
||||
pos += sizeof(VarDataLenT);
|
||||
char* data = (char*)(pData + pos);
|
||||
pos += len;
|
||||
EXPECT_STREQ(data, val);
|
||||
}
|
||||
|
||||
int32_t showId;
|
||||
STableMetaMsg* pMeta;
|
||||
SRetrieveTableRsp* pRetrieveRsp;
|
||||
char* pData;
|
||||
int32_t pos;
|
||||
};
|
||||
|
||||
SServer* DndTestDnode::pServer1;
|
||||
SServer* DndTestDnode::pServer2;
|
||||
SServer* DndTestDnode::pServer3;
|
||||
SServer* DndTestDnode::pServer4;
|
||||
SServer* DndTestDnode::pServer5;
|
||||
SClient* DndTestDnode::pClient;
|
||||
|
||||
TEST_F(DndTestDnode, ShowDnode) {
|
||||
SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DNODE, "show dnodes", 7);
|
||||
CheckSchema(0, TSDB_DATA_TYPE_SMALLINT, 2, "id");
|
||||
CheckSchema(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "end point");
|
||||
CheckSchema(2, TSDB_DATA_TYPE_SMALLINT, 2, "vnodes");
|
||||
CheckSchema(3, TSDB_DATA_TYPE_SMALLINT, 2, "max vnodes");
|
||||
CheckSchema(4, TSDB_DATA_TYPE_BINARY, 10 + VARSTR_HEADER_SIZE, "status");
|
||||
CheckSchema(5, TSDB_DATA_TYPE_TIMESTAMP, 8, "create time");
|
||||
CheckSchema(6, TSDB_DATA_TYPE_BINARY, 24 + VARSTR_HEADER_SIZE, "offline reason");
|
||||
|
||||
SendThenCheckShowRetrieveMsg(1);
|
||||
CheckInt16(1);
|
||||
CheckBinary("localhost:9521", TSDB_EP_LEN);
|
||||
CheckInt16(0);
|
||||
CheckInt16(1);
|
||||
CheckBinary("ready", 10);
|
||||
CheckTimestamp();
|
||||
CheckBinary("", 24);
|
||||
}
|
||||
|
||||
TEST_F(DndTestDnode, ConfigDnode_01) {
|
||||
SCfgDnodeMsg* pReq = (SCfgDnodeMsg*)rpcMallocCont(sizeof(SCfgDnodeMsg));
|
||||
pReq->dnodeId = htonl(1);
|
||||
strcpy(pReq->config, "ddebugflag 131");
|
||||
|
||||
SRpcMsg rpcMsg = {0};
|
||||
rpcMsg.pCont = pReq;
|
||||
rpcMsg.contLen = sizeof(SCfgDnodeMsg);
|
||||
rpcMsg.msgType = TSDB_MSG_TYPE_CONFIG_DNODE;
|
||||
|
||||
sendMsg(pClient, &rpcMsg);
|
||||
SRpcMsg* pMsg = pClient->pRsp;
|
||||
ASSERT_NE(pMsg, nullptr);
|
||||
ASSERT_EQ(pMsg->code, 0);
|
||||
}
|
||||
|
||||
TEST_F(DndTestDnode, CreateDnode_01) {
|
||||
SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(sizeof(SCreateDnodeMsg));
|
||||
strcpy(pReq->ep, "localhost:9522");
|
||||
|
||||
SRpcMsg rpcMsg = {0};
|
||||
rpcMsg.pCont = pReq;
|
||||
rpcMsg.contLen = sizeof(SCreateDnodeMsg);
|
||||
rpcMsg.msgType = TSDB_MSG_TYPE_CREATE_DNODE;
|
||||
|
||||
sendMsg(pClient, &rpcMsg);
|
||||
SRpcMsg* pMsg = pClient->pRsp;
|
||||
ASSERT_NE(pMsg, nullptr);
|
||||
ASSERT_EQ(pMsg->code, 0);
|
||||
|
||||
taosMsleep(1300);
|
||||
SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DNODE, "show dnodes", 7);
|
||||
SendThenCheckShowRetrieveMsg(2);
|
||||
CheckInt16(1);
|
||||
CheckInt16(2);
|
||||
CheckBinary("localhost:9521", TSDB_EP_LEN);
|
||||
CheckBinary("localhost:9522", TSDB_EP_LEN);
|
||||
CheckInt16(0);
|
||||
CheckInt16(0);
|
||||
CheckInt16(1);
|
||||
CheckInt16(1);
|
||||
CheckBinary("ready", 10);
|
||||
CheckBinary("ready", 10);
|
||||
CheckTimestamp();
|
||||
CheckTimestamp();
|
||||
CheckBinary("", 24);
|
||||
CheckBinary("", 24);
|
||||
}
|
||||
|
||||
TEST_F(DndTestDnode, DropDnode_01) {
|
||||
SDropDnodeMsg* pReq = (SDropDnodeMsg*)rpcMallocCont(sizeof(SDropDnodeMsg));
|
||||
pReq->dnodeId = htonl(2);
|
||||
|
||||
SRpcMsg rpcMsg = {0};
|
||||
rpcMsg.pCont = pReq;
|
||||
rpcMsg.contLen = sizeof(SDropDnodeMsg);
|
||||
rpcMsg.msgType = TSDB_MSG_TYPE_DROP_DNODE;
|
||||
|
||||
sendMsg(pClient, &rpcMsg);
|
||||
SRpcMsg* pMsg = pClient->pRsp;
|
||||
ASSERT_NE(pMsg, nullptr);
|
||||
ASSERT_EQ(pMsg->code, 0);
|
||||
|
||||
SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DNODE, "show dnodes", 7);
|
||||
SendThenCheckShowRetrieveMsg(1);
|
||||
CheckInt16(1);
|
||||
CheckBinary("localhost:9521", TSDB_EP_LEN);
|
||||
CheckInt16(0);
|
||||
CheckInt16(1);
|
||||
CheckBinary("ready", 10);
|
||||
CheckTimestamp();
|
||||
CheckBinary("", 24);
|
||||
}
|
||||
|
||||
TEST_F(DndTestDnode, CreateDnode_02) {
|
||||
{
|
||||
SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(sizeof(SCreateDnodeMsg));
|
||||
strcpy(pReq->ep, "localhost:9523");
|
||||
|
||||
SRpcMsg rpcMsg = {0};
|
||||
rpcMsg.pCont = pReq;
|
||||
rpcMsg.contLen = sizeof(SCreateDnodeMsg);
|
||||
rpcMsg.msgType = TSDB_MSG_TYPE_CREATE_DNODE;
|
||||
|
||||
sendMsg(pClient, &rpcMsg);
|
||||
SRpcMsg* pMsg = pClient->pRsp;
|
||||
ASSERT_NE(pMsg, nullptr);
|
||||
ASSERT_EQ(pMsg->code, 0);
|
||||
}
|
||||
|
||||
{
|
||||
SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(sizeof(SCreateDnodeMsg));
|
||||
strcpy(pReq->ep, "localhost:9524");
|
||||
|
||||
SRpcMsg rpcMsg = {0};
|
||||
rpcMsg.pCont = pReq;
|
||||
rpcMsg.contLen = sizeof(SCreateDnodeMsg);
|
||||
rpcMsg.msgType = TSDB_MSG_TYPE_CREATE_DNODE;
|
||||
|
||||
sendMsg(pClient, &rpcMsg);
|
||||
SRpcMsg* pMsg = pClient->pRsp;
|
||||
ASSERT_NE(pMsg, nullptr);
|
||||
ASSERT_EQ(pMsg->code, 0);
|
||||
}
|
||||
|
||||
{
|
||||
SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(sizeof(SCreateDnodeMsg));
|
||||
strcpy(pReq->ep, "localhost:9525");
|
||||
|
||||
SRpcMsg rpcMsg = {0};
|
||||
rpcMsg.pCont = pReq;
|
||||
rpcMsg.contLen = sizeof(SCreateDnodeMsg);
|
||||
rpcMsg.msgType = TSDB_MSG_TYPE_CREATE_DNODE;
|
||||
|
||||
sendMsg(pClient, &rpcMsg);
|
||||
SRpcMsg* pMsg = pClient->pRsp;
|
||||
ASSERT_NE(pMsg, nullptr);
|
||||
ASSERT_EQ(pMsg->code, 0);
|
||||
}
|
||||
|
||||
taosMsleep(1300);
|
||||
SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DNODE, "show dnodes", 7);
|
||||
SendThenCheckShowRetrieveMsg(4);
|
||||
CheckInt16(1);
|
||||
CheckInt16(3);
|
||||
CheckInt16(4);
|
||||
CheckInt16(5);
|
||||
CheckBinary("localhost:9521", TSDB_EP_LEN);
|
||||
CheckBinary("localhost:9523", TSDB_EP_LEN);
|
||||
CheckBinary("localhost:9524", TSDB_EP_LEN);
|
||||
CheckBinary("localhost:9525", TSDB_EP_LEN);
|
||||
CheckInt16(0);
|
||||
CheckInt16(0);
|
||||
CheckInt16(0);
|
||||
CheckInt16(0);
|
||||
CheckInt16(1);
|
||||
CheckInt16(1);
|
||||
CheckInt16(1);
|
||||
CheckInt16(1);
|
||||
CheckBinary("ready", 10);
|
||||
CheckBinary("ready", 10);
|
||||
CheckBinary("ready", 10);
|
||||
CheckBinary("ready", 10);
|
||||
CheckTimestamp();
|
||||
CheckTimestamp();
|
||||
CheckTimestamp();
|
||||
CheckTimestamp();
|
||||
CheckBinary("", 24);
|
||||
CheckBinary("", 24);
|
||||
CheckBinary("", 24);
|
||||
CheckBinary("", 24);
|
||||
}
|
||||
|
||||
TEST_F(DndTestDnode, RestartDnode_01) {
|
||||
uInfo("stop all server");
|
||||
stopServer(pServer1);
|
||||
stopServer(pServer2);
|
||||
stopServer(pServer3);
|
||||
stopServer(pServer4);
|
||||
stopServer(pServer5);
|
||||
pServer1 = NULL;
|
||||
pServer2 = NULL;
|
||||
pServer3 = NULL;
|
||||
pServer4 = NULL;
|
||||
pServer5 = NULL;
|
||||
|
||||
uInfo("start all server");
|
||||
|
||||
const char* fqdn = "localhost";
|
||||
const char* firstEp = "localhost:9521";
|
||||
pServer1 = startServer("/tmp/dndTestDnode1", fqdn, 9521, firstEp);
|
||||
// pServer1 = startServer("/tmp/dndTestDnode3", fqdn, 9523, firstEp);
|
||||
// pServer1 = startServer("/tmp/dndTestDnode4", fqdn, 9524, firstEp);
|
||||
// pServer1 = startServer("/tmp/dndTestDnode5", fqdn, 9525, firstEp);
|
||||
|
||||
uInfo("all server is running");
|
||||
|
||||
// taosMsleep(1300);
|
||||
// SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DNODE, "show dnodes", 7);
|
||||
// SendThenCheckShowRetrieveMsg(4);
|
||||
// CheckInt16(1);
|
||||
// CheckInt16(3);
|
||||
// CheckInt16(4);
|
||||
// CheckInt16(5);
|
||||
// CheckBinary("localhost:9521", TSDB_EP_LEN);
|
||||
// CheckBinary("localhost:9523", TSDB_EP_LEN);
|
||||
// CheckBinary("localhost:9524", TSDB_EP_LEN);
|
||||
// CheckBinary("localhost:9525", TSDB_EP_LEN);
|
||||
// CheckInt16(0);
|
||||
// CheckInt16(0);
|
||||
// CheckInt16(0);
|
||||
// CheckInt16(0);
|
||||
// CheckInt16(1);
|
||||
// CheckInt16(1);
|
||||
// CheckInt16(1);
|
||||
// CheckInt16(1);
|
||||
// CheckBinary("ready", 10);
|
||||
// CheckBinary("ready", 10);
|
||||
// CheckBinary("ready", 10);
|
||||
// CheckBinary("ready", 10);
|
||||
// CheckTimestamp();
|
||||
// CheckTimestamp();
|
||||
// CheckTimestamp();
|
||||
// CheckTimestamp();
|
||||
// CheckBinary("", 24);
|
||||
// CheckBinary("", 24);
|
||||
// CheckBinary("", 24);
|
||||
// CheckBinary("", 24);
|
||||
}
|
|
@ -33,7 +33,7 @@ class DndTestProfile : public ::testing::Test {
|
|||
}
|
||||
|
||||
static void TearDownTestSuite() {
|
||||
dropServer(pServer);
|
||||
stopServer(pServer);
|
||||
dropClient(pClient);
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ TEST_F(DndTestProfile, SConnectMsg_03) {
|
|||
|
||||
EXPECT_NE(pRsp->showId, 0);
|
||||
EXPECT_EQ(pMeta->contLen, 0);
|
||||
EXPECT_STREQ(pMeta->tableFname, "");
|
||||
EXPECT_STREQ(pMeta->tbFname, "");
|
||||
EXPECT_EQ(pMeta->numOfTags, 0);
|
||||
EXPECT_EQ(pMeta->precision, 0);
|
||||
EXPECT_EQ(pMeta->tableType, 0);
|
||||
|
@ -480,7 +480,7 @@ TEST_F(DndTestProfile, SKillQueryMsg_03) {
|
|||
|
||||
EXPECT_NE(pRsp->showId, 0);
|
||||
EXPECT_EQ(pMeta->contLen, 0);
|
||||
EXPECT_STREQ(pMeta->tableFname, "");
|
||||
EXPECT_STREQ(pMeta->tbFname, "");
|
||||
EXPECT_EQ(pMeta->numOfTags, 0);
|
||||
EXPECT_EQ(pMeta->precision, 0);
|
||||
EXPECT_EQ(pMeta->tableType, 0);
|
||||
|
@ -667,7 +667,7 @@ TEST_F(DndTestProfile, SKillStreamMsg_03) {
|
|||
|
||||
EXPECT_NE(pRsp->showId, 0);
|
||||
EXPECT_EQ(pMeta->contLen, 0);
|
||||
EXPECT_STREQ(pMeta->tableFname, "");
|
||||
EXPECT_STREQ(pMeta->tbFname, "");
|
||||
EXPECT_EQ(pMeta->numOfTags, 0);
|
||||
EXPECT_EQ(pMeta->precision, 0);
|
||||
EXPECT_EQ(pMeta->tableType, 0);
|
||||
|
|
|
@ -33,7 +33,7 @@ class DndTestShow : public ::testing::Test {
|
|||
}
|
||||
|
||||
static void TearDownTestSuite() {
|
||||
dropServer(pServer);
|
||||
stopServer(pServer);
|
||||
dropClient(pClient);
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ TEST_F(DndTestShow, SShowMsg_04) {
|
|||
|
||||
EXPECT_NE(pRsp->showId, 0);
|
||||
EXPECT_EQ(pMeta->contLen, 0);
|
||||
EXPECT_STREQ(pMeta->tableFname, "");
|
||||
EXPECT_STREQ(pMeta->tbFname, "");
|
||||
EXPECT_EQ(pMeta->numOfTags, 0);
|
||||
EXPECT_EQ(pMeta->precision, 0);
|
||||
EXPECT_EQ(pMeta->tableType, 0);
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
#include "deploy.h"
|
||||
|
||||
void initLog(const char* path) {
|
||||
dDebugFlag = 0;
|
||||
dDebugFlag = 143;
|
||||
vDebugFlag = 0;
|
||||
mDebugFlag = 207;
|
||||
mDebugFlag = 143;
|
||||
cDebugFlag = 0;
|
||||
jniDebugFlag = 0;
|
||||
tmrDebugFlag = 0;
|
||||
|
@ -26,7 +26,7 @@ void initLog(const char* path) {
|
|||
httpDebugFlag = 0;
|
||||
mqttDebugFlag = 0;
|
||||
monDebugFlag = 0;
|
||||
uDebugFlag = 0;
|
||||
uDebugFlag = 143;
|
||||
rpcDebugFlag = 0;
|
||||
odbcDebugFlag = 0;
|
||||
qDebugFlag = 0;
|
||||
|
@ -34,6 +34,10 @@ void initLog(const char* path) {
|
|||
sDebugFlag = 0;
|
||||
tsdbDebugFlag = 0;
|
||||
cqDebugFlag = 0;
|
||||
tscEmbeddedInUtil = 1;
|
||||
|
||||
taosRemoveDir(path);
|
||||
taosMkDir(path);
|
||||
|
||||
char temp[PATH_MAX];
|
||||
snprintf(temp, PATH_MAX, "%s/taosdlog", path);
|
||||
|
@ -50,14 +54,13 @@ void* runServer(void* param) {
|
|||
}
|
||||
}
|
||||
|
||||
void initOption(SDnodeOpt* pOption, const char* path, const char* fqdn, uint16_t port) {
|
||||
void initOption(SDnodeOpt* pOption, const char* path, const char* fqdn, uint16_t port, const char* firstEp) {
|
||||
pOption->sver = 1;
|
||||
pOption->numOfCores = 1;
|
||||
pOption->numOfSupportMnodes = 1;
|
||||
pOption->numOfSupportVnodes = 1;
|
||||
pOption->numOfSupportQnodes = 1;
|
||||
pOption->statusInterval = 1;
|
||||
pOption->mnodeEqualVnodeNum = 1;
|
||||
pOption->numOfThreadsPerCore = 1;
|
||||
pOption->ratioOfQueryCores = 1;
|
||||
pOption->maxShellConns = 1000;
|
||||
|
@ -66,16 +69,14 @@ void initOption(SDnodeOpt* pOption, const char* path, const char* fqdn, uint16_t
|
|||
strcpy(pOption->dataDir, path);
|
||||
snprintf(pOption->localEp, TSDB_EP_LEN, "%s:%u", fqdn, port);
|
||||
snprintf(pOption->localFqdn, TSDB_FQDN_LEN, "%s", fqdn);
|
||||
snprintf(pOption->firstEp, TSDB_EP_LEN, "%s:%u", fqdn, port);
|
||||
snprintf(pOption->firstEp, TSDB_EP_LEN, "%s", firstEp);
|
||||
}
|
||||
|
||||
SServer* createServer(const char* path, const char* fqdn, uint16_t port) {
|
||||
taosRemoveDir(path);
|
||||
SServer* startServer(const char* path, const char* fqdn, uint16_t port, const char* firstEp) {
|
||||
taosMkDir(path);
|
||||
initLog(path);
|
||||
|
||||
SDnodeOpt option = {0};
|
||||
initOption(&option, path, fqdn, port);
|
||||
initOption(&option, path, fqdn, port, firstEp);
|
||||
|
||||
SDnode* pDnode = dndInit(&option);
|
||||
ASSERT(pDnode);
|
||||
|
@ -90,16 +91,28 @@ SServer* createServer(const char* path, const char* fqdn, uint16_t port) {
|
|||
return pServer;
|
||||
}
|
||||
|
||||
void dropServer(SServer* pServer) {
|
||||
SServer* createServer(const char* path, const char* fqdn, uint16_t port, const char* firstEp) {
|
||||
taosRemoveDir(path);
|
||||
return startServer(path, fqdn, port, firstEp);
|
||||
}
|
||||
|
||||
void stopServer(SServer* pServer) {
|
||||
if (pServer == NULL) return;
|
||||
if (pServer->threadId != NULL) {
|
||||
taosDestoryThread(pServer->threadId);
|
||||
}
|
||||
|
||||
if (pServer->pDnode != NULL) {
|
||||
dndCleanup(pServer->pDnode);
|
||||
pServer->pDnode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void processClientRsp(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) {
|
||||
SClient* pClient = (SClient*)parent;
|
||||
pClient->pRsp = pMsg;
|
||||
// taosMsleep(1000000);
|
||||
uInfo("response:%s from dnode, pCont:%p contLen:%d code:0x%X", taosMsg[pMsg->msgType], pMsg->pCont, pMsg->contLen,
|
||||
pMsg->code);
|
||||
tsem_post(&pClient->sem);
|
||||
}
|
||||
|
||||
|
@ -107,7 +120,7 @@ SClient* createClient(const char* user, const char* pass, const char* fqdn, uint
|
|||
SClient* pClient = (SClient*)calloc(1, sizeof(SClient));
|
||||
ASSERT(pClient);
|
||||
|
||||
char secretEncrypt[32] = {0};
|
||||
char secretEncrypt[TSDB_PASSWORD_LEN] = {0};
|
||||
taosEncryptPass((uint8_t*)pass, strlen(pass), secretEncrypt);
|
||||
|
||||
SRpcInit rpcInit;
|
||||
|
@ -145,7 +158,7 @@ void sendMsg(SClient* pClient, SRpcMsg* pMsg) {
|
|||
epSet.inUse = 0;
|
||||
epSet.numOfEps = 1;
|
||||
epSet.port[0] = pClient->port;
|
||||
strcpy(epSet.fqdn[0], pClient->fqdn);
|
||||
memcpy(epSet.fqdn[0], pClient->fqdn, TSDB_FQDN_LEN);
|
||||
|
||||
rpcSendRequest(pClient->clientRpc, &epSet, pMsg, NULL);
|
||||
tsem_wait(&pClient->sem);
|
||||
|
|
|
@ -39,8 +39,10 @@ typedef struct {
|
|||
tsem_t sem;
|
||||
} SClient;
|
||||
|
||||
SServer* createServer(const char* path, const char* fqdn, uint16_t port);
|
||||
void dropServer(SServer* pServer);
|
||||
void initLog(const char* path);
|
||||
SServer* createServer(const char* path, const char* fqdn, uint16_t port, const char* firstEp);
|
||||
SServer* startServer(const char* path, const char* fqdn, uint16_t port, const char* firstEp);
|
||||
void stopServer(SServer* pServer);
|
||||
SClient* createClient(const char* user, const char* pass, const char* fqdn, uint16_t port);
|
||||
void dropClient(SClient* pClient);
|
||||
void sendMsg(SClient* pClient, SRpcMsg* pMsg);
|
||||
|
|
|
@ -17,269 +17,223 @@
|
|||
|
||||
class DndTestUser : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {}
|
||||
void TearDown() override {}
|
||||
static SServer* CreateServer(const char* path, const char* fqdn, uint16_t port, const char* firstEp) {
|
||||
SServer* pServer = createServer(path, fqdn, port, firstEp);
|
||||
ASSERT(pServer);
|
||||
return pServer;
|
||||
}
|
||||
|
||||
static void SetUpTestSuite() {
|
||||
const char* user = "root";
|
||||
const char* pass = "taosdata";
|
||||
const char* path = "/tmp/dndTestUser";
|
||||
const char* fqdn = "localhost";
|
||||
uint16_t port = 9524;
|
||||
initLog("/tmp/dndTestUser");
|
||||
|
||||
pServer = createServer(path, fqdn, port);
|
||||
ASSERT(pServer);
|
||||
pClient = createClient(user, pass, fqdn, port);
|
||||
const char* fqdn = "localhost";
|
||||
const char* firstEp = "localhost:9530";
|
||||
pServer = CreateServer("/tmp/dndTestUser", fqdn, 9530, firstEp);
|
||||
pClient = createClient("root", "taosdata", fqdn, 9530);
|
||||
taosMsleep(300);
|
||||
}
|
||||
|
||||
static void TearDownTestSuite() {
|
||||
dropServer(pServer);
|
||||
stopServer(pServer);
|
||||
dropClient(pClient);
|
||||
pServer = NULL;
|
||||
pClient = NULL;
|
||||
}
|
||||
|
||||
static SServer* pServer;
|
||||
static SClient* pClient;
|
||||
static int32_t connId;
|
||||
|
||||
public:
|
||||
void SetUp() override {}
|
||||
void TearDown() override {}
|
||||
|
||||
void SendTheCheckShowMetaMsg(int8_t showType, const char* showName, int32_t columns) {
|
||||
SShowMsg* pShow = (SShowMsg*)rpcMallocCont(sizeof(SShowMsg));
|
||||
pShow->type = showType;
|
||||
strcpy(pShow->db, "");
|
||||
|
||||
SRpcMsg showRpcMsg = {0};
|
||||
showRpcMsg.pCont = pShow;
|
||||
showRpcMsg.contLen = sizeof(SShowMsg);
|
||||
showRpcMsg.msgType = TSDB_MSG_TYPE_SHOW;
|
||||
|
||||
sendMsg(pClient, &showRpcMsg);
|
||||
ASSERT_NE(pClient->pRsp, nullptr);
|
||||
ASSERT_EQ(pClient->pRsp->code, 0);
|
||||
ASSERT_NE(pClient->pRsp->pCont, nullptr);
|
||||
|
||||
SShowRsp* pShowRsp = (SShowRsp*)pClient->pRsp->pCont;
|
||||
ASSERT_NE(pShowRsp, nullptr);
|
||||
pShowRsp->showId = htonl(pShowRsp->showId);
|
||||
pMeta = &pShowRsp->tableMeta;
|
||||
pMeta->numOfTags = htons(pMeta->numOfTags);
|
||||
pMeta->numOfColumns = htons(pMeta->numOfColumns);
|
||||
pMeta->sversion = htons(pMeta->sversion);
|
||||
pMeta->tversion = htons(pMeta->tversion);
|
||||
pMeta->tuid = htobe64(pMeta->tuid);
|
||||
pMeta->suid = htobe64(pMeta->suid);
|
||||
|
||||
showId = pShowRsp->showId;
|
||||
|
||||
EXPECT_NE(pShowRsp->showId, 0);
|
||||
EXPECT_STREQ(pMeta->tbFname, showName);
|
||||
EXPECT_EQ(pMeta->numOfTags, 0);
|
||||
EXPECT_EQ(pMeta->numOfColumns, columns);
|
||||
EXPECT_EQ(pMeta->precision, 0);
|
||||
EXPECT_EQ(pMeta->tableType, 0);
|
||||
EXPECT_EQ(pMeta->update, 0);
|
||||
EXPECT_EQ(pMeta->sversion, 0);
|
||||
EXPECT_EQ(pMeta->tversion, 0);
|
||||
EXPECT_EQ(pMeta->tuid, 0);
|
||||
EXPECT_EQ(pMeta->suid, 0);
|
||||
}
|
||||
|
||||
void CheckSchema(int32_t index, int8_t type, int32_t bytes, const char* name) {
|
||||
SSchema* pSchema = &pMeta->pSchema[index];
|
||||
pSchema->bytes = htons(pSchema->bytes);
|
||||
EXPECT_EQ(pSchema->colId, 0);
|
||||
EXPECT_EQ(pSchema->type, type);
|
||||
EXPECT_EQ(pSchema->bytes, bytes);
|
||||
EXPECT_STREQ(pSchema->name, name);
|
||||
}
|
||||
|
||||
void SendThenCheckShowRetrieveMsg(int32_t rows) {
|
||||
SRetrieveTableMsg* pRetrieve = (SRetrieveTableMsg*)rpcMallocCont(sizeof(SRetrieveTableMsg));
|
||||
pRetrieve->showId = htonl(showId);
|
||||
pRetrieve->free = 0;
|
||||
|
||||
SRpcMsg retrieveRpcMsg = {0};
|
||||
retrieveRpcMsg.pCont = pRetrieve;
|
||||
retrieveRpcMsg.contLen = sizeof(SRetrieveTableMsg);
|
||||
retrieveRpcMsg.msgType = TSDB_MSG_TYPE_SHOW_RETRIEVE;
|
||||
|
||||
sendMsg(pClient, &retrieveRpcMsg);
|
||||
|
||||
ASSERT_NE(pClient->pRsp, nullptr);
|
||||
ASSERT_EQ(pClient->pRsp->code, 0);
|
||||
ASSERT_NE(pClient->pRsp->pCont, nullptr);
|
||||
|
||||
pRetrieveRsp = (SRetrieveTableRsp*)pClient->pRsp->pCont;
|
||||
ASSERT_NE(pRetrieveRsp, nullptr);
|
||||
pRetrieveRsp->numOfRows = htonl(pRetrieveRsp->numOfRows);
|
||||
pRetrieveRsp->offset = htobe64(pRetrieveRsp->offset);
|
||||
pRetrieveRsp->useconds = htobe64(pRetrieveRsp->useconds);
|
||||
pRetrieveRsp->compLen = htonl(pRetrieveRsp->compLen);
|
||||
|
||||
EXPECT_EQ(pRetrieveRsp->numOfRows, rows);
|
||||
EXPECT_EQ(pRetrieveRsp->offset, 0);
|
||||
EXPECT_EQ(pRetrieveRsp->useconds, 0);
|
||||
// EXPECT_EQ(pRetrieveRsp->completed, completed);
|
||||
EXPECT_EQ(pRetrieveRsp->precision, TSDB_TIME_PRECISION_MILLI);
|
||||
EXPECT_EQ(pRetrieveRsp->compressed, 0);
|
||||
EXPECT_EQ(pRetrieveRsp->reserved, 0);
|
||||
EXPECT_EQ(pRetrieveRsp->compLen, 0);
|
||||
|
||||
pData = pRetrieveRsp->data;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
void CheckInt16(int16_t val) {
|
||||
int16_t data = *((int16_t*)(pData + pos));
|
||||
pos += sizeof(int16_t);
|
||||
EXPECT_EQ(data, val);
|
||||
}
|
||||
|
||||
void CheckInt64(int64_t val) {
|
||||
int64_t data = *((int64_t*)(pData + pos));
|
||||
pos += sizeof(int64_t);
|
||||
EXPECT_EQ(data, val);
|
||||
}
|
||||
|
||||
void CheckTimestamp() {
|
||||
int64_t data = *((int64_t*)(pData + pos));
|
||||
pos += sizeof(int64_t);
|
||||
EXPECT_GT(data, 0);
|
||||
}
|
||||
|
||||
void CheckBinary(const char* val, int32_t len) {
|
||||
pos += sizeof(VarDataLenT);
|
||||
char* data = (char*)(pData + pos);
|
||||
pos += len;
|
||||
EXPECT_STREQ(data, val);
|
||||
}
|
||||
|
||||
int32_t showId;
|
||||
STableMetaMsg* pMeta;
|
||||
SRetrieveTableRsp* pRetrieveRsp;
|
||||
char* pData;
|
||||
int32_t pos;
|
||||
};
|
||||
|
||||
SServer* DndTestUser::pServer;
|
||||
SClient* DndTestUser::pClient;
|
||||
int32_t DndTestUser::connId;
|
||||
|
||||
#if 0
|
||||
TEST_F(DndTestUser, ShowUser) {
|
||||
int32_t showId = 0;
|
||||
SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_USER, "show users", 4);
|
||||
CheckSchema(0, TSDB_DATA_TYPE_BINARY, TSDB_USER_LEN + VARSTR_HEADER_SIZE, "name");
|
||||
CheckSchema(1, TSDB_DATA_TYPE_BINARY, 10 + VARSTR_HEADER_SIZE, "privilege");
|
||||
CheckSchema(2, TSDB_DATA_TYPE_TIMESTAMP, 8, "create time");
|
||||
CheckSchema(3, TSDB_DATA_TYPE_BINARY, TSDB_USER_LEN + VARSTR_HEADER_SIZE, "account");
|
||||
|
||||
//--- meta ---
|
||||
SShowMsg* pShow = (SShowMsg*)rpcMallocCont(sizeof(SShowMsg));
|
||||
pShow->type = TSDB_MGMT_TABLE_USER;
|
||||
strcpy(pShow->db, "");
|
||||
|
||||
SRpcMsg showRpcMsg = {0};
|
||||
showRpcMsg.pCont = pShow;
|
||||
showRpcMsg.contLen = sizeof(SShowMsg);
|
||||
showRpcMsg.msgType = TSDB_MSG_TYPE_SHOW;
|
||||
|
||||
sendMsg(pClient, &showRpcMsg);
|
||||
ASSERT_NE(pClient->pRsp, nullptr);
|
||||
|
||||
SShowRsp* pShowRsp = (SShowRsp*)pClient->pRsp->pCont;
|
||||
ASSERT_NE(pShowRsp, nullptr);
|
||||
pShowRsp->showId = htonl(pShowRsp->showId);
|
||||
STableMetaMsg* pMeta = &pShowRsp->tableMeta;
|
||||
pMeta->contLen = htonl(pMeta->contLen);
|
||||
pMeta->numOfColumns = htons(pMeta->numOfColumns);
|
||||
pMeta->sversion = htons(pMeta->sversion);
|
||||
pMeta->tversion = htons(pMeta->tversion);
|
||||
pMeta->tid = htonl(pMeta->tid);
|
||||
pMeta->uid = htobe64(pMeta->uid);
|
||||
pMeta->suid = htobe64(pMeta->suid);
|
||||
|
||||
showId = pShowRsp->showId;
|
||||
|
||||
EXPECT_NE(pShowRsp->showId, 0);
|
||||
EXPECT_EQ(pMeta->contLen, 0);
|
||||
EXPECT_STREQ(pMeta->tableFname, "show users");
|
||||
EXPECT_EQ(pMeta->numOfTags, 0);
|
||||
EXPECT_EQ(pMeta->precision, 0);
|
||||
EXPECT_EQ(pMeta->tableType, 0);
|
||||
EXPECT_EQ(pMeta->numOfColumns, 4);
|
||||
EXPECT_EQ(pMeta->sversion, 0);
|
||||
EXPECT_EQ(pMeta->tversion, 0);
|
||||
EXPECT_EQ(pMeta->tid, 0);
|
||||
EXPECT_EQ(pMeta->uid, 0);
|
||||
EXPECT_STREQ(pMeta->sTableName, "");
|
||||
EXPECT_EQ(pMeta->suid, 0);
|
||||
|
||||
SSchema* pSchema = NULL;
|
||||
|
||||
pSchema = &pMeta->pSchema[0];
|
||||
pSchema->bytes = htons(pSchema->bytes);
|
||||
EXPECT_EQ(pSchema->colId, 0);
|
||||
EXPECT_EQ(pSchema->type, TSDB_DATA_TYPE_BINARY);
|
||||
EXPECT_EQ(pSchema->bytes, TSDB_USER_LEN + VARSTR_HEADER_SIZE);
|
||||
EXPECT_STREQ(pSchema->name, "name");
|
||||
|
||||
pSchema = &pMeta->pSchema[1];
|
||||
pSchema->bytes = htons(pSchema->bytes);
|
||||
EXPECT_EQ(pSchema->colId, 0);
|
||||
EXPECT_EQ(pSchema->type, TSDB_DATA_TYPE_BINARY);
|
||||
EXPECT_EQ(pSchema->bytes, 10 + VARSTR_HEADER_SIZE);
|
||||
EXPECT_STREQ(pSchema->name, "privilege");
|
||||
|
||||
pSchema = &pMeta->pSchema[2];
|
||||
pSchema->bytes = htons(pSchema->bytes);
|
||||
EXPECT_EQ(pSchema->colId, 0);
|
||||
EXPECT_EQ(pSchema->type, TSDB_DATA_TYPE_TIMESTAMP);
|
||||
EXPECT_EQ(pSchema->bytes, 8);
|
||||
EXPECT_STREQ(pSchema->name, "create_time");
|
||||
|
||||
pSchema = &pMeta->pSchema[3];
|
||||
pSchema->bytes = htons(pSchema->bytes);
|
||||
EXPECT_EQ(pSchema->colId, 0);
|
||||
EXPECT_EQ(pSchema->type, TSDB_DATA_TYPE_BINARY);
|
||||
EXPECT_EQ(pSchema->bytes, TSDB_USER_LEN + VARSTR_HEADER_SIZE);
|
||||
EXPECT_STREQ(pSchema->name, "account");
|
||||
|
||||
//--- retrieve ---
|
||||
SRetrieveTableMsg* pRetrieve = (SRetrieveTableMsg*)rpcMallocCont(sizeof(SRetrieveTableMsg));
|
||||
pRetrieve->showId = htonl(showId);
|
||||
pRetrieve->free = 0;
|
||||
|
||||
SRpcMsg retrieveRpcMsg = {0};
|
||||
retrieveRpcMsg.pCont = pRetrieve;
|
||||
retrieveRpcMsg.contLen = sizeof(SRetrieveTableMsg);
|
||||
retrieveRpcMsg.msgType = TSDB_MSG_TYPE_SHOW_RETRIEVE;
|
||||
|
||||
sendMsg(pClient, &retrieveRpcMsg);
|
||||
ASSERT_NE(pClient->pRsp, nullptr);
|
||||
ASSERT_EQ(pClient->pRsp->code, 0);
|
||||
|
||||
SRetrieveTableRsp* pRetrieveRsp = (SRetrieveTableRsp*)pClient->pRsp->pCont;
|
||||
ASSERT_NE(pRetrieveRsp, nullptr);
|
||||
pRetrieveRsp->numOfRows = htonl(pRetrieveRsp->numOfRows);
|
||||
pRetrieveRsp->offset = htobe64(pRetrieveRsp->offset);
|
||||
pRetrieveRsp->useconds = htobe64(pRetrieveRsp->useconds);
|
||||
pRetrieveRsp->compLen = htonl(pRetrieveRsp->compLen);
|
||||
|
||||
EXPECT_EQ(pRetrieveRsp->numOfRows, 2);
|
||||
EXPECT_EQ(pRetrieveRsp->offset, 0);
|
||||
EXPECT_EQ(pRetrieveRsp->useconds, 0);
|
||||
EXPECT_EQ(pRetrieveRsp->completed, 1);
|
||||
EXPECT_EQ(pRetrieveRsp->precision, TSDB_TIME_PRECISION_MILLI);
|
||||
EXPECT_EQ(pRetrieveRsp->compressed, 0);
|
||||
EXPECT_EQ(pRetrieveRsp->reserved, 0);
|
||||
EXPECT_EQ(pRetrieveRsp->compLen, 0);
|
||||
|
||||
char* pData = pRetrieveRsp->data;
|
||||
int32_t pos = 0;
|
||||
char* strVal = NULL;
|
||||
int64_t int64Val = 0;
|
||||
|
||||
//--- name ---
|
||||
{
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += TSDB_USER_LEN;
|
||||
EXPECT_STREQ(strVal, "root");
|
||||
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += TSDB_USER_LEN;
|
||||
EXPECT_STREQ(strVal, "_root");
|
||||
}
|
||||
|
||||
//--- privilege ---
|
||||
{
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += 10;
|
||||
EXPECT_STREQ(strVal, "super");
|
||||
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += 10;
|
||||
EXPECT_STREQ(strVal, "writable");
|
||||
}
|
||||
|
||||
//--- create_time ---
|
||||
{
|
||||
int64Val = *((int64_t*)(pData + pos));
|
||||
pos += sizeof(int64_t);
|
||||
EXPECT_GT(int64Val, 0);
|
||||
|
||||
int64Val = *((int64_t*)(pData + pos));
|
||||
pos += sizeof(int64_t);
|
||||
EXPECT_GT(int64Val, 0);
|
||||
}
|
||||
|
||||
//--- account ---
|
||||
{
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += TSDB_USER_LEN;
|
||||
EXPECT_STREQ(strVal, "root");
|
||||
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += TSDB_USER_LEN;
|
||||
EXPECT_STREQ(strVal, "root");
|
||||
}
|
||||
SendThenCheckShowRetrieveMsg(1);
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
CheckBinary("super", 10);
|
||||
CheckTimestamp();
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_F(DndTestUser, CreateUser_01) {
|
||||
ASSERT_NE(pClient, nullptr);
|
||||
|
||||
//--- create user ---
|
||||
SCreateUserMsg* pReq = (SCreateUserMsg*)rpcMallocCont(sizeof(SCreateUserMsg));
|
||||
strcpy(pReq->user, "u1");
|
||||
strcpy(pReq->pass, "p1");
|
||||
|
||||
SRpcMsg rpcMsg = {0};
|
||||
rpcMsg.pCont = pReq;
|
||||
rpcMsg.contLen = sizeof(SCreateUserMsg);
|
||||
rpcMsg.msgType = TSDB_MSG_TYPE_CREATE_USER;
|
||||
|
||||
sendMsg(pClient, &rpcMsg);
|
||||
SRpcMsg* pMsg = pClient->pRsp;
|
||||
ASSERT_NE(pMsg, nullptr);
|
||||
ASSERT_EQ(pMsg->code, 0);
|
||||
|
||||
//--- meta ---
|
||||
SShowMsg* pShow = (SShowMsg*)rpcMallocCont(sizeof(SShowMsg));
|
||||
pShow->type = TSDB_MGMT_TABLE_USER;
|
||||
SRpcMsg showRpcMsg = {0};
|
||||
showRpcMsg.pCont = pShow;
|
||||
showRpcMsg.contLen = sizeof(SShowMsg);
|
||||
showRpcMsg.msgType = TSDB_MSG_TYPE_SHOW;
|
||||
|
||||
sendMsg(pClient, &showRpcMsg);
|
||||
SShowRsp* pShowRsp = (SShowRsp*)pClient->pRsp->pCont;
|
||||
STableMetaMsg* pMeta = &pShowRsp->tableMeta;
|
||||
pMeta->numOfColumns = htons(pMeta->numOfColumns);
|
||||
EXPECT_EQ(pMeta->numOfColumns, 4);
|
||||
|
||||
//--- retrieve ---
|
||||
SRetrieveTableMsg* pRetrieve = (SRetrieveTableMsg*)rpcMallocCont(sizeof(SRetrieveTableMsg));
|
||||
pRetrieve->showId = pShowRsp->showId;
|
||||
SRpcMsg retrieveRpcMsg = {0};
|
||||
retrieveRpcMsg.pCont = pRetrieve;
|
||||
retrieveRpcMsg.contLen = sizeof(SRetrieveTableMsg);
|
||||
retrieveRpcMsg.msgType = TSDB_MSG_TYPE_SHOW_RETRIEVE;
|
||||
|
||||
sendMsg(pClient, &retrieveRpcMsg);
|
||||
SRetrieveTableRsp* pRetrieveRsp = (SRetrieveTableRsp*)pClient->pRsp->pCont;
|
||||
pRetrieveRsp->numOfRows = htonl(pRetrieveRsp->numOfRows);
|
||||
EXPECT_EQ(pRetrieveRsp->numOfRows, 3);
|
||||
|
||||
char* pData = pRetrieveRsp->data;
|
||||
int32_t pos = 0;
|
||||
char* strVal = NULL;
|
||||
|
||||
//--- name ---
|
||||
{
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += TSDB_USER_LEN;
|
||||
EXPECT_STREQ(strVal, "u1");
|
||||
SCreateUserMsg* pReq = (SCreateUserMsg*)rpcMallocCont(sizeof(SCreateUserMsg));
|
||||
strcpy(pReq->user, "u1");
|
||||
strcpy(pReq->pass, "p1");
|
||||
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += TSDB_USER_LEN;
|
||||
EXPECT_STREQ(strVal, "root");
|
||||
SRpcMsg rpcMsg = {0};
|
||||
rpcMsg.pCont = pReq;
|
||||
rpcMsg.contLen = sizeof(SCreateUserMsg);
|
||||
rpcMsg.msgType = TSDB_MSG_TYPE_CREATE_USER;
|
||||
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += TSDB_USER_LEN;
|
||||
EXPECT_STREQ(strVal, "_root");
|
||||
sendMsg(pClient, &rpcMsg);
|
||||
SRpcMsg* pMsg = pClient->pRsp;
|
||||
ASSERT_NE(pMsg, nullptr);
|
||||
ASSERT_EQ(pMsg->code, 0);
|
||||
}
|
||||
|
||||
{
|
||||
SCreateUserMsg* pReq = (SCreateUserMsg*)rpcMallocCont(sizeof(SCreateUserMsg));
|
||||
strcpy(pReq->user, "u2");
|
||||
strcpy(pReq->pass, "p2");
|
||||
|
||||
SRpcMsg rpcMsg = {0};
|
||||
rpcMsg.pCont = pReq;
|
||||
rpcMsg.contLen = sizeof(SCreateUserMsg);
|
||||
rpcMsg.msgType = TSDB_MSG_TYPE_CREATE_USER;
|
||||
|
||||
sendMsg(pClient, &rpcMsg);
|
||||
SRpcMsg* pMsg = pClient->pRsp;
|
||||
ASSERT_NE(pMsg, nullptr);
|
||||
ASSERT_EQ(pMsg->code, 0);
|
||||
}
|
||||
|
||||
SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_USER, "show users", 4);
|
||||
SendThenCheckShowRetrieveMsg(3);
|
||||
CheckBinary("u1", TSDB_USER_LEN);
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
CheckBinary("u2", TSDB_USER_LEN);
|
||||
CheckBinary("normal", 10);
|
||||
CheckBinary("super", 10);
|
||||
CheckBinary("normal", 10);
|
||||
CheckTimestamp();
|
||||
CheckTimestamp();
|
||||
CheckTimestamp();
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
}
|
||||
|
||||
TEST_F(DndTestUser, AlterUser_01) {
|
||||
ASSERT_NE(pClient, nullptr);
|
||||
|
||||
//--- drop user ---
|
||||
SAlterUserMsg* pReq = (SAlterUserMsg*)rpcMallocCont(sizeof(SAlterUserMsg));
|
||||
strcpy(pReq->user, "u1");
|
||||
strcpy(pReq->pass, "p2");
|
||||
|
@ -294,60 +248,23 @@ TEST_F(DndTestUser, AlterUser_01) {
|
|||
ASSERT_NE(pMsg, nullptr);
|
||||
ASSERT_EQ(pMsg->code, 0);
|
||||
|
||||
//--- meta ---
|
||||
SShowMsg* pShow = (SShowMsg*)rpcMallocCont(sizeof(SShowMsg));
|
||||
pShow->type = TSDB_MGMT_TABLE_USER;
|
||||
SRpcMsg showRpcMsg = {0};
|
||||
showRpcMsg.pCont = pShow;
|
||||
showRpcMsg.contLen = sizeof(SShowMsg);
|
||||
showRpcMsg.msgType = TSDB_MSG_TYPE_SHOW;
|
||||
|
||||
sendMsg(pClient, &showRpcMsg);
|
||||
SShowRsp* pShowRsp = (SShowRsp*)pClient->pRsp->pCont;
|
||||
STableMetaMsg* pMeta = &pShowRsp->tableMeta;
|
||||
pMeta->numOfColumns = htons(pMeta->numOfColumns);
|
||||
EXPECT_EQ(pMeta->numOfColumns, 4);
|
||||
|
||||
//--- retrieve ---
|
||||
SRetrieveTableMsg* pRetrieve = (SRetrieveTableMsg*)rpcMallocCont(sizeof(SRetrieveTableMsg));
|
||||
pRetrieve->showId = pShowRsp->showId;
|
||||
SRpcMsg retrieveRpcMsg = {0};
|
||||
retrieveRpcMsg.pCont = pRetrieve;
|
||||
retrieveRpcMsg.contLen = sizeof(SRetrieveTableMsg);
|
||||
retrieveRpcMsg.msgType = TSDB_MSG_TYPE_SHOW_RETRIEVE;
|
||||
|
||||
sendMsg(pClient, &retrieveRpcMsg);
|
||||
SRetrieveTableRsp* pRetrieveRsp = (SRetrieveTableRsp*)pClient->pRsp->pCont;
|
||||
pRetrieveRsp->numOfRows = htonl(pRetrieveRsp->numOfRows);
|
||||
EXPECT_EQ(pRetrieveRsp->numOfRows, 3);
|
||||
|
||||
char* pData = pRetrieveRsp->data;
|
||||
int32_t pos = 0;
|
||||
char* strVal = NULL;
|
||||
|
||||
//--- name ---
|
||||
{
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += TSDB_USER_LEN;
|
||||
EXPECT_STREQ(strVal, "u1");
|
||||
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += TSDB_USER_LEN;
|
||||
EXPECT_STREQ(strVal, "root");
|
||||
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += TSDB_USER_LEN;
|
||||
EXPECT_STREQ(strVal, "_root");
|
||||
}
|
||||
SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_USER, "show users", 4);
|
||||
SendThenCheckShowRetrieveMsg(3);
|
||||
CheckBinary("u1", TSDB_USER_LEN);
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
CheckBinary("u2", TSDB_USER_LEN);
|
||||
CheckBinary("normal", 10);
|
||||
CheckBinary("super", 10);
|
||||
CheckBinary("normal", 10);
|
||||
CheckTimestamp();
|
||||
CheckTimestamp();
|
||||
CheckTimestamp();
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
}
|
||||
|
||||
TEST_F(DndTestUser, DropUser_01) {
|
||||
ASSERT_NE(pClient, nullptr);
|
||||
|
||||
//--- drop user ---
|
||||
SDropUserMsg* pReq = (SDropUserMsg*)rpcMallocCont(sizeof(SDropUserMsg));
|
||||
strcpy(pReq->user, "u1");
|
||||
|
||||
|
@ -361,47 +278,38 @@ TEST_F(DndTestUser, DropUser_01) {
|
|||
ASSERT_NE(pMsg, nullptr);
|
||||
ASSERT_EQ(pMsg->code, 0);
|
||||
|
||||
//--- meta ---
|
||||
SShowMsg* pShow = (SShowMsg*)rpcMallocCont(sizeof(SShowMsg));
|
||||
pShow->type = TSDB_MGMT_TABLE_USER;
|
||||
SRpcMsg showRpcMsg = {0};
|
||||
showRpcMsg.pCont = pShow;
|
||||
showRpcMsg.contLen = sizeof(SShowMsg);
|
||||
showRpcMsg.msgType = TSDB_MSG_TYPE_SHOW;
|
||||
SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_USER, "show users", 4);
|
||||
SendThenCheckShowRetrieveMsg(2);
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
CheckBinary("u2", TSDB_USER_LEN);
|
||||
CheckBinary("super", 10);
|
||||
CheckBinary("normal", 10);
|
||||
CheckTimestamp();
|
||||
CheckTimestamp();
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
}
|
||||
|
||||
sendMsg(pClient, &showRpcMsg);
|
||||
SShowRsp* pShowRsp = (SShowRsp*)pClient->pRsp->pCont;
|
||||
STableMetaMsg* pMeta = &pShowRsp->tableMeta;
|
||||
pMeta->numOfColumns = htons(pMeta->numOfColumns);
|
||||
EXPECT_EQ(pMeta->numOfColumns, 4);
|
||||
TEST_F(DndTestUser, RestartDnode) {
|
||||
stopServer(pServer);
|
||||
pServer = NULL;
|
||||
|
||||
//--- retrieve ---
|
||||
SRetrieveTableMsg* pRetrieve = (SRetrieveTableMsg*)rpcMallocCont(sizeof(SRetrieveTableMsg));
|
||||
pRetrieve->showId = pShowRsp->showId;
|
||||
SRpcMsg retrieveRpcMsg = {0};
|
||||
retrieveRpcMsg.pCont = pRetrieve;
|
||||
retrieveRpcMsg.contLen = sizeof(SRetrieveTableMsg);
|
||||
retrieveRpcMsg.msgType = TSDB_MSG_TYPE_SHOW_RETRIEVE;
|
||||
uInfo("start all server");
|
||||
|
||||
sendMsg(pClient, &retrieveRpcMsg);
|
||||
SRetrieveTableRsp* pRetrieveRsp = (SRetrieveTableRsp*)pClient->pRsp->pCont;
|
||||
pRetrieveRsp->numOfRows = htonl(pRetrieveRsp->numOfRows);
|
||||
EXPECT_EQ(pRetrieveRsp->numOfRows, 2);
|
||||
const char* fqdn = "localhost";
|
||||
const char* firstEp = "localhost:9530";
|
||||
pServer = startServer("/tmp/dndTestUser", fqdn, 9530, firstEp);
|
||||
|
||||
char* pData = pRetrieveRsp->data;
|
||||
int32_t pos = 0;
|
||||
char* strVal = NULL;
|
||||
uInfo("all server is running");
|
||||
|
||||
//--- name ---
|
||||
{
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += TSDB_USER_LEN;
|
||||
EXPECT_STREQ(strVal, "root");
|
||||
|
||||
pos += sizeof(VarDataLenT);
|
||||
strVal = (char*)(pData + pos);
|
||||
pos += TSDB_USER_LEN;
|
||||
EXPECT_STREQ(strVal, "_root");
|
||||
}
|
||||
}
|
||||
SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_USER, "show users", 4);
|
||||
SendThenCheckShowRetrieveMsg(2);
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
CheckBinary("u2", TSDB_USER_LEN);
|
||||
CheckBinary("super", 10);
|
||||
CheckBinary("normal", 10);
|
||||
CheckTimestamp();
|
||||
CheckTimestamp();
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
CheckBinary("root", TSDB_USER_LEN);
|
||||
}
|
||||
|
|
|
@ -92,7 +92,6 @@ typedef enum {
|
|||
DND_REASON_VERSION_NOT_MATCH,
|
||||
DND_REASON_DNODE_ID_NOT_MATCH,
|
||||
DND_REASON_CLUSTER_ID_NOT_MATCH,
|
||||
DND_REASON_MN_EQUAL_VN_NOT_MATCH,
|
||||
DND_REASON_STATUS_INTERVAL_NOT_MATCH,
|
||||
DND_REASON_TIME_ZONE_NOT_MATCH,
|
||||
DND_REASON_LOCALE_NOT_MATCH,
|
||||
|
@ -125,6 +124,7 @@ typedef struct SDnodeObj {
|
|||
int64_t createdTime;
|
||||
int64_t updateTime;
|
||||
int64_t rebootTime;
|
||||
int64_t lastAccessTime;
|
||||
int32_t accessTimes;
|
||||
int16_t numOfMnodes;
|
||||
int16_t numOfVnodes;
|
||||
|
@ -180,13 +180,11 @@ typedef struct SAcctObj {
|
|||
|
||||
typedef struct SUserObj {
|
||||
char user[TSDB_USER_LEN];
|
||||
char pass[TSDB_KEY_LEN];
|
||||
char pass[TSDB_PASSWORD_LEN];
|
||||
char acct[TSDB_USER_LEN];
|
||||
int64_t createdTime;
|
||||
int64_t updateTime;
|
||||
int8_t superAuth;
|
||||
int8_t readAuth;
|
||||
int8_t writeAuth;
|
||||
int8_t superUser;
|
||||
int32_t acctId;
|
||||
SHashObj *prohibitDbHash;
|
||||
} SUserObj;
|
||||
|
@ -241,7 +239,7 @@ typedef struct SVgObj {
|
|||
SVnodeGid vnodeGid[TSDB_MAX_REPLICA];
|
||||
} SVgObj;
|
||||
|
||||
typedef struct SStableObj {
|
||||
typedef struct {
|
||||
char name[TSDB_TABLE_FNAME_LEN];
|
||||
char db[TSDB_FULL_DB_NAME_LEN];
|
||||
int64_t createdTime;
|
||||
|
@ -251,9 +249,8 @@ typedef struct SStableObj {
|
|||
int32_t numOfColumns;
|
||||
int32_t numOfTags;
|
||||
SRWLatch lock;
|
||||
SSchema *columnSchema;
|
||||
SSchema *tagSchema;
|
||||
} SStableObj;
|
||||
SSchema *pSchema;
|
||||
} SStbObj;
|
||||
|
||||
typedef struct SFuncObj {
|
||||
char name[TSDB_FUNC_NAME_LEN];
|
||||
|
|
|
@ -88,6 +88,8 @@ void mndSendMsgToMnode(SMnode *pMnode, SRpcMsg *pMsg);
|
|||
void mndSendRedirectMsg(SMnode *pMnode, SRpcMsg *pMsg);
|
||||
void mndSetMsgHandle(SMnode *pMnode, int32_t msgType, MndMsgFp fp);
|
||||
|
||||
uint64_t mndGenerateUid(char *name, int32_t len) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_MND_STABLE_H_
|
||||
#define _TD_MND_STABLE_H_
|
||||
#ifndef _TD_MND_STB_H_
|
||||
#define _TD_MND_STB_H_
|
||||
|
||||
#include "mndInt.h"
|
||||
|
||||
|
@ -22,11 +22,11 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
int32_t mndInitStable(SMnode *pMnode);
|
||||
void mndCleanupStable(SMnode *pMnode);
|
||||
int32_t mndInitStb(SMnode *pMnode);
|
||||
void mndCleanupStb(SMnode *pMnode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_MND_STABLE_H_*/
|
||||
#endif /*_TD_MND_STB_H_*/
|
|
@ -159,7 +159,7 @@ static int32_t mndGetClusterMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg
|
|||
cols++;
|
||||
|
||||
pMeta->numOfColumns = htons(cols);
|
||||
strcpy(pMeta->tableFname, "show cluster");
|
||||
strcpy(pMeta->tbFname, mndShowStr(pShow->type));
|
||||
pShow->numOfColumns = cols;
|
||||
|
||||
pShow->offset[0] = 0;
|
||||
|
|
|
@ -767,7 +767,7 @@ static int32_t mndGetDbMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMe
|
|||
|
||||
pShow->numOfRows = sdbGetSize(pSdb, SDB_DB);
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
strcpy(pMeta->tableFname, mndShowStr(pShow->type));
|
||||
strcpy(pMeta->tbFname, mndShowStr(pShow->type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -22,10 +22,13 @@
|
|||
#include "tutil.h"
|
||||
|
||||
#define TSDB_DNODE_VER 1
|
||||
#define TSDB_DNODE_RESERVE_SIZE 64
|
||||
#define TSDB_CONFIG_OPTION_LEN 16
|
||||
#define TSDB_CONIIG_VALUE_LEN 48
|
||||
#define TSDB_CONFIG_NUMBER 8
|
||||
|
||||
static int32_t id = 2;
|
||||
|
||||
static const char *offlineReason[] = {
|
||||
"",
|
||||
"status msg timeout",
|
||||
|
@ -33,7 +36,6 @@ static const char *offlineReason[] = {
|
|||
"version not match",
|
||||
"dnodeId not match",
|
||||
"clusterId not match",
|
||||
"mnEqualVn not match",
|
||||
"interval not match",
|
||||
"timezone not match",
|
||||
"locale not match",
|
||||
|
@ -117,6 +119,7 @@ static SSdbRaw *mndDnodeActionEncode(SDnodeObj *pDnode) {
|
|||
SDB_SET_INT64(pRaw, dataPos, pDnode->updateTime)
|
||||
SDB_SET_INT16(pRaw, dataPos, pDnode->port)
|
||||
SDB_SET_BINARY(pRaw, dataPos, pDnode->fqdn, TSDB_FQDN_LEN)
|
||||
SDB_SET_RESERVE(pRaw, dataPos, TSDB_DNODE_RESERVE_SIZE)
|
||||
SDB_SET_DATALEN(pRaw, dataPos);
|
||||
|
||||
return pRaw;
|
||||
|
@ -142,28 +145,28 @@ static SSdbRow *mndDnodeActionDecode(SSdbRaw *pRaw) {
|
|||
SDB_GET_INT64(pRaw, pRow, dataPos, &pDnode->updateTime)
|
||||
SDB_GET_INT16(pRaw, pRow, dataPos, &pDnode->port)
|
||||
SDB_GET_BINARY(pRaw, pRow, dataPos, pDnode->fqdn, TSDB_FQDN_LEN)
|
||||
SDB_GET_RESERVE(pRaw, pRow, dataPos, TSDB_DNODE_RESERVE_SIZE)
|
||||
|
||||
return pRow;
|
||||
}
|
||||
|
||||
static void mnodeResetDnode(SDnodeObj *pDnode) {
|
||||
static int32_t mndDnodeActionInsert(SSdb *pSdb, SDnodeObj *pDnode) {
|
||||
mTrace("dnode:%d, perform insert action", pDnode->id);
|
||||
|
||||
pDnode->rebootTime = 0;
|
||||
pDnode->lastAccessTime = 0;
|
||||
pDnode->accessTimes = 0;
|
||||
pDnode->numOfCores = 0;
|
||||
pDnode->numOfMnodes = 0;
|
||||
pDnode->numOfVnodes = 0;
|
||||
pDnode->numOfQnodes = 0;
|
||||
pDnode->numOfSupportMnodes = 0;
|
||||
pDnode->numOfSupportVnodes = 0;
|
||||
pDnode->numOfSupportQnodes = 0;
|
||||
pDnode->numOfCores = 0;
|
||||
pDnode->status = DND_STATUS_OFFLINE;
|
||||
pDnode->offlineReason = DND_REASON_STATUS_NOT_RECEIVED;
|
||||
snprintf(pDnode->ep, TSDB_EP_LEN, "%s:%u", pDnode->fqdn, pDnode->port);
|
||||
}
|
||||
|
||||
static int32_t mndDnodeActionInsert(SSdb *pSdb, SDnodeObj *pDnode) {
|
||||
mTrace("dnode:%d, perform insert action", pDnode->id);
|
||||
mnodeResetDnode(pDnode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -174,11 +177,6 @@ static int32_t mndDnodeActionDelete(SSdb *pSdb, SDnodeObj *pDnode) {
|
|||
|
||||
static int32_t mndDnodeActionUpdate(SSdb *pSdb, SDnodeObj *pOldDnode, SDnodeObj *pNewDnode) {
|
||||
mTrace("dnode:%d, perform update action", pOldDnode->id);
|
||||
pOldDnode->id = pNewDnode->id;
|
||||
pOldDnode->createdTime = pNewDnode->createdTime;
|
||||
pOldDnode->updateTime = pNewDnode->updateTime;
|
||||
pOldDnode->port = pNewDnode->port;
|
||||
memcpy(pOldDnode->fqdn, pNewDnode->fqdn, TSDB_FQDN_LEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -232,6 +230,7 @@ static void mndGetDnodeData(SMnode *pMnode, SDnodeEps *pEps, int32_t numOfEps) {
|
|||
if (pIter == NULL) break;
|
||||
if (i >= numOfEps) {
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
sdbRelease(pSdb, pDnode);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -244,20 +243,15 @@ static void mndGetDnodeData(SMnode *pMnode, SDnodeEps *pEps, int32_t numOfEps) {
|
|||
pEp->isMnode = 1;
|
||||
}
|
||||
i++;
|
||||
sdbRelease(pSdb, pDnode);
|
||||
}
|
||||
|
||||
pEps->num = htonl(i);
|
||||
}
|
||||
|
||||
static int32_t mndCheckClusterCfgPara(SMnode *pMnode, const SClusterCfg *pCfg) {
|
||||
if (pCfg->mnodeEqualVnodeNum != pMnode->cfg.mnodeEqualVnodeNum) {
|
||||
mError("\"mnodeEqualVnodeNum\"[%d - %d] cfg inconsistent", pCfg->mnodeEqualVnodeNum,
|
||||
pMnode->cfg.mnodeEqualVnodeNum);
|
||||
return DND_REASON_MN_EQUAL_VN_NOT_MATCH;
|
||||
}
|
||||
|
||||
if (pCfg->statusInterval != pMnode->cfg.statusInterval) {
|
||||
mError("\"statusInterval\"[%d - %d] cfg inconsistent", pCfg->statusInterval, pMnode->cfg.statusInterval);
|
||||
mError("statusInterval [%d - %d] cfg inconsistent", pCfg->statusInterval, pMnode->cfg.statusInterval);
|
||||
return DND_REASON_STATUS_INTERVAL_NOT_MATCH;
|
||||
}
|
||||
|
||||
|
@ -265,18 +259,18 @@ static int32_t mndCheckClusterCfgPara(SMnode *pMnode, const SClusterCfg *pCfg) {
|
|||
char timestr[32] = "1970-01-01 00:00:00.00";
|
||||
(void)taosParseTime(timestr, &checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0);
|
||||
if ((0 != strcasecmp(pCfg->timezone, pMnode->cfg.timezone)) && (checkTime != pCfg->checkTime)) {
|
||||
mError("\"timezone\"[%s - %s] [%" PRId64 " - %" PRId64 "] cfg inconsistent", pCfg->timezone, pMnode->cfg.timezone,
|
||||
mError("timezone [%s - %s] [%" PRId64 " - %" PRId64 "] cfg inconsistent", pCfg->timezone, pMnode->cfg.timezone,
|
||||
pCfg->checkTime, checkTime);
|
||||
return DND_REASON_TIME_ZONE_NOT_MATCH;
|
||||
}
|
||||
|
||||
if (0 != strcasecmp(pCfg->locale, pMnode->cfg.locale)) {
|
||||
mError("\"locale\"[%s - %s] cfg parameters inconsistent", pCfg->locale, pMnode->cfg.locale);
|
||||
mError("locale [%s - %s] cfg inconsistent", pCfg->locale, pMnode->cfg.locale);
|
||||
return DND_REASON_LOCALE_NOT_MATCH;
|
||||
}
|
||||
|
||||
if (0 != strcasecmp(pCfg->charset, pMnode->cfg.charset)) {
|
||||
mError("\"charset\"[%s - %s] cfg parameters inconsistent.", pCfg->charset, pMnode->cfg.charset);
|
||||
mError("charset [%s - %s] cfg inconsistent.", pCfg->charset, pMnode->cfg.charset);
|
||||
return DND_REASON_CHARSET_NOT_MATCH;
|
||||
}
|
||||
|
||||
|
@ -287,14 +281,12 @@ static void mndParseStatusMsg(SStatusMsg *pStatus) {
|
|||
pStatus->sver = htonl(pStatus->sver);
|
||||
pStatus->dnodeId = htonl(pStatus->dnodeId);
|
||||
pStatus->clusterId = htonl(pStatus->clusterId);
|
||||
pStatus->rebootTime = htonl(pStatus->rebootTime);
|
||||
pStatus->rebootTime = htobe64(pStatus->rebootTime);
|
||||
pStatus->numOfCores = htons(pStatus->numOfCores);
|
||||
pStatus->numOfSupportMnodes = htons(pStatus->numOfSupportMnodes);
|
||||
pStatus->numOfSupportVnodes = htons(pStatus->numOfSupportVnodes);
|
||||
pStatus->numOfSupportQnodes = htons(pStatus->numOfSupportQnodes);
|
||||
|
||||
pStatus->clusterCfg.statusInterval = htonl(pStatus->clusterCfg.statusInterval);
|
||||
pStatus->clusterCfg.mnodeEqualVnodeNum = htonl(pStatus->clusterCfg.mnodeEqualVnodeNum);
|
||||
pStatus->clusterCfg.checkTime = htobe64(pStatus->clusterCfg.checkTime);
|
||||
}
|
||||
|
||||
|
@ -308,7 +300,8 @@ static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) {
|
|||
pDnode = mndAcquireDnodeByEp(pMnode, pStatus->dnodeEp);
|
||||
if (pDnode == NULL) {
|
||||
mDebug("dnode:%s, not created yet", pStatus->dnodeEp);
|
||||
return TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
pDnode = mndAcquireDnode(pMnode, pStatus->dnodeId);
|
||||
|
@ -319,7 +312,8 @@ static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) {
|
|||
}
|
||||
mError("dnode:%d, %s not exist", pStatus->dnodeId, pStatus->dnodeEp);
|
||||
mndReleaseDnode(pMnode, pDnode);
|
||||
return TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,7 +323,8 @@ static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) {
|
|||
}
|
||||
mndReleaseDnode(pMnode, pDnode);
|
||||
mError("dnode:%d, status msg version:%d not match cluster:%d", pStatus->dnodeId, pStatus->sver, pMnode->cfg.sver);
|
||||
return TSDB_CODE_MND_INVALID_MSG_VERSION;
|
||||
terrno = TSDB_CODE_MND_INVALID_MSG_VERSION;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pStatus->dnodeId == 0) {
|
||||
|
@ -341,7 +336,8 @@ static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) {
|
|||
}
|
||||
mError("dnode:%d, clusterId %d not match exist %d", pDnode->id, pStatus->clusterId, pMnode->clusterId);
|
||||
mndReleaseDnode(pMnode, pDnode);
|
||||
return TSDB_CODE_MND_INVALID_CLUSTER_ID;
|
||||
terrno != TSDB_CODE_MND_INVALID_CLUSTER_ID;
|
||||
return -1;
|
||||
} else {
|
||||
pDnode->accessTimes++;
|
||||
mTrace("dnode:%d, status received, access times %d", pDnode->id, pDnode->accessTimes);
|
||||
|
@ -355,7 +351,8 @@ static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) {
|
|||
pDnode->offlineReason = ret;
|
||||
mError("dnode:%d, cluster cfg inconsistent since:%s", pDnode->id, offlineReason[ret]);
|
||||
mndReleaseDnode(pMnode, pDnode);
|
||||
return TSDB_CODE_MND_CLUSTER_CFG_INCONSISTENT;
|
||||
terrno = TSDB_CODE_MND_INVALID_CLUSTER_CFG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
mInfo("dnode:%d, from offline to online", pDnode->id);
|
||||
|
@ -366,6 +363,7 @@ static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) {
|
|||
pDnode->numOfSupportMnodes = pStatus->numOfSupportMnodes;
|
||||
pDnode->numOfSupportVnodes = pStatus->numOfSupportVnodes;
|
||||
pDnode->numOfSupportQnodes = pStatus->numOfSupportQnodes;
|
||||
pDnode->lastAccessTime = taosGetTimestampMs();
|
||||
pDnode->status = DND_STATUS_READY;
|
||||
|
||||
int32_t numOfEps = mndGetDnodeSize(pMnode);
|
||||
|
@ -373,7 +371,8 @@ static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) {
|
|||
SStatusRsp *pRsp = rpcMallocCont(contLen);
|
||||
if (pRsp == NULL) {
|
||||
mndReleaseDnode(pMnode, pDnode);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pRsp->dnodeCfg.dnodeId = htonl(pDnode->id);
|
||||
|
@ -390,13 +389,13 @@ static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) {
|
|||
|
||||
static int32_t mndCreateDnode(SMnode *pMnode, SMnodeMsg *pMsg, SCreateDnodeMsg *pCreate) {
|
||||
SDnodeObj dnodeObj = {0};
|
||||
dnodeObj.id = 1; // todo
|
||||
dnodeObj.id = id++;
|
||||
dnodeObj.createdTime = taosGetTimestampMs();
|
||||
dnodeObj.updateTime = dnodeObj.createdTime;
|
||||
taosGetFqdnPortFromEp(pCreate->ep, dnodeObj.fqdn, &dnodeObj.port);
|
||||
|
||||
if (dnodeObj.fqdn[0] == 0 || dnodeObj.port <= 0) {
|
||||
terrno = TSDB_CODE_SDB_APP_ERROR;
|
||||
terrno = TSDB_CODE_MND_INVALID_DNODE_EP;
|
||||
mError("dnode:%s, failed to create since %s", pCreate->ep, terrstr());
|
||||
return terrno;
|
||||
}
|
||||
|
@ -449,7 +448,7 @@ static int32_t mndProcessCreateDnodeMsg(SMnodeMsg *pMsg) {
|
|||
mDebug("dnode:%s, start to create", pCreate->ep);
|
||||
|
||||
if (pCreate->ep[0] == 0) {
|
||||
terrno = TSDB_CODE_SDB_APP_ERROR;
|
||||
terrno = TSDB_CODE_MND_INVALID_DNODE_EP;
|
||||
mError("dnode:%s, failed to create since %s", pCreate->ep, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
@ -457,7 +456,7 @@ static int32_t mndProcessCreateDnodeMsg(SMnodeMsg *pMsg) {
|
|||
SDnodeObj *pDnode = mndAcquireDnodeByEp(pMnode, pCreate->ep);
|
||||
if (pDnode != NULL) {
|
||||
mError("dnode:%d, already exist", pDnode->id);
|
||||
sdbRelease(pMnode->pSdb, pDnode);
|
||||
mndReleaseDnode(pMnode, pDnode);
|
||||
terrno = TSDB_CODE_MND_DNODE_ALREADY_EXIST;
|
||||
return -1;
|
||||
}
|
||||
|
@ -478,7 +477,7 @@ static int32_t mndDropDnode(SMnode *pMnode, SMnodeMsg *pMsg, SDnodeObj *pDnode)
|
|||
mError("dnode:%d, failed to drop since %s", pDnode->id, terrstr());
|
||||
return -1;
|
||||
}
|
||||
mDebug("trans:%d, used to drop user:%d", pTrans->id, pDnode->id);
|
||||
mDebug("trans:%d, used to drop dnode:%d", pTrans->id, pDnode->id);
|
||||
|
||||
SSdbRaw *pRedoRaw = mndDnodeActionEncode(pDnode);
|
||||
if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||
|
@ -522,26 +521,26 @@ static int32_t mndProcessDropDnodeMsg(SMnodeMsg *pMsg) {
|
|||
mDebug("dnode:%d, start to drop", pDrop->dnodeId);
|
||||
|
||||
if (pDrop->dnodeId <= 0) {
|
||||
terrno = TSDB_CODE_SDB_APP_ERROR;
|
||||
terrno = TSDB_CODE_MND_INVALID_DNODE_ID;
|
||||
mError("dnode:%d, failed to drop since %s", pDrop->dnodeId, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDnodeObj *pDnode = mndAcquireDnode(pMnode, pDrop->dnodeId);
|
||||
if (pDnode == NULL) {
|
||||
mError("dnode:%d, not exist", pDrop->dnodeId);
|
||||
terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t code = mndDropDnode(pMnode, pMsg, pDnode);
|
||||
|
||||
if (code != 0) {
|
||||
mError("dnode:%d, failed to drop since %s", pDrop->dnodeId, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
sdbRelease(pMnode->pSdb, pDnode);
|
||||
int32_t code = mndDropDnode(pMnode, pMsg, pDnode);
|
||||
if (code != 0) {
|
||||
mndReleaseDnode(pMnode, pDnode);
|
||||
mError("dnode:%d, failed to drop since %s", pDrop->dnodeId, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
mndReleaseDnode(pMnode, pDnode);
|
||||
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
|
@ -553,7 +552,7 @@ static int32_t mndProcessConfigDnodeMsg(SMnodeMsg *pMsg) {
|
|||
SDnodeObj *pDnode = mndAcquireDnode(pMnode, pCfg->dnodeId);
|
||||
if (pDnode == NULL) {
|
||||
terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
mError("dnode:%d, failed to cfg since %s ", pCfg->dnodeId, terrstr());
|
||||
mError("dnode:%d, failed to config since %s ", pCfg->dnodeId, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -562,17 +561,22 @@ static int32_t mndProcessConfigDnodeMsg(SMnodeMsg *pMsg) {
|
|||
|
||||
SCfgDnodeMsg *pCfgDnode = rpcMallocCont(sizeof(SCfgDnodeMsg));
|
||||
pCfgDnode->dnodeId = htonl(pCfg->dnodeId);
|
||||
memcpy(pCfgDnode->config, pCfg->config, 128);
|
||||
memcpy(pCfgDnode->config, pCfg->config, TSDB_DNODE_CONFIG_LEN);
|
||||
|
||||
SRpcMsg rpcMsg = {.msgType = TSDB_MSG_TYPE_CONFIG_DNODE_IN, .pCont = pCfgDnode, .contLen = sizeof(SCfgDnodeMsg)};
|
||||
SRpcMsg rpcMsg = {.msgType = TSDB_MSG_TYPE_CONFIG_DNODE_IN,
|
||||
.pCont = pCfgDnode,
|
||||
.contLen = sizeof(SCfgDnodeMsg),
|
||||
.ahandle = pMsg->rpcMsg.ahandle};
|
||||
|
||||
mInfo("dnode:%d, is configured", pCfg->dnodeId);
|
||||
mInfo("dnode:%d, app:%p config:%s req send to dnode", pCfg->dnodeId, rpcMsg.ahandle, pCfg->config);
|
||||
mndSendMsgToDnode(pMnode, &epSet, &rpcMsg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndProcessConfigDnodeRsp(SMnodeMsg *pMsg) { mInfo("cfg dnode rsp is received"); }
|
||||
static int32_t mndProcessConfigDnodeRsp(SMnodeMsg *pMsg) {
|
||||
mInfo("app:%p config rsp from dnode", pMsg->rpcMsg.ahandle);
|
||||
}
|
||||
|
||||
static int32_t mndGetConfigMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) {
|
||||
int32_t cols = 0;
|
||||
|
@ -600,8 +604,7 @@ static int32_t mndGetConfigMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg
|
|||
|
||||
pShow->numOfRows = TSDB_CONFIG_NUMBER;
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
pShow->pIter = NULL;
|
||||
strcpy(pMeta->tableFname, mndShowStr(pShow->type));
|
||||
strcpy(pMeta->tbFname, mndShowStr(pShow->type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -676,7 +679,7 @@ static int32_t mndGetDnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *
|
|||
|
||||
pShow->bytes[cols] = 2;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
|
||||
strcpy(pSchema[cols].name, "cores");
|
||||
strcpy(pSchema[cols].name, "max vnodes");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
|
@ -708,7 +711,7 @@ static int32_t mndGetDnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *
|
|||
|
||||
pShow->numOfRows = sdbGetSize(pSdb, SDB_DNODE);
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
strcpy(pMeta->tableFname, mndShowStr(pShow->type));
|
||||
strcpy(pMeta->tbFname, mndShowStr(pShow->type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -740,7 +743,7 @@ static int32_t mndRetrieveDnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, i
|
|||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int16_t *)pWrite = pDnode->numOfCores;
|
||||
*(int16_t *)pWrite = pDnode->numOfSupportVnodes;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
|
@ -753,7 +756,11 @@ static int32_t mndRetrieveDnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, i
|
|||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
STR_TO_VARSTR(pWrite, offlineReason[pDnode->offlineReason]);
|
||||
if (pDnode->status == DND_STATUS_READY) {
|
||||
STR_TO_VARSTR(pWrite, "");
|
||||
} else {
|
||||
STR_TO_VARSTR(pWrite, offlineReason[pDnode->offlineReason]);
|
||||
}
|
||||
cols++;
|
||||
|
||||
numOfRows++;
|
||||
|
|
|
@ -429,7 +429,7 @@ static int32_t mndGetFuncMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *p
|
|||
|
||||
pShow->numOfRows = sdbGetSize(pSdb, SDB_FUNC);
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
strcpy(pMeta->tableFname, "show funcs");
|
||||
strcpy(pMeta->tbFname, "show funcs");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -405,7 +405,7 @@ static int32_t mndGetMnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *
|
|||
|
||||
pShow->numOfRows = sdbGetSize(pSdb, SDB_MNODE);
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
strcpy(pMeta->tableFname, mndShowStr(pShow->type));
|
||||
strcpy(pMeta->tbFname, mndShowStr(pShow->type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ typedef struct {
|
|||
char user[TSDB_USER_LEN];
|
||||
char app[TSDB_APP_NAME_LEN]; // app name that invokes taosc
|
||||
int32_t pid; // pid of app that invokes taosc
|
||||
int64_t appStartTime; // app start time
|
||||
int32_t id;
|
||||
int8_t killed;
|
||||
int8_t align;
|
||||
|
@ -44,7 +45,7 @@ typedef struct {
|
|||
SQueryDesc *pQueries;
|
||||
} SConnObj;
|
||||
|
||||
static SConnObj *mndCreateConn(SMnode *pMnode, char *user, uint32_t ip, uint16_t port, int32_t pid, const char *app);
|
||||
static SConnObj *mndCreateConn(SMnode *pMnode, char *user, uint32_t ip, uint16_t port, int32_t pid, const char *app, int64_t startTime);
|
||||
static void mndFreeConn(SConnObj *pConn);
|
||||
static SConnObj *mndAcquireConn(SMnode *pMnode, int32_t connId);
|
||||
static void mndReleaseConn(SMnode *pMnode, SConnObj *pConn);
|
||||
|
@ -102,13 +103,14 @@ void mndCleanupProfile(SMnode *pMnode) {
|
|||
}
|
||||
}
|
||||
|
||||
static SConnObj *mndCreateConn(SMnode *pMnode, char *user, uint32_t ip, uint16_t port, int32_t pid, const char *app) {
|
||||
static SConnObj *mndCreateConn(SMnode *pMnode, char *user, uint32_t ip, uint16_t port, int32_t pid, const char *app, int64_t startTime) {
|
||||
SProfileMgmt *pMgmt = &pMnode->profileMgmt;
|
||||
|
||||
int32_t connId = atomic_add_fetch_32(&pMgmt->connId, 1);
|
||||
if (connId == 0) atomic_add_fetch_32(&pMgmt->connId, 1);
|
||||
|
||||
SConnObj connObj = {.pid = pid,
|
||||
.appStartTime = startTime,
|
||||
.id = connId,
|
||||
.killed = 0,
|
||||
.port = port,
|
||||
|
@ -195,6 +197,7 @@ static int32_t mndProcessConnectMsg(SMnodeMsg *pMsg) {
|
|||
SMnode *pMnode = pMsg->pMnode;
|
||||
SConnectMsg *pReq = pMsg->rpcMsg.pCont;
|
||||
pReq->pid = htonl(pReq->pid);
|
||||
pReq->startTime = htobe64(pReq->startTime);
|
||||
|
||||
SRpcConnInfo info = {0};
|
||||
if (rpcGetConnInfo(pMsg->rpcMsg.handle, &info) != 0) {
|
||||
|
@ -216,7 +219,7 @@ static int32_t mndProcessConnectMsg(SMnodeMsg *pMsg) {
|
|||
mndReleaseDb(pMnode, pDb);
|
||||
}
|
||||
|
||||
SConnObj *pConn = mndCreateConn(pMnode, info.user, info.clientIp, info.clientPort, pReq->pid, pReq->app);
|
||||
SConnObj *pConn = mndCreateConn(pMnode, info.user, info.clientIp, info.clientPort, pReq->pid, pReq->app, pReq->startTime);
|
||||
if (pConn == NULL) {
|
||||
mError("user:%s, failed to login from %s while create connection since %s", pMsg->user, ip, terrstr());
|
||||
return -1;
|
||||
|
@ -233,9 +236,7 @@ static int32_t mndProcessConnectMsg(SMnodeMsg *pMsg) {
|
|||
SUserObj *pUser = mndAcquireUser(pMnode, pMsg->user);
|
||||
if (pUser != NULL) {
|
||||
pRsp->acctId = htonl(pUser->acctId);
|
||||
pRsp->superAuth = pUser->superAuth;
|
||||
pRsp->readAuth = pUser->readAuth;
|
||||
pRsp->writeAuth = pUser->writeAuth;
|
||||
pRsp->superUser = pUser->superUser;
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
}
|
||||
|
||||
|
@ -246,7 +247,8 @@ static int32_t mndProcessConnectMsg(SMnodeMsg *pMsg) {
|
|||
|
||||
pMsg->contLen = sizeof(SConnectRsp);
|
||||
pMsg->pCont = pRsp;
|
||||
mDebug("user:%s, login from %s, conn:%d", info.user, ip, pConn->id);
|
||||
|
||||
mDebug("user:%s, login from %s, conn:%d, app:%s", info.user, ip, pConn->id, pReq->app);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -301,7 +303,7 @@ static int32_t mndProcessHeartBeatMsg(SMnodeMsg *pMsg) {
|
|||
|
||||
SConnObj *pConn = mndAcquireConn(pMnode, pReq->connId);
|
||||
if (pConn == NULL) {
|
||||
pConn = mndCreateConn(pMnode, info.user, info.clientIp, info.clientPort, pReq->pid, pReq->app);
|
||||
pConn = mndCreateConn(pMnode, info.user, info.clientIp, info.clientPort, pReq->pid, pReq->app, 0);
|
||||
if (pConn == NULL) {
|
||||
mError("user:%s, conn:%d is freed and failed to create new conn since %s", pMsg->user, pReq->connId, terrstr());
|
||||
return -1;
|
||||
|
@ -368,7 +370,7 @@ static int32_t mndProcessKillQueryMsg(SMnodeMsg *pMsg) {
|
|||
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, pMsg->user);
|
||||
if (pUser == NULL) return 0;
|
||||
if (!pUser->superAuth) {
|
||||
if (!pUser->superUser) {
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
terrno = TSDB_CODE_MND_NO_RIGHTS;
|
||||
return -1;
|
||||
|
@ -399,7 +401,7 @@ static int32_t mndProcessKillStreamMsg(SMnodeMsg *pMsg) {
|
|||
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, pMsg->user);
|
||||
if (pUser == NULL) return 0;
|
||||
if (!pUser->superAuth) {
|
||||
if (!pUser->superUser) {
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
terrno = TSDB_CODE_MND_NO_RIGHTS;
|
||||
return -1;
|
||||
|
@ -430,7 +432,7 @@ static int32_t mndProcessKillConnectionMsg(SMnodeMsg *pMsg) {
|
|||
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, pMsg->user);
|
||||
if (pUser == NULL) return 0;
|
||||
if (!pUser->superAuth) {
|
||||
if (!pUser->superUser) {
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
terrno = TSDB_CODE_MND_NO_RIGHTS;
|
||||
return -1;
|
||||
|
@ -459,7 +461,7 @@ static int32_t mndGetConnsMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *
|
|||
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, pMsg->user);
|
||||
if (pUser == NULL) return 0;
|
||||
if (!pUser->superAuth) {
|
||||
if (!pUser->superUser) {
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
terrno = TSDB_CODE_MND_NO_RIGHTS;
|
||||
return -1;
|
||||
|
@ -587,7 +589,7 @@ static int32_t mndGetQueryMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *
|
|||
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, pMsg->user);
|
||||
if (pUser == NULL) return 0;
|
||||
if (!pUser->superAuth) {
|
||||
if (!pUser->superUser) {
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
terrno = TSDB_CODE_MND_NO_RIGHTS;
|
||||
return -1;
|
||||
|
@ -803,7 +805,7 @@ static int32_t mndGetStreamMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg
|
|||
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, pMsg->user);
|
||||
if (pUser == NULL) return 0;
|
||||
if (!pUser->superAuth) {
|
||||
if (!pUser->superUser) {
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
terrno = TSDB_CODE_MND_NO_RIGHTS;
|
||||
return -1;
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "mndShow.h"
|
||||
|
||||
#define SHOW_STEP_SIZE 100
|
||||
|
||||
static SShowObj *mndCreateShowObj(SMnode *pMnode, SShowMsg *pMsg);
|
||||
static void mndFreeShowObj(SShowObj *pShow);
|
||||
static SShowObj *mndAcquireShowObj(SMnode *pMnode, int32_t showId);
|
||||
|
@ -211,7 +213,7 @@ static int32_t mndProcessRetrieveMsg(SMnodeMsg *pMnodeMsg) {
|
|||
}
|
||||
|
||||
/* return no more than 100 tables in one round trip */
|
||||
if (rowsToRead > 100) rowsToRead = 100;
|
||||
if (rowsToRead > SHOW_STEP_SIZE) rowsToRead = SHOW_STEP_SIZE;
|
||||
|
||||
/*
|
||||
* the actual number of table may be larger than the value of pShow->numOfRows, if a query is
|
||||
|
@ -220,7 +222,7 @@ static int32_t mndProcessRetrieveMsg(SMnodeMsg *pMnodeMsg) {
|
|||
if (rowsToRead < 0) rowsToRead = 0;
|
||||
size = pShow->rowSize * rowsToRead;
|
||||
|
||||
size += 100;
|
||||
size += SHOW_STEP_SIZE;
|
||||
SRetrieveTableRsp *pRsp = rpcMallocCont(size);
|
||||
if (pRsp == NULL) {
|
||||
mndReleaseShowObj(pShow, false);
|
||||
|
@ -270,7 +272,7 @@ char *mndShowStr(int32_t showType) {
|
|||
return "show mnodes";
|
||||
case TSDB_MGMT_TABLE_VGROUP:
|
||||
return "show vgroups";
|
||||
case TSDB_MGMT_TABLE_STABLE:
|
||||
case TSDB_MGMT_TABLE_STB:
|
||||
return "show stables";
|
||||
case TSDB_MGMT_TABLE_MODULE:
|
||||
return "show modules";
|
||||
|
|
|
@ -1,427 +0,0 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndStable.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndMnode.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndTrans.h"
|
||||
#include "mndUser.h"
|
||||
#include "mndDb.h"
|
||||
#include "tname.h"
|
||||
|
||||
#define TSDB_STABLE_VER_NUM 1
|
||||
#define TSDB_STABLE_RESERVE_SIZE 64
|
||||
|
||||
static SSdbRaw *mndStableActionEncode(SStableObj *pStb);
|
||||
static SSdbRow *mndStableActionDecode(SSdbRaw *pRaw);
|
||||
static int32_t mndStableActionInsert(SSdb *pSdb, SStableObj *pStb);
|
||||
static int32_t mndStableActionDelete(SSdb *pSdb, SStableObj *pStb);
|
||||
static int32_t mndStableActionUpdate(SSdb *pSdb, SStableObj *pOldStb, SStableObj *pNewStb);
|
||||
static int32_t mndProcessCreateStableMsg(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessAlterStableMsg(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessDropStableMsg(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessCreateStableInRsp(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessAlterStableInRsp(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessDropStableInRsp(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessStableMetaMsg(SMnodeMsg *pMsg);
|
||||
static int32_t mndGetStableMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta);
|
||||
static int32_t mndRetrieveStables(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows);
|
||||
static void mndCancelGetNextStable(SMnode *pMnode, void *pIter);
|
||||
|
||||
int32_t mndInitStable(SMnode *pMnode) {
|
||||
SSdbTable table = {.sdbType = SDB_STABLE,
|
||||
.keyType = SDB_KEY_BINARY,
|
||||
.encodeFp = (SdbEncodeFp)mndStableActionEncode,
|
||||
.decodeFp = (SdbDecodeFp)mndStableActionDecode,
|
||||
.insertFp = (SdbInsertFp)mndStableActionInsert,
|
||||
.updateFp = (SdbUpdateFp)mndStableActionUpdate,
|
||||
.deleteFp = (SdbDeleteFp)mndStableActionDelete};
|
||||
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_CREATE_STABLE, mndProcessCreateStableMsg);
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_ALTER_STABLE, mndProcessAlterStableMsg);
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_DROP_STABLE, mndProcessDropStableMsg);
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_CREATE_STABLE_IN_RSP, mndProcessCreateStableInRsp);
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_ALTER_STABLE_IN_RSP, mndProcessAlterStableInRsp);
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_DROP_STABLE_IN_RSP, mndProcessDropStableInRsp);
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_TABLE_META, mndProcessStableMetaMsg);
|
||||
|
||||
mndAddShowMetaHandle(pMnode, TSDB_MGMT_TABLE_STABLE, mndGetStableMeta);
|
||||
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_STABLE, mndRetrieveStables);
|
||||
mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_STABLE, mndCancelGetNextStable);
|
||||
|
||||
return sdbSetTable(pMnode->pSdb, table);
|
||||
}
|
||||
|
||||
void mndCleanupStable(SMnode *pMnode) {}
|
||||
|
||||
static SSdbRaw *mndStableActionEncode(SStableObj *pStb) {
|
||||
int32_t size = sizeof(SStableObj) + (pStb->numOfColumns + pStb->numOfTags) * sizeof(SSchema);
|
||||
SSdbRaw *pRaw = sdbAllocRaw(SDB_STABLE, TSDB_STABLE_VER_NUM, size);
|
||||
if (pRaw == NULL) return NULL;
|
||||
|
||||
int32_t dataPos = 0;
|
||||
SDB_SET_BINARY(pRaw, dataPos, pStb->name, TSDB_TABLE_NAME_LEN)
|
||||
SDB_SET_INT64(pRaw, dataPos, pStb->createdTime)
|
||||
SDB_SET_INT64(pRaw, dataPos, pStb->updateTime)
|
||||
SDB_SET_INT64(pRaw, dataPos, pStb->uid)
|
||||
SDB_SET_INT64(pRaw, dataPos, pStb->version)
|
||||
SDB_SET_INT32(pRaw, dataPos, pStb->numOfColumns)
|
||||
SDB_SET_INT32(pRaw, dataPos, pStb->numOfTags)
|
||||
|
||||
for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
|
||||
SSchema *pSchema = &pStb->columnSchema[i];
|
||||
SDB_SET_INT8(pRaw, dataPos, pSchema->type);
|
||||
SDB_SET_INT32(pRaw, dataPos, pSchema->colId);
|
||||
SDB_SET_INT32(pRaw, dataPos, pSchema->bytes);
|
||||
SDB_SET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pStb->numOfTags; ++i) {
|
||||
SSchema *pSchema = &pStb->tagSchema[i];
|
||||
SDB_SET_INT8(pRaw, dataPos, pSchema->type);
|
||||
SDB_SET_INT32(pRaw, dataPos, pSchema->colId);
|
||||
SDB_SET_INT32(pRaw, dataPos, pSchema->bytes);
|
||||
SDB_SET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN);
|
||||
}
|
||||
|
||||
SDB_SET_RESERVE(pRaw, dataPos, TSDB_STABLE_RESERVE_SIZE)
|
||||
SDB_SET_DATALEN(pRaw, dataPos);
|
||||
|
||||
return pRaw;
|
||||
}
|
||||
|
||||
static SSdbRow *mndStableActionDecode(SSdbRaw *pRaw) {
|
||||
int8_t sver = 0;
|
||||
if (sdbGetRawSoftVer(pRaw, &sver) != 0) return NULL;
|
||||
|
||||
if (sver != TSDB_STABLE_VER_NUM) {
|
||||
mError("failed to decode stable since %s", terrstr());
|
||||
terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t size = sizeof(SStableObj) + TSDB_MAX_COLUMNS * sizeof(SSchema);
|
||||
SSdbRow *pRow = sdbAllocRow(size);
|
||||
SStableObj *pStb = sdbGetRowObj(pRow);
|
||||
if (pStb == NULL) return NULL;
|
||||
|
||||
int32_t dataPos = 0;
|
||||
SDB_GET_BINARY(pRaw, pRow, dataPos, pStb->name, TSDB_TABLE_NAME_LEN)
|
||||
SDB_GET_INT64(pRaw, pRow, dataPos, &pStb->createdTime)
|
||||
SDB_GET_INT64(pRaw, pRow, dataPos, &pStb->updateTime)
|
||||
SDB_GET_INT64(pRaw, pRow, dataPos, &pStb->uid)
|
||||
SDB_GET_INT32(pRaw, pRow, dataPos, &pStb->version)
|
||||
SDB_GET_INT32(pRaw, pRow, dataPos, &pStb->numOfColumns)
|
||||
SDB_GET_INT32(pRaw, pRow, dataPos, &pStb->numOfTags)
|
||||
|
||||
pStb->columnSchema = calloc(pStb->numOfColumns, sizeof(SSchema));
|
||||
pStb->tagSchema = calloc(pStb->numOfTags, sizeof(SSchema));
|
||||
|
||||
for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
|
||||
SSchema *pSchema = &pStb->columnSchema[i];
|
||||
SDB_GET_INT8(pRaw, pRow, dataPos, &pSchema->type);
|
||||
SDB_GET_INT32(pRaw, pRow, dataPos, &pSchema->colId);
|
||||
SDB_GET_INT32(pRaw, pRow, dataPos, &pSchema->bytes);
|
||||
SDB_GET_BINARY(pRaw, pRow, dataPos, pSchema->name, TSDB_COL_NAME_LEN);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pStb->numOfTags; ++i) {
|
||||
SSchema *pSchema = &pStb->tagSchema[i];
|
||||
SDB_GET_INT8(pRaw, pRow, dataPos, &pSchema->type);
|
||||
SDB_GET_INT32(pRaw, pRow, dataPos, &pSchema->colId);
|
||||
SDB_GET_INT32(pRaw, pRow, dataPos, &pSchema->bytes);
|
||||
SDB_GET_BINARY(pRaw, pRow, dataPos, pSchema->name, TSDB_COL_NAME_LEN);
|
||||
}
|
||||
|
||||
SDB_GET_RESERVE(pRaw, pRow, dataPos, TSDB_STABLE_RESERVE_SIZE)
|
||||
|
||||
return pRow;
|
||||
}
|
||||
|
||||
static int32_t mndStableActionInsert(SSdb *pSdb, SStableObj *pStb) {
|
||||
mTrace("stable:%s, perform insert action", pStb->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndStableActionDelete(SSdb *pSdb, SStableObj *pStb) {
|
||||
mTrace("stable:%s, perform delete action", pStb->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndStableActionUpdate(SSdb *pSdb, SStableObj *pOldStb, SStableObj *pNewStb) {
|
||||
mTrace("stable:%s, perform update action", pOldStb->name);
|
||||
atomic_exchange_32(&pOldStb->updateTime, pNewStb->updateTime);
|
||||
atomic_exchange_32(&pOldStb->version, pNewStb->version);
|
||||
|
||||
taosWLockLatch(&pOldStb->lock);
|
||||
int32_t numOfTags = pNewStb->numOfTags;
|
||||
int32_t tagSize = numOfTags * sizeof(SSchema);
|
||||
int32_t numOfColumns = pNewStb->numOfColumns;
|
||||
int32_t columnSize = numOfColumns * sizeof(SSchema);
|
||||
|
||||
if (pOldStb->numOfTags < numOfTags) {
|
||||
pOldStb->tagSchema = malloc(tagSize);
|
||||
}
|
||||
if (pOldStb->numOfColumns < numOfColumns) {
|
||||
pOldStb->columnSchema = malloc(columnSize);
|
||||
}
|
||||
|
||||
memcpy(pOldStb->tagSchema, pNewStb->tagSchema, tagSize);
|
||||
memcpy(pOldStb->columnSchema, pNewStb->columnSchema, columnSize);
|
||||
taosWUnLockLatch(&pOldStb->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SStableObj *mndAcquireStb(SMnode *pMnode, char *stbName) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
return sdbAcquire(pSdb, SDB_STABLE, stbName);
|
||||
}
|
||||
|
||||
void mndReleaseStb(SMnode *pMnode, SStableObj *pStb) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
sdbRelease(pSdb, pStb);
|
||||
}
|
||||
|
||||
static int32_t mndProcessCreateStableMsg(SMnodeMsg *pMsg) { return 0; }
|
||||
|
||||
static int32_t mndProcessCreateStableInRsp(SMnodeMsg *pMsg) { return 0; }
|
||||
|
||||
static int32_t mndProcessAlterStableMsg(SMnodeMsg *pMsg) { return 0; }
|
||||
|
||||
static int32_t mndProcessAlterStableInRsp(SMnodeMsg *pMsg) { return 0; }
|
||||
|
||||
static int32_t mndProcessDropStableMsg(SMnodeMsg *pMsg) { return 0; }
|
||||
|
||||
static int32_t mndProcessDropStableInRsp(SMnodeMsg *pMsg) { return 0; }
|
||||
|
||||
static SDbObj *mndGetDbByStbName(SMnode *pMnode, char *stbName) {
|
||||
SName name = {0};
|
||||
tNameFromString(&name, stbName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
|
||||
char db[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameGetFullDbName(&name, db);
|
||||
|
||||
return mndAcquireDb(pMnode, db);
|
||||
}
|
||||
|
||||
static int32_t mndProcessStableMetaMsg(SMnodeMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
SStableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
|
||||
|
||||
mDebug("stable:%s, start to retrieve meta", pInfo->name);
|
||||
|
||||
SDbObj *pDb = mndGetDbByStbName(pMnode, pInfo->name);
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
|
||||
mError("stable:%s, failed to retrieve meta since %s", pInfo->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SStableObj *pStb = mndAcquireStb(pMnode, pInfo->name);
|
||||
if (pStb == NULL) {
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
terrno = TSDB_CODE_MND_INVALID_TABLE_NAME;
|
||||
mError("stable:%s, failed to get meta since %s", pInfo->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t contLen = sizeof(STableMetaMsg) + (pStb->numOfColumns + pStb->numOfTags) * sizeof(SSchema);
|
||||
STableMetaMsg *pMeta = rpcMallocCont(contLen);
|
||||
if (pMeta == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
mError("stable:%s, failed to get meta since %s", pInfo->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(pMeta->stableFname, pStb->name, TSDB_TABLE_FNAME_LEN);
|
||||
pMeta->numOfTags = htonl(pStb->numOfTags);
|
||||
pMeta->numOfColumns = htonl(pStb->numOfColumns);
|
||||
pMeta->precision = pDb->cfg.precision;
|
||||
pMeta->tableType = TSDB_SUPER_TABLE;
|
||||
pMeta->update = pDb->cfg.update;
|
||||
pMeta->sversion = htonl(pStb->version);
|
||||
pMeta->suid = htonl(pStb->uid);
|
||||
|
||||
for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
|
||||
SSchema *pSchema = &pMeta->pSchema[i];
|
||||
SSchema *pColumn = &pStb->columnSchema[i];
|
||||
memcpy(pSchema->name, pColumn->name, TSDB_COL_NAME_LEN);
|
||||
pSchema->type = pColumn->type;
|
||||
pSchema->colId = htonl(pColumn->colId);
|
||||
pSchema->bytes = htonl(pColumn->bytes);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pStb->numOfTags; ++i) {
|
||||
SSchema *pSchema = &pMeta->pSchema[i + pStb->numOfColumns];
|
||||
SSchema *pTag = &pStb->tagSchema[i];
|
||||
memcpy(pSchema->name, pTag->name, TSDB_COL_NAME_LEN);
|
||||
pSchema->type = pTag->type;
|
||||
pSchema->colId = htons(pTag->colId);
|
||||
pSchema->bytes = htonl(pTag->bytes);
|
||||
}
|
||||
|
||||
pMsg->pCont = pMeta;
|
||||
pMsg->contLen = contLen;
|
||||
|
||||
mDebug("stable:%s, meta is retrieved, cols:%d tags:%d", pInfo->name, pStb->numOfColumns, pStb->numOfTags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndGetNumOfStables(SMnode *pMnode, char *dbName, int32_t *pNumOfStables) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
||||
SDbObj *pDb = mndAcquireDb(pMnode, dbName);
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t numOfStables = 0;
|
||||
void *pIter = NULL;
|
||||
while (1) {
|
||||
SStableObj *pStb = NULL;
|
||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pStb);
|
||||
if (pIter == NULL) break;
|
||||
|
||||
if (strcmp(pStb->db, dbName) == 0) {
|
||||
numOfStables++;
|
||||
}
|
||||
|
||||
sdbRelease(pSdb, pStb);
|
||||
}
|
||||
|
||||
*pNumOfStables = numOfStables;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndGetStableMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
||||
if (mndGetNumOfStables(pMnode, pShow->db, &pShow->numOfRows) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t cols = 0;
|
||||
SSchema *pSchema = pMeta->pSchema;
|
||||
|
||||
pShow->bytes[cols] = TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||
strcpy(pSchema[cols].name, "name");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 8;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
strcpy(pSchema[cols].name, "create time");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 2;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
|
||||
strcpy(pSchema[cols].name, "columns");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 2;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
|
||||
strcpy(pSchema[cols].name, "tags");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pMeta->numOfColumns = htons(cols);
|
||||
pShow->numOfColumns = cols;
|
||||
|
||||
pShow->offset[0] = 0;
|
||||
for (int32_t i = 1; i < cols; ++i) {
|
||||
pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1];
|
||||
}
|
||||
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
strcpy(pMeta->tableFname, mndShowStr(pShow->type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mnodeExtractTableName(char* tableId, char* name) {
|
||||
int pos = -1;
|
||||
int num = 0;
|
||||
for (pos = 0; tableId[pos] != 0; ++pos) {
|
||||
if (tableId[pos] == '.') num++;
|
||||
if (num == 2) break;
|
||||
}
|
||||
|
||||
if (num == 2) {
|
||||
strcpy(name, tableId + pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t mndRetrieveStables(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
int32_t numOfRows = 0;
|
||||
SStableObj *pStb = NULL;
|
||||
int32_t cols = 0;
|
||||
char *pWrite;
|
||||
char prefix[64] = {0};
|
||||
|
||||
tstrncpy(prefix, pShow->db, 64);
|
||||
strcat(prefix, TS_PATH_DELIMITER);
|
||||
int32_t prefixLen = (int32_t)strlen(prefix);
|
||||
|
||||
while (numOfRows < rows) {
|
||||
pShow->pIter = sdbFetch(pSdb, SDB_STABLE, pShow->pIter, (void **)&pStb);
|
||||
if (pShow->pIter == NULL) break;
|
||||
|
||||
if (strncmp(pStb->name, prefix, prefixLen) != 0) {
|
||||
sdbRelease(pSdb, pStb);
|
||||
continue;
|
||||
}
|
||||
|
||||
cols = 0;
|
||||
|
||||
char stableName[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
memcpy(stableName, pStb->name + prefixLen, TSDB_TABLE_FNAME_LEN - prefixLen);
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
STR_TO_VARSTR(pWrite, stableName);
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int64_t *)pWrite = pStb->createdTime;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int16_t *)pWrite = pStb->numOfColumns;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int16_t *)pWrite = pStb->numOfTags;
|
||||
cols++;
|
||||
|
||||
numOfRows++;
|
||||
sdbRelease(pSdb, pStb);
|
||||
}
|
||||
|
||||
pShow->numOfReads += numOfRows;
|
||||
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||
return numOfRows;
|
||||
}
|
||||
|
||||
static void mndCancelGetNextStable(SMnode *pMnode, void *pIter) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
}
|
|
@ -0,0 +1,675 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndStb.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndMnode.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndTrans.h"
|
||||
#include "mndUser.h"
|
||||
#include "tname.h"
|
||||
|
||||
#define TSDB_STB_VER_NUM 1
|
||||
#define TSDB_STB_RESERVE_SIZE 64
|
||||
|
||||
static SSdbRaw *mndStbActionEncode(SStbObj *pStb);
|
||||
static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw);
|
||||
static int32_t mndStbActionInsert(SSdb *pSdb, SStbObj *pStb);
|
||||
static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb);
|
||||
static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOldStb, SStbObj *pNewStb);
|
||||
static int32_t mndProcessCreateStbMsg(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessAlterStbMsg(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessDropStbMsg(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessCreateStbInRsp(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessAlterStbInRsp(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessDropStbInRsp(SMnodeMsg *pMsg);
|
||||
static int32_t mndProcessStbMetaMsg(SMnodeMsg *pMsg);
|
||||
static int32_t mndGetStbMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta);
|
||||
static int32_t mndRetrieveStb(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows);
|
||||
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter);
|
||||
|
||||
int32_t mndInitStb(SMnode *pMnode) {
|
||||
SSdbTable table = {.sdbType = SDB_STB,
|
||||
.keyType = SDB_KEY_BINARY,
|
||||
.encodeFp = (SdbEncodeFp)mndStbActionEncode,
|
||||
.decodeFp = (SdbDecodeFp)mndStbActionDecode,
|
||||
.insertFp = (SdbInsertFp)mndStbActionInsert,
|
||||
.updateFp = (SdbUpdateFp)mndStbActionUpdate,
|
||||
.deleteFp = (SdbDeleteFp)mndStbActionDelete};
|
||||
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_CREATE_STB, mndProcessCreateStbMsg);
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_ALTER_STB, mndProcessAlterStbMsg);
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_DROP_STB, mndProcessDropStbMsg);
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_CREATE_STB_IN_RSP, mndProcessCreateStbInRsp);
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_ALTER_STB_IN_RSP, mndProcessAlterStbInRsp);
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_DROP_STB_IN_RSP, mndProcessDropStbInRsp);
|
||||
mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_TABLE_META, mndProcessStbMetaMsg);
|
||||
|
||||
mndAddShowMetaHandle(pMnode, TSDB_MGMT_TABLE_STB, mndGetStbMeta);
|
||||
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_STB, mndRetrieveStb);
|
||||
mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_STB, mndCancelGetNextStb);
|
||||
|
||||
return sdbSetTable(pMnode->pSdb, table);
|
||||
}
|
||||
|
||||
void mndCleanupStb(SMnode *pMnode) {}
|
||||
|
||||
static SSdbRaw *mndStbActionEncode(SStbObj *pStb) {
|
||||
int32_t size = sizeof(SStbObj) + (pStb->numOfColumns + pStb->numOfTags) * sizeof(SSchema);
|
||||
SSdbRaw *pRaw = sdbAllocRaw(SDB_STB, TSDB_STB_VER_NUM, size);
|
||||
if (pRaw == NULL) return NULL;
|
||||
|
||||
int32_t dataPos = 0;
|
||||
SDB_SET_BINARY(pRaw, dataPos, pStb->name, TSDB_TABLE_NAME_LEN)
|
||||
SDB_SET_INT64(pRaw, dataPos, pStb->createdTime)
|
||||
SDB_SET_INT64(pRaw, dataPos, pStb->updateTime)
|
||||
SDB_SET_INT64(pRaw, dataPos, pStb->uid)
|
||||
SDB_SET_INT64(pRaw, dataPos, pStb->version)
|
||||
SDB_SET_INT32(pRaw, dataPos, pStb->numOfColumns)
|
||||
SDB_SET_INT32(pRaw, dataPos, pStb->numOfTags)
|
||||
|
||||
int32_t totalCols = pStb->numOfColumns + pStb->numOfTags;
|
||||
for (int32_t i = 0; i < totalCols; ++i) {
|
||||
SSchema *pSchema = &pStb->pSchema[i];
|
||||
SDB_SET_INT8(pRaw, dataPos, pSchema->type);
|
||||
SDB_SET_INT32(pRaw, dataPos, pSchema->colId);
|
||||
SDB_SET_INT32(pRaw, dataPos, pSchema->bytes);
|
||||
SDB_SET_BINARY(pRaw, dataPos, pSchema->name, TSDB_COL_NAME_LEN);
|
||||
}
|
||||
|
||||
SDB_SET_RESERVE(pRaw, dataPos, TSDB_STB_RESERVE_SIZE)
|
||||
SDB_SET_DATALEN(pRaw, dataPos);
|
||||
|
||||
return pRaw;
|
||||
}
|
||||
|
||||
static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
|
||||
int8_t sver = 0;
|
||||
if (sdbGetRawSoftVer(pRaw, &sver) != 0) return NULL;
|
||||
|
||||
if (sver != TSDB_STB_VER_NUM) {
|
||||
mError("failed to decode stable since %s", terrstr());
|
||||
terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t size = sizeof(SStbObj) + TSDB_MAX_COLUMNS * sizeof(SSchema);
|
||||
SSdbRow *pRow = sdbAllocRow(size);
|
||||
SStbObj *pStb = sdbGetRowObj(pRow);
|
||||
if (pStb == NULL) return NULL;
|
||||
|
||||
int32_t dataPos = 0;
|
||||
SDB_GET_BINARY(pRaw, pRow, dataPos, pStb->name, TSDB_TABLE_NAME_LEN)
|
||||
SDB_GET_INT64(pRaw, pRow, dataPos, &pStb->createdTime)
|
||||
SDB_GET_INT64(pRaw, pRow, dataPos, &pStb->updateTime)
|
||||
SDB_GET_INT64(pRaw, pRow, dataPos, &pStb->uid)
|
||||
SDB_GET_INT32(pRaw, pRow, dataPos, &pStb->version)
|
||||
SDB_GET_INT32(pRaw, pRow, dataPos, &pStb->numOfColumns)
|
||||
SDB_GET_INT32(pRaw, pRow, dataPos, &pStb->numOfTags)
|
||||
|
||||
int32_t totalCols = pStb->numOfColumns + pStb->numOfTags;
|
||||
pStb->pSchema = calloc(totalCols, sizeof(SSchema));
|
||||
|
||||
for (int32_t i = 0; i < totalCols; ++i) {
|
||||
SSchema *pSchema = &pStb->pSchema[i];
|
||||
SDB_GET_INT8(pRaw, pRow, dataPos, &pSchema->type);
|
||||
SDB_GET_INT32(pRaw, pRow, dataPos, &pSchema->colId);
|
||||
SDB_GET_INT32(pRaw, pRow, dataPos, &pSchema->bytes);
|
||||
SDB_GET_BINARY(pRaw, pRow, dataPos, pSchema->name, TSDB_COL_NAME_LEN);
|
||||
}
|
||||
|
||||
SDB_GET_RESERVE(pRaw, pRow, dataPos, TSDB_STB_RESERVE_SIZE)
|
||||
|
||||
return pRow;
|
||||
}
|
||||
|
||||
static int32_t mndStbActionInsert(SSdb *pSdb, SStbObj *pStb) {
|
||||
mTrace("stb:%s, perform insert action", pStb->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb) {
|
||||
mTrace("stb:%s, perform delete action", pStb->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndStbActionUpdate(SSdb *pSdb, SStbObj *pOldStb, SStbObj *pNewStb) {
|
||||
mTrace("stb:%s, perform update action", pOldStb->name);
|
||||
atomic_exchange_32(&pOldStb->updateTime, pNewStb->updateTime);
|
||||
atomic_exchange_32(&pOldStb->version, pNewStb->version);
|
||||
|
||||
taosWLockLatch(&pOldStb->lock);
|
||||
int32_t totalCols = pNewStb->numOfTags + pNewStb->numOfColumns;
|
||||
int32_t totalSize = totalCols * sizeof(SSchema);
|
||||
|
||||
if (pOldStb->numOfTags + pOldStb->numOfColumns < totalCols) {
|
||||
pOldStb->pSchema = malloc(totalSize);
|
||||
}
|
||||
|
||||
memcpy(pOldStb->pSchema, pNewStb->pSchema, totalSize);
|
||||
taosWUnLockLatch(&pOldStb->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SStbObj *mndAcquireStb(SMnode *pMnode, char *stbName) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
return sdbAcquire(pSdb, SDB_STB, stbName);
|
||||
}
|
||||
|
||||
void mndReleaseStb(SMnode *pMnode, SStbObj *pStb) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
sdbRelease(pSdb, pStb);
|
||||
}
|
||||
|
||||
static SDbObj *mndAcquireDbByStb(SMnode *pMnode, char *stbName) {
|
||||
SName name = {0};
|
||||
tNameFromString(&name, stbName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
|
||||
char db[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameGetFullDbName(&name, db);
|
||||
|
||||
return mndAcquireDb(pMnode, db);
|
||||
}
|
||||
|
||||
static int32_t mndCheckStbMsg(SCreateStbMsg *pCreate) {
|
||||
pCreate->numOfColumns = htonl(pCreate->numOfColumns);
|
||||
pCreate->numOfTags = htonl(pCreate->numOfTags);
|
||||
int32_t totalCols = pCreate->numOfColumns + pCreate->numOfTags;
|
||||
for (int32_t i = 0; i < totalCols; ++i) {
|
||||
SSchema *pSchema = &pCreate->pSchema[i];
|
||||
pSchema->colId = htonl(pSchema->colId);
|
||||
pSchema->bytes = htonl(pSchema->bytes);
|
||||
}
|
||||
|
||||
if (pCreate->igExists < 0 || pCreate->igExists > 1) {
|
||||
terrno = TSDB_CODE_MND_STB_INVALID_IGEXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pCreate->numOfColumns < TSDB_MIN_COLUMNS || pCreate->numOfColumns > TSDB_MAX_COLUMNS) {
|
||||
terrno = TSDB_CODE_MND_STB_INVALID_COLS_NUM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pCreate->numOfTags <= 0 || pCreate->numOfTags > TSDB_MAX_TAGS) {
|
||||
terrno = TSDB_CODE_MND_STB_INVALID_TAGS_NUM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t maxColId = (TSDB_MAX_COLUMNS + TSDB_MAX_TAGS);
|
||||
for (int32_t i = 0; i < totalCols; ++i) {
|
||||
SSchema *pSchema = &pCreate->pSchema[i];
|
||||
if (pSchema->type <= 0) {
|
||||
terrno = TSDB_CODE_MND_STB_INVALID_COL_TYPE;
|
||||
return -1;
|
||||
}
|
||||
if (pSchema->colId < 0 || pSchema->colId >= maxColId) {
|
||||
terrno = TSDB_CODE_MND_STB_INVALID_COL_ID;
|
||||
return -1;
|
||||
}
|
||||
if (pSchema->bytes <= 0) {
|
||||
terrno = TSDB_CODE_MND_STB_INVALID_COL_BYTES;
|
||||
return -1;
|
||||
}
|
||||
if (pSchema->name[0] == 0) {
|
||||
terrno = TSDB_CODE_MND_STB_INVALID_COL_NAME;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndCreateStb(SMnode *pMnode, SMnodeMsg *pMsg, SCreateStbMsg *pCreate, SDbObj *pDb) {
|
||||
SStbObj stbObj = {0};
|
||||
tstrncpy(stbObj.name, pCreate->name, TSDB_TABLE_FNAME_LEN);
|
||||
tstrncpy(stbObj.db, pDb->name, TSDB_FULL_DB_NAME_LEN);
|
||||
stbObj.createdTime = taosGetTimestampMs();
|
||||
stbObj.updateTime = stbObj.createdTime;
|
||||
stbObj.uid = mndGenerateUid(pCreate->name, TSDB_TABLE_FNAME_LEN);
|
||||
stbObj.version = 1;
|
||||
stbObj.numOfColumns = pCreate->numOfColumns;
|
||||
stbObj.numOfTags = pCreate->numOfTags;
|
||||
|
||||
int32_t totalCols = stbObj.numOfColumns + stbObj.numOfTags;
|
||||
int32_t totalSize = totalCols * sizeof(SSchema);
|
||||
stbObj.pSchema = malloc(totalSize);
|
||||
if (stbObj.pSchema == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
memcpy(stbObj.pSchema, pCreate->pSchema, totalSize);
|
||||
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, pMsg->rpcMsg.handle);
|
||||
if (pTrans == NULL) {
|
||||
mError("stb:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
mDebug("trans:%d, used to create stb:%s", pTrans->id, pCreate->name);
|
||||
|
||||
SSdbRaw *pRedoRaw = mndStbActionEncode(&stbObj);
|
||||
if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||
mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING);
|
||||
|
||||
SSdbRaw *pUndoRaw = mndStbActionEncode(&stbObj);
|
||||
if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) {
|
||||
mError("trans:%d, failed to append undo log since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED);
|
||||
|
||||
SSdbRaw *pCommitRaw = mndStbActionEncode(&stbObj);
|
||||
if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||
mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
|
||||
|
||||
if (mndTransPrepare(pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mndTransDrop(pTrans);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndProcessCreateStbMsg(SMnodeMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
SCreateStbMsg *pCreate = pMsg->rpcMsg.pCont;
|
||||
|
||||
mDebug("stb:%s, start to create", pCreate->name);
|
||||
|
||||
if (mndCheckStbMsg(pCreate) != 0) {
|
||||
mError("stb:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SStbObj *pStb = mndAcquireStb(pMnode, pCreate->name);
|
||||
if (pStb != NULL) {
|
||||
sdbRelease(pMnode->pSdb, pStb);
|
||||
if (pCreate->igExists) {
|
||||
mDebug("stb:%s, already exist, ignore exist is set", pCreate->name);
|
||||
return 0;
|
||||
} else {
|
||||
terrno = TSDB_CODE_MND_STB_ALREADY_EXIST;
|
||||
mError("db:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
SDbObj *pDb = mndAcquireDbByStb(pMnode, pCreate->name);
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
|
||||
mError("stb:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t code = mndCreateStb(pMnode, pMsg, pCreate, pDb);
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
|
||||
if (code != 0) {
|
||||
terrno = code;
|
||||
mError("stb:%s, failed to create since %s", pCreate->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
static int32_t mndProcessCreateStbInRsp(SMnodeMsg *pMsg) { return 0; }
|
||||
|
||||
static int32_t mndCheckAlterStbMsg(SAlterStbMsg *pAlter) {
|
||||
SSchema *pSchema = &pAlter->schema;
|
||||
pSchema->colId = htonl(pSchema->colId);
|
||||
pSchema->bytes = htonl(pSchema->bytes);
|
||||
|
||||
if (pSchema->type <= 0) {
|
||||
terrno = TSDB_CODE_MND_STB_INVALID_COL_TYPE;
|
||||
return -1;
|
||||
}
|
||||
if (pSchema->colId < 0 || pSchema->colId >= (TSDB_MAX_COLUMNS + TSDB_MAX_TAGS)) {
|
||||
terrno = TSDB_CODE_MND_STB_INVALID_COL_ID;
|
||||
return -1;
|
||||
}
|
||||
if (pSchema->bytes <= 0) {
|
||||
terrno = TSDB_CODE_MND_STB_INVALID_COL_BYTES;
|
||||
return -1;
|
||||
}
|
||||
if (pSchema->name[0] == 0) {
|
||||
terrno = TSDB_CODE_MND_STB_INVALID_COL_NAME;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndUpdateStb(SMnode *pMnode, SMnodeMsg *pMsg, SStbObj *pOldStb, SStbObj *pNewStb) { return 0; }
|
||||
|
||||
static int32_t mndProcessAlterStbMsg(SMnodeMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
SAlterStbMsg *pAlter = pMsg->rpcMsg.pCont;
|
||||
|
||||
mDebug("stb:%s, start to alter", pAlter->name);
|
||||
|
||||
if (mndCheckAlterStbMsg(pAlter) != 0) {
|
||||
mError("stb:%s, failed to alter since %s", pAlter->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SStbObj *pStb = mndAcquireStb(pMnode, pAlter->name);
|
||||
if (pStb == NULL) {
|
||||
terrno = TSDB_CODE_MND_STB_NOT_EXIST;
|
||||
mError("stb:%s, failed to alter since %s", pAlter->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SStbObj stbObj = {0};
|
||||
memcpy(&stbObj, pStb, sizeof(SStbObj));
|
||||
|
||||
int32_t code = mndUpdateStb(pMnode, pMsg, pStb, &stbObj);
|
||||
mndReleaseStb(pMnode, pStb);
|
||||
|
||||
if (code != 0) {
|
||||
mError("stb:%s, failed to alter since %s", pAlter->name, tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
static int32_t mndProcessAlterStbInRsp(SMnodeMsg *pMsg) { return 0; }
|
||||
|
||||
static int32_t mndDropStb(SMnode *pMnode, SMnodeMsg *pMsg, SStbObj *pStb) {
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, pMsg->rpcMsg.handle);
|
||||
if (pTrans == NULL) {
|
||||
mError("stb:%s, failed to drop since %s", pStb->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
mDebug("trans:%d, used to drop stb:%s", pTrans->id, pStb->name);
|
||||
|
||||
SSdbRaw *pRedoRaw = mndStbActionEncode(pStb);
|
||||
if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||
mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING);
|
||||
|
||||
SSdbRaw *pUndoRaw = mndStbActionEncode(pStb);
|
||||
if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) {
|
||||
mError("trans:%d, failed to append undo log since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pUndoRaw, SDB_STATUS_READY);
|
||||
|
||||
SSdbRaw *pCommitRaw = mndStbActionEncode(pStb);
|
||||
if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||
mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED);
|
||||
|
||||
if (mndTransPrepare(pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mndTransDrop(pTrans);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndProcessDropStbMsg(SMnodeMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
SDropStbMsg *pDrop = pMsg->rpcMsg.pCont;
|
||||
|
||||
mDebug("stb:%s, start to drop", pDrop->name);
|
||||
|
||||
SStbObj *pStb = mndAcquireStb(pMnode, pDrop->name);
|
||||
if (pStb == NULL) {
|
||||
if (pDrop->igNotExists) {
|
||||
mDebug("stb:%s, not exist, ignore not exist is set", pDrop->name);
|
||||
return 0;
|
||||
} else {
|
||||
terrno = TSDB_CODE_MND_STB_NOT_EXIST;
|
||||
mError("stb:%s, failed to drop since %s", pDrop->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t code = mndDropStb(pMnode, pMsg, pStb);
|
||||
mndReleaseStb(pMnode, pStb);
|
||||
|
||||
if (code != 0) {
|
||||
terrno = code;
|
||||
mError("stb:%s, failed to drop since %s", pDrop->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
static int32_t mndProcessDropStbInRsp(SMnodeMsg *pMsg) { return 0; }
|
||||
|
||||
static int32_t mndProcessStbMetaMsg(SMnodeMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
SStbInfoMsg *pInfo = pMsg->rpcMsg.pCont;
|
||||
|
||||
mDebug("stb:%s, start to retrieve meta", pInfo->name);
|
||||
|
||||
SDbObj *pDb = mndAcquireDbByStb(pMnode, pInfo->name);
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
|
||||
mError("stb:%s, failed to retrieve meta since %s", pInfo->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SStbObj *pStb = mndAcquireStb(pMnode, pInfo->name);
|
||||
if (pStb == NULL) {
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
terrno = TSDB_CODE_MND_INVALID_TABLE_NAME;
|
||||
mError("stb:%s, failed to get meta since %s", pInfo->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t contLen = sizeof(STableMetaMsg) + (pStb->numOfColumns + pStb->numOfTags) * sizeof(SSchema);
|
||||
STableMetaMsg *pMeta = rpcMallocCont(contLen);
|
||||
if (pMeta == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
mError("stb:%s, failed to get meta since %s", pInfo->name, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(pMeta->stbFname, pStb->name, TSDB_TABLE_FNAME_LEN);
|
||||
pMeta->numOfTags = htonl(pStb->numOfTags);
|
||||
pMeta->numOfColumns = htonl(pStb->numOfColumns);
|
||||
pMeta->precision = pDb->cfg.precision;
|
||||
pMeta->tableType = TSDB_SUPER_TABLE;
|
||||
pMeta->update = pDb->cfg.update;
|
||||
pMeta->sversion = htonl(pStb->version);
|
||||
pMeta->suid = htonl(pStb->uid);
|
||||
|
||||
for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
|
||||
SSchema *pSchema = &pMeta->pSchema[i];
|
||||
SSchema *pSrcSchema = &pStb->pSchema[i];
|
||||
memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
|
||||
pSchema->type = pSrcSchema->type;
|
||||
pSchema->colId = htonl(pSrcSchema->colId);
|
||||
pSchema->bytes = htonl(pSrcSchema->bytes);
|
||||
}
|
||||
|
||||
pMsg->pCont = pMeta;
|
||||
pMsg->contLen = contLen;
|
||||
|
||||
mDebug("stb:%s, meta is retrieved, cols:%d tags:%d", pInfo->name, pStb->numOfColumns, pStb->numOfTags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndGetNumOfStbs(SMnode *pMnode, char *dbName, int32_t *pNumOfStbs) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
||||
SDbObj *pDb = mndAcquireDb(pMnode, dbName);
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t numOfStbs = 0;
|
||||
void *pIter = NULL;
|
||||
while (1) {
|
||||
SStbObj *pStb = NULL;
|
||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pStb);
|
||||
if (pIter == NULL) break;
|
||||
|
||||
if (strcmp(pStb->db, dbName) == 0) {
|
||||
numOfStbs++;
|
||||
}
|
||||
|
||||
sdbRelease(pSdb, pStb);
|
||||
}
|
||||
|
||||
*pNumOfStbs = numOfStbs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndGetStbMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
||||
if (mndGetNumOfStbs(pMnode, pShow->db, &pShow->numOfRows) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t cols = 0;
|
||||
SSchema *pSchema = pMeta->pSchema;
|
||||
|
||||
pShow->bytes[cols] = TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||
strcpy(pSchema[cols].name, "name");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 8;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
strcpy(pSchema[cols].name, "create time");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 2;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
|
||||
strcpy(pSchema[cols].name, "columns");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 2;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
|
||||
strcpy(pSchema[cols].name, "tags");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pMeta->numOfColumns = htons(cols);
|
||||
pShow->numOfColumns = cols;
|
||||
|
||||
pShow->offset[0] = 0;
|
||||
for (int32_t i = 1; i < cols; ++i) {
|
||||
pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1];
|
||||
}
|
||||
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
strcpy(pMeta->tbFname, mndShowStr(pShow->type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mnodeExtractTableName(char *tableId, char *name) {
|
||||
int pos = -1;
|
||||
int num = 0;
|
||||
for (pos = 0; tableId[pos] != 0; ++pos) {
|
||||
if (tableId[pos] == '.') num++;
|
||||
if (num == 2) break;
|
||||
}
|
||||
|
||||
if (num == 2) {
|
||||
strcpy(name, tableId + pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t mndRetrieveStb(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows) {
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
int32_t numOfRows = 0;
|
||||
SStbObj *pStb = NULL;
|
||||
int32_t cols = 0;
|
||||
char *pWrite;
|
||||
char prefix[64] = {0};
|
||||
|
||||
tstrncpy(prefix, pShow->db, 64);
|
||||
strcat(prefix, TS_PATH_DELIMITER);
|
||||
int32_t prefixLen = (int32_t)strlen(prefix);
|
||||
|
||||
while (numOfRows < rows) {
|
||||
pShow->pIter = sdbFetch(pSdb, SDB_STB, pShow->pIter, (void **)&pStb);
|
||||
if (pShow->pIter == NULL) break;
|
||||
|
||||
if (strncmp(pStb->name, prefix, prefixLen) != 0) {
|
||||
sdbRelease(pSdb, pStb);
|
||||
continue;
|
||||
}
|
||||
|
||||
cols = 0;
|
||||
|
||||
char stbName[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
memcpy(stbName, pStb->name + prefixLen, TSDB_TABLE_FNAME_LEN - prefixLen);
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
STR_TO_VARSTR(pWrite, stbName);
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int64_t *)pWrite = pStb->createdTime;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int16_t *)pWrite = pStb->numOfColumns;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int16_t *)pWrite = pStb->numOfTags;
|
||||
cols++;
|
||||
|
||||
numOfRows++;
|
||||
sdbRelease(pSdb, pStb);
|
||||
}
|
||||
|
||||
pShow->numOfReads += numOfRows;
|
||||
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||
return numOfRows;
|
||||
}
|
||||
|
||||
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
}
|
|
@ -65,11 +65,9 @@ static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char
|
|||
taosEncryptPass((uint8_t *)pass, strlen(pass), userObj.pass);
|
||||
userObj.createdTime = taosGetTimestampMs();
|
||||
userObj.updateTime = userObj.createdTime;
|
||||
userObj.readAuth = 1;
|
||||
userObj.writeAuth = 1;
|
||||
|
||||
if (strcmp(user, TSDB_DEFAULT_USER) == 0) {
|
||||
userObj.superAuth = 1;
|
||||
userObj.superUser = 1;
|
||||
}
|
||||
|
||||
SSdbRaw *pRaw = mndUserActionEncode(&userObj);
|
||||
|
@ -85,9 +83,11 @@ static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (mndCreateDefaultUser(pMnode, TSDB_DEFAULT_USER, "_" TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS) != 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -98,13 +98,11 @@ static SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
|
|||
|
||||
int32_t dataPos = 0;
|
||||
SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN)
|
||||
SDB_SET_BINARY(pRaw, dataPos, pUser->pass, TSDB_KEY_LEN)
|
||||
SDB_SET_BINARY(pRaw, dataPos, pUser->pass, TSDB_PASSWORD_LEN)
|
||||
SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN)
|
||||
SDB_SET_INT64(pRaw, dataPos, pUser->createdTime)
|
||||
SDB_SET_INT64(pRaw, dataPos, pUser->updateTime)
|
||||
SDB_SET_INT8(pRaw, dataPos, pUser->superAuth)
|
||||
SDB_SET_INT8(pRaw, dataPos, pUser->readAuth)
|
||||
SDB_SET_INT8(pRaw, dataPos, pUser->writeAuth)
|
||||
SDB_SET_INT8(pRaw, dataPos, pUser->superUser)
|
||||
SDB_SET_DATALEN(pRaw, dataPos);
|
||||
|
||||
return pRaw;
|
||||
|
@ -126,13 +124,11 @@ static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
|
|||
|
||||
int32_t dataPos = 0;
|
||||
SDB_GET_BINARY(pRaw, pRow, dataPos, pUser->user, TSDB_USER_LEN)
|
||||
SDB_GET_BINARY(pRaw, pRow, dataPos, pUser->pass, TSDB_KEY_LEN)
|
||||
SDB_GET_BINARY(pRaw, pRow, dataPos, pUser->pass, TSDB_PASSWORD_LEN)
|
||||
SDB_GET_BINARY(pRaw, pRow, dataPos, pUser->acct, TSDB_USER_LEN)
|
||||
SDB_GET_INT64(pRaw, pRow, dataPos, &pUser->createdTime)
|
||||
SDB_GET_INT64(pRaw, pRow, dataPos, &pUser->updateTime)
|
||||
SDB_GET_INT8(pRaw, pRow, dataPos, &pUser->superAuth)
|
||||
SDB_GET_INT8(pRaw, pRow, dataPos, &pUser->readAuth)
|
||||
SDB_GET_INT8(pRaw, pRow, dataPos, &pUser->writeAuth)
|
||||
SDB_GET_INT8(pRaw, pRow, dataPos, &pUser->superUser)
|
||||
|
||||
return pRow;
|
||||
}
|
||||
|
@ -171,13 +167,11 @@ static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
|
|||
static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOldUser, SUserObj *pNewUser) {
|
||||
mTrace("user:%s, perform update action", pOldUser->user);
|
||||
memcpy(pOldUser->user, pNewUser->user, TSDB_USER_LEN);
|
||||
memcpy(pOldUser->pass, pNewUser->pass, TSDB_KEY_LEN);
|
||||
memcpy(pOldUser->pass, pNewUser->pass, TSDB_PASSWORD_LEN);
|
||||
memcpy(pOldUser->acct, pNewUser->acct, TSDB_USER_LEN);
|
||||
pOldUser->createdTime = pNewUser->createdTime;
|
||||
pOldUser->updateTime = pNewUser->updateTime;
|
||||
pOldUser->superAuth = pNewUser->superAuth;
|
||||
pOldUser->readAuth = pNewUser->readAuth;
|
||||
pOldUser->writeAuth = pNewUser->writeAuth;
|
||||
pOldUser->superUser = pNewUser->superUser;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -198,9 +192,7 @@ static int32_t mndCreateUser(SMnode *pMnode, char *acct, char *user, char *pass,
|
|||
taosEncryptPass((uint8_t *)pass, strlen(pass), userObj.pass);
|
||||
userObj.createdTime = taosGetTimestampMs();
|
||||
userObj.updateTime = userObj.createdTime;
|
||||
userObj.superAuth = 0;
|
||||
userObj.readAuth = 1;
|
||||
userObj.writeAuth = 1;
|
||||
userObj.superUser = 0;
|
||||
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, pMsg->rpcMsg.handle);
|
||||
if (pTrans == NULL) {
|
||||
|
@ -469,7 +461,7 @@ static int32_t mndGetUserMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *p
|
|||
|
||||
pShow->bytes[cols] = 8;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
strcpy(pSchema[cols].name, "create_time");
|
||||
strcpy(pSchema[cols].name, "create time");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
|
@ -489,7 +481,7 @@ static int32_t mndGetUserMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *p
|
|||
|
||||
pShow->numOfRows = sdbGetSize(pSdb, SDB_USER);
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
strcpy(pMeta->tableFname, mndShowStr(pShow->type));
|
||||
strcpy(pMeta->tbFname, mndShowStr(pShow->type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -513,14 +505,11 @@ static int32_t mndRetrieveUsers(SMnodeMsg *pMsg, SShowObj *pShow, char *data, in
|
|||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
if (pUser->superAuth) {
|
||||
if (pUser->superUser) {
|
||||
const char *src = "super";
|
||||
STR_WITH_SIZE_TO_VARSTR(pWrite, src, strlen(src));
|
||||
} else if (pUser->writeAuth) {
|
||||
const char *src = "writable";
|
||||
STR_WITH_SIZE_TO_VARSTR(pWrite, src, strlen(src));
|
||||
} else {
|
||||
const char *src = "readable";
|
||||
const char *src = "normal";
|
||||
STR_WITH_SIZE_TO_VARSTR(pWrite, src, strlen(src));
|
||||
}
|
||||
cols++;
|
||||
|
|
|
@ -45,7 +45,7 @@ static void mndCancelGetNextVnode(SMnode *pMnode, void *pIter);
|
|||
|
||||
int32_t mndInitVgroup(SMnode *pMnode) {
|
||||
SSdbTable table = {.sdbType = SDB_VGROUP,
|
||||
.keyType = SDB_KEY_BINARY,
|
||||
.keyType = SDB_KEY_INT32,
|
||||
.encodeFp = (SdbEncodeFp)mndVgroupActionEncode,
|
||||
.decodeFp = (SdbDecodeFp)mndVgroupActionDecode,
|
||||
.insertFp = (SdbInsertFp)mndVgroupActionInsert,
|
||||
|
@ -238,7 +238,7 @@ static int32_t mndGetVgroupMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg
|
|||
}
|
||||
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
strcpy(pMeta->tableFname, mndShowStr(pShow->type));
|
||||
strcpy(pMeta->tbFname, mndShowStr(pShow->type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ static int32_t mndGetVnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *
|
|||
pShow->replica = dnodeId;
|
||||
pShow->numOfRows = mndGetVnodesNum(pMnode, dnodeId);
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
strcpy(pMeta->tableFname, mndShowStr(pShow->type));
|
||||
strcpy(pMeta->tbFname, mndShowStr(pShow->type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "mndMnode.h"
|
||||
#include "mndProfile.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndStable.h"
|
||||
#include "mndStb.h"
|
||||
#include "mndSync.h"
|
||||
#include "mndTelem.h"
|
||||
#include "mndTrans.h"
|
||||
|
@ -131,7 +131,7 @@ static int32_t mndInitSteps(SMnode *pMnode) {
|
|||
if (mndAllocStep(pMnode, "mnode-user", mndInitUser, mndCleanupUser) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-db", mndInitDb, mndCleanupDb) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-vgroup", mndInitVgroup, mndCleanupVgroup) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-stable", mndInitStable, mndCleanupStable) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-stb", mndInitStb, mndCleanupStb) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-func", mndInitFunc, mndCleanupFunc) != 0) return -1;
|
||||
if (pMnode->clusterId <= 0) {
|
||||
if (mndAllocStep(pMnode, "mnode-sdb-deploy", mndDeploySdb, NULL) != 0) return -1;
|
||||
|
@ -205,7 +205,6 @@ static int32_t mndSetOptions(SMnode *pMnode, const SMnodeOpt *pOption) {
|
|||
pMnode->cfg.sver = pOption->cfg.sver;
|
||||
pMnode->cfg.enableTelem = pOption->cfg.enableTelem;
|
||||
pMnode->cfg.statusInterval = pOption->cfg.statusInterval;
|
||||
pMnode->cfg.mnodeEqualVnodeNum = pOption->cfg.mnodeEqualVnodeNum;
|
||||
pMnode->cfg.shellActivityTimer = pOption->cfg.shellActivityTimer;
|
||||
pMnode->cfg.timezone = strdup(pOption->cfg.timezone);
|
||||
pMnode->cfg.locale = strdup(pOption->cfg.locale);
|
||||
|
@ -215,7 +214,7 @@ static int32_t mndSetOptions(SMnode *pMnode, const SMnodeOpt *pOption) {
|
|||
|
||||
if (pMnode->sendMsgToDnodeFp == NULL || pMnode->sendMsgToMnodeFp == NULL || pMnode->sendRedirectMsgFp == NULL ||
|
||||
pMnode->putMsgToApplyMsgFp == NULL || pMnode->dnodeId < 0 || pMnode->clusterId < 0 ||
|
||||
pMnode->cfg.statusInterval < 1 || pOption->cfg.mnodeEqualVnodeNum < 0) {
|
||||
pMnode->cfg.statusInterval < 1) {
|
||||
terrno = TSDB_CODE_MND_INVALID_OPTIONS;
|
||||
return -1;
|
||||
}
|
||||
|
@ -337,8 +336,8 @@ SMnodeMsg *mndInitMsg(SMnode *pMnode, SRpcMsg *pRpcMsg) {
|
|||
}
|
||||
|
||||
SRpcConnInfo connInfo = {0};
|
||||
if (rpcGetConnInfo(pRpcMsg->handle, &connInfo) != 0) {
|
||||
mndCleanupMsg(pMsg);
|
||||
if ((pRpcMsg->msgType & 1U) && rpcGetConnInfo(pRpcMsg->handle, &connInfo) != 0) {
|
||||
taosFreeQitem(pMsg);
|
||||
terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
|
||||
mError("RPC:%p, app:%p failed to create msg since %s", pRpcMsg->handle, pRpcMsg->ahandle, terrstr());
|
||||
return NULL;
|
||||
|
@ -355,6 +354,8 @@ SMnodeMsg *mndInitMsg(SMnode *pMnode, SRpcMsg *pRpcMsg) {
|
|||
|
||||
void mndCleanupMsg(SMnodeMsg *pMsg) {
|
||||
mTrace("msg:%p, app:%p is destroyed, RPC:%p", pMsg, pMsg->rpcMsg.ahandle, pMsg->rpcMsg.handle);
|
||||
rpcFreeCont(pMsg->rpcMsg.pCont);
|
||||
pMsg->rpcMsg.pCont = NULL;
|
||||
taosFreeQitem(pMsg);
|
||||
}
|
||||
|
||||
|
@ -368,7 +369,7 @@ static void mndProcessRpcMsg(SMnodeMsg *pMsg) {
|
|||
int32_t code = 0;
|
||||
int32_t msgType = pMsg->rpcMsg.msgType;
|
||||
void *ahandle = pMsg->rpcMsg.ahandle;
|
||||
bool isReq = (msgType % 2 == 1);
|
||||
bool isReq = (msgType & 1U);
|
||||
|
||||
mTrace("msg:%p, app:%p type:%s will be processed", pMsg, ahandle, taosMsg[msgType]);
|
||||
|
||||
|
@ -430,3 +431,10 @@ void mndProcessWriteMsg(SMnodeMsg *pMsg) { mndProcessRpcMsg(pMsg); }
|
|||
void mndProcessSyncMsg(SMnodeMsg *pMsg) { mndProcessRpcMsg(pMsg); }
|
||||
|
||||
void mndProcessApplyMsg(SMnodeMsg *pMsg) {}
|
||||
|
||||
uint64_t mndGenerateUid(char *name, int32_t len) {
|
||||
int64_t us = taosGetTimestampUs();
|
||||
int32_t hashval = MurmurHash3_32(name, len);
|
||||
uint64_t x = (us & 0x000000FFFFFFFFFF) << 24;
|
||||
return x + ((hashval & ((1ul << 16) - 1ul)) << 8) + (taosRand() & ((1ul << 8) - 1ul));
|
||||
}
|
|
@ -52,10 +52,10 @@ SSdb *sdbInit(SSdbOpt *pOption) {
|
|||
void sdbCleanup(SSdb *pSdb) {
|
||||
mDebug("start to cleanup sdb");
|
||||
|
||||
if (pSdb->curVer != pSdb->lastCommitVer) {
|
||||
// if (pSdb->curVer != pSdb->lastCommitVer) {
|
||||
mDebug("write sdb file for curVer:% " PRId64 " and lastVer:%" PRId64, pSdb->curVer, pSdb->lastCommitVer);
|
||||
sdbWriteFile(pSdb);
|
||||
}
|
||||
// }
|
||||
|
||||
if (pSdb->currDir != NULL) {
|
||||
tfree(pSdb->currDir);
|
||||
|
|
|
@ -18,6 +18,6 @@ target_link_libraries(
|
|||
)
|
||||
|
||||
# test
|
||||
#if(${BUILD_TEST})
|
||||
# add_subdirectory(test)
|
||||
#endif(${BUILD_TEST})
|
||||
if(${BUILD_TEST})
|
||||
add_subdirectory(test)
|
||||
endif(${BUILD_TEST})
|
|
@ -28,6 +28,7 @@ typedef struct SVBufPool SVBufPool;
|
|||
int vnodeOpenBufPool(SVnode *pVnode);
|
||||
void vnodeCloseBufPool(SVnode *pVnode);
|
||||
void *vnodeMalloc(SVnode *pVnode, uint64_t size);
|
||||
bool vnodeBufPoolIsFull(SVnode *pVnode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool vnodeShouldCommit(SVnode *pVnode);
|
||||
int vnodeAsyncCommit(SVnode *pVnode);
|
||||
#define vnodeShouldCommit vnodeBufPoolIsFull
|
||||
int vnodeAsyncCommit(SVnode *pVnode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -18,15 +18,17 @@
|
|||
|
||||
#include "mallocator.h"
|
||||
#include "sync.h"
|
||||
#include "tcoding.h"
|
||||
#include "tdlist.h"
|
||||
#include "tlockfree.h"
|
||||
#include "wal.h"
|
||||
#include "tcoding.h"
|
||||
|
||||
#include "vnode.h"
|
||||
#include "vnodeBufferPool.h"
|
||||
#include "vnodeCfg.h"
|
||||
#include "vnodeCommit.h"
|
||||
#include "vnodeFS.h"
|
||||
#include "vnodeMemAllocator.h"
|
||||
#include "vnodeRequest.h"
|
||||
#include "vnodeStateMgr.h"
|
||||
#include "vnodeSync.h"
|
||||
|
|
|
@ -16,15 +16,37 @@
|
|||
#ifndef _TD_VNODE_MEM_ALLOCATOR_H_
|
||||
#define _TD_VNODE_MEM_ALLOCATOR_H_
|
||||
|
||||
#include "mallocator.h"
|
||||
#include "vnode.h"
|
||||
#include "os.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SMemAllocator *vnodeCreateMemAllocator(SVnode *pVnode);
|
||||
void vnodeDestroyMemAllocator(SMemAllocator *pma);
|
||||
typedef struct SVArenaNode SVArenaNode;
|
||||
typedef struct SVMemAllocator SVMemAllocator;
|
||||
|
||||
struct SVArenaNode {
|
||||
TD_SLIST_NODE(SVArenaNode);
|
||||
uint64_t size; // current node size
|
||||
void * ptr;
|
||||
char data[];
|
||||
};
|
||||
|
||||
struct SVMemAllocator {
|
||||
TD_DLIST_NODE(SVMemAllocator);
|
||||
uint64_t capacity;
|
||||
uint64_t ssize;
|
||||
uint64_t lsize;
|
||||
SVArenaNode *pNode;
|
||||
TD_SLIST(SVArenaNode) nlist;
|
||||
};
|
||||
|
||||
SVMemAllocator *vmaCreate(uint64_t capacity, uint64_t ssize, uint64_t lsize);
|
||||
void vmaDestroy(SVMemAllocator *pVMA);
|
||||
void vmaReset(SVMemAllocator *pVMA);
|
||||
void * vmaMalloc(SVMemAllocator *pVMA, uint64_t size);
|
||||
void vmaFree(SVMemAllocator *pVMA, void *ptr);
|
||||
bool vmaIsFull(SVMemAllocator *pVMA);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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 "vnodeDef.h"
|
||||
|
||||
static SVArenaNode *vArenaNodeNew(uint64_t capacity);
|
||||
static void vArenaNodeFree(SVArenaNode *pNode);
|
||||
|
||||
SVMemAllocator *vmaCreate(uint64_t capacity, uint64_t ssize, uint64_t lsize) {
|
||||
SVMemAllocator *pVMA = (SVMemAllocator *)malloc(sizeof(*pVMA));
|
||||
if (pVMA == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pVMA->capacity = capacity;
|
||||
pVMA->ssize = ssize;
|
||||
pVMA->lsize = lsize;
|
||||
tSListInit(&(pVMA->nlist));
|
||||
|
||||
pVMA->pNode = vArenaNodeNew(capacity);
|
||||
if (pVMA->pNode == NULL) {
|
||||
free(pVMA);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tSListPush(&(pVMA->nlist), pVMA->pNode);
|
||||
|
||||
return pVMA;
|
||||
}
|
||||
|
||||
void vmaDestroy(SVMemAllocator *pVMA) {
|
||||
if (pVMA) {
|
||||
while (TD_SLIST_NELES(&(pVMA->nlist)) > 1) {
|
||||
SVArenaNode *pNode = TD_SLIST_HEAD(&(pVMA->nlist));
|
||||
tSListPop(&(pVMA->nlist));
|
||||
vArenaNodeFree(pNode);
|
||||
}
|
||||
|
||||
free(pVMA);
|
||||
}
|
||||
}
|
||||
|
||||
void vmaReset(SVMemAllocator *pVMA) {
|
||||
while (TD_SLIST_NELES(&(pVMA->nlist)) > 1) {
|
||||
SVArenaNode *pNode = TD_SLIST_HEAD(&(pVMA->nlist));
|
||||
tSListPop(&(pVMA->nlist));
|
||||
vArenaNodeFree(pNode);
|
||||
}
|
||||
|
||||
SVArenaNode *pNode = TD_SLIST_HEAD(&(pVMA->nlist));
|
||||
pNode->ptr = pNode->data;
|
||||
}
|
||||
|
||||
void *vmaMalloc(SVMemAllocator *pVMA, uint64_t size) {
|
||||
SVArenaNode *pNode = TD_SLIST_HEAD(&(pVMA->nlist));
|
||||
void * ptr;
|
||||
|
||||
if (pNode->size < POINTER_DISTANCE(pNode->ptr, pNode->data) + size) {
|
||||
uint64_t capacity = MAX(pVMA->ssize, size);
|
||||
pNode = vArenaNodeNew(capacity);
|
||||
if (pNode == NULL) {
|
||||
// TODO: handle error
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tSListPush(&(pVMA->nlist), pNode);
|
||||
}
|
||||
|
||||
ptr = pNode->ptr;
|
||||
pNode->ptr = POINTER_SHIFT(ptr, size);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void vmaFree(SVMemAllocator *pVMA, void *ptr) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
bool vmaIsFull(SVMemAllocator *pVMA) {
|
||||
SVArenaNode *pNode = TD_SLIST_HEAD(&(pVMA->nlist));
|
||||
|
||||
return (TD_SLIST_NELES(&(pVMA->nlist)) > 1) ||
|
||||
(pNode->size < POINTER_DISTANCE(pNode->ptr, pNode->data) + pVMA->lsize);
|
||||
}
|
||||
|
||||
/* ------------------------ STATIC METHODS ------------------------ */
|
||||
static SVArenaNode *vArenaNodeNew(uint64_t capacity) {
|
||||
SVArenaNode *pNode = NULL;
|
||||
|
||||
pNode = (SVArenaNode *)malloc(sizeof(*pNode) + capacity);
|
||||
if (pNode == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pNode->size = capacity;
|
||||
pNode->ptr = pNode->data;
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static void vArenaNodeFree(SVArenaNode *pNode) {
|
||||
if (pNode) {
|
||||
free(pNode);
|
||||
}
|
||||
}
|
|
@ -19,14 +19,90 @@
|
|||
#define VNODE_BUF_POOL_SHARDS 3
|
||||
|
||||
struct SVBufPool {
|
||||
// buffer pool impl
|
||||
SList free;
|
||||
SList incycle;
|
||||
SListNode *inuse;
|
||||
TD_DLIST(SVMemAllocator) free;
|
||||
TD_DLIST(SVMemAllocator) incycle;
|
||||
SVMemAllocator *inuse;
|
||||
// MAF for submodules
|
||||
SMemAllocatorFactory maf;
|
||||
// SMemAllocatorFactory maf;
|
||||
};
|
||||
|
||||
int vnodeOpenBufPool(SVnode *pVnode) {
|
||||
uint64_t capacity;
|
||||
// EVMemAllocatorT type = E_V_ARENA_ALLOCATOR;
|
||||
|
||||
if ((pVnode->pBufPool = (SVBufPool *)calloc(1, sizeof(SVBufPool))) == NULL) {
|
||||
/* TODO */
|
||||
return -1;
|
||||
}
|
||||
|
||||
tDListInit(&(pVnode->pBufPool->free));
|
||||
tDListInit(&(pVnode->pBufPool->incycle));
|
||||
|
||||
pVnode->pBufPool->inuse = NULL;
|
||||
|
||||
// TODO
|
||||
capacity = pVnode->config.wsize / VNODE_BUF_POOL_SHARDS;
|
||||
|
||||
for (int i = 0; i < VNODE_BUF_POOL_SHARDS; i++) {
|
||||
SVMemAllocator *pVMA = vmaCreate(capacity, pVnode->config.ssize, pVnode->config.lsize);
|
||||
if (pVMA == NULL) {
|
||||
// TODO: handle error
|
||||
return -1;
|
||||
}
|
||||
|
||||
tDListAppend(&(pVnode->pBufPool->free), pVMA);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vnodeCloseBufPool(SVnode *pVnode) {
|
||||
if (pVnode->pBufPool) {
|
||||
vmaDestroy(pVnode->pBufPool->inuse);
|
||||
|
||||
while (true) {
|
||||
SVMemAllocator *pVMA = TD_DLIST_HEAD(&(pVnode->pBufPool->incycle));
|
||||
if (pVMA == NULL) break;
|
||||
tDListPop(&(pVnode->pBufPool->incycle), pVMA);
|
||||
vmaDestroy(pVMA);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
SVMemAllocator *pVMA = TD_DLIST_HEAD(&(pVnode->pBufPool->free));
|
||||
if (pVMA == NULL) break;
|
||||
tDListPop(&(pVnode->pBufPool->free), pVMA);
|
||||
vmaDestroy(pVMA);
|
||||
}
|
||||
|
||||
free(pVnode->pBufPool);
|
||||
pVnode->pBufPool = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void *vnodeMalloc(SVnode *pVnode, uint64_t size) {
|
||||
SVBufPool *pBufPool = pVnode->pBufPool;
|
||||
|
||||
if (pBufPool->inuse == NULL) {
|
||||
while (true) {
|
||||
// TODO: add sem_wait and sem_post
|
||||
pBufPool->inuse = TD_DLIST_HEAD(&(pBufPool->free));
|
||||
if (pBufPool->inuse) {
|
||||
tDListPop(&(pBufPool->free), pBufPool->inuse);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vmaMalloc(pBufPool->inuse, size);
|
||||
}
|
||||
|
||||
bool vnodeBufPoolIsFull(SVnode *pVnode) {
|
||||
if (pVnode->pBufPool->inuse == NULL) return false;
|
||||
return vmaIsFull(pVnode->pBufPool->inuse);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
typedef enum {
|
||||
// Heap allocator
|
||||
E_V_HEAP_ALLOCATOR = 0,
|
||||
|
@ -57,15 +133,6 @@ typedef struct {
|
|||
SListNode *pNode;
|
||||
} SVMAWrapper;
|
||||
|
||||
typedef struct {
|
||||
T_REF_DECLARE()
|
||||
uint64_t capacity;
|
||||
EVMemAllocatorT type;
|
||||
union {
|
||||
SVHeapAllocator vha;
|
||||
SVArenaAllocator vaa;
|
||||
};
|
||||
} SVMemAllocator;
|
||||
|
||||
static SListNode * vBufPoolNewNode(uint64_t capacity, EVMemAllocatorT type);
|
||||
static void vBufPoolFreeNode(SListNode *pNode);
|
||||
|
@ -73,106 +140,13 @@ static SMemAllocator *vBufPoolCreateMA(SMemAllocatorFactory *pmaf);
|
|||
static void vBufPoolDestroyMA(SMemAllocatorFactory *pmaf, SMemAllocator *pma);
|
||||
static void * vBufPoolMalloc(SVMemAllocator *pvma, uint64_t size);
|
||||
|
||||
int vnodeOpenBufPool(SVnode *pVnode) {
|
||||
uint64_t capacity;
|
||||
EVMemAllocatorT type = E_V_ARENA_ALLOCATOR;
|
||||
|
||||
if ((pVnode->pBufPool = (SVBufPool *)calloc(1, sizeof(SVBufPool))) == NULL) {
|
||||
/* TODO */
|
||||
return -1;
|
||||
}
|
||||
|
||||
tdListInit(&(pVnode->pBufPool->free), 0);
|
||||
tdListInit(&(pVnode->pBufPool->incycle), 0);
|
||||
|
||||
capacity = pVnode->config.wsize / VNODE_BUF_POOL_SHARDS;
|
||||
if (pVnode->config.isHeapAllocator) {
|
||||
type = E_V_HEAP_ALLOCATOR;
|
||||
}
|
||||
|
||||
for (int i = 0; i < VNODE_BUF_POOL_SHARDS; i++) {
|
||||
SListNode *pNode = vBufPoolNewNode(capacity, type);
|
||||
if (pNode == NULL) {
|
||||
vnodeCloseBufPool(pVnode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tdListAppendNode(&(pVnode->pBufPool->free), pNode);
|
||||
}
|
||||
|
||||
pVnode->pBufPool->maf.impl = pVnode;
|
||||
pVnode->pBufPool->maf.create = vBufPoolCreateMA;
|
||||
pVnode->pBufPool->maf.destroy = vBufPoolDestroyMA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vnodeCloseBufPool(SVnode *pVnode) {
|
||||
SListNode *pNode;
|
||||
if (pVnode->pBufPool) {
|
||||
// Clear free list
|
||||
while ((pNode = tdListPopHead(&(pVnode->pBufPool->free))) != NULL) {
|
||||
vBufPoolFreeNode(pNode);
|
||||
}
|
||||
|
||||
// Clear incycle list
|
||||
while ((pNode = tdListPopHead(&(pVnode->pBufPool->incycle))) != NULL) {
|
||||
vBufPoolFreeNode(pNode);
|
||||
}
|
||||
|
||||
// Free inuse node
|
||||
if (pVnode->pBufPool->inuse) {
|
||||
vBufPoolFreeNode(pVnode->pBufPool->inuse);
|
||||
}
|
||||
|
||||
free(pVnode->pBufPool);
|
||||
pVnode->pBufPool = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void *vnodeMalloc(SVnode *pVnode, uint64_t size) {
|
||||
void *ptr;
|
||||
|
||||
if (pVnode->pBufPool->inuse == NULL) {
|
||||
SListNode *pNode;
|
||||
while ((pNode = tdListPopHead(&(pVnode->pBufPool->free))) == NULL) {
|
||||
// todo
|
||||
// tsem_wait();
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
pVnode->pBufPool->inuse = pNode;
|
||||
}
|
||||
|
||||
SVMemAllocator *pvma = (SVMemAllocator *)(pVnode->pBufPool->inuse->data);
|
||||
return vBufPoolMalloc(pvma, size);
|
||||
}
|
||||
|
||||
/* ------------------------ STATIC METHODS ------------------------ */
|
||||
static void vArenaAllocatorInit(SVArenaAllocator *pvaa, uint64_t capacity, uint64_t ssize, uint64_t lsize) { /* TODO */
|
||||
pvaa->ssize = ssize;
|
||||
pvaa->lsize = lsize;
|
||||
pvaa->inuse = &pvaa->node;
|
||||
|
||||
pvaa->node.prev = NULL;
|
||||
pvaa->node.size = capacity;
|
||||
pvaa->node.ptr = pvaa->node.data;
|
||||
}
|
||||
|
||||
static void vArenaAllocatorClear(SVArenaAllocator *pvaa) { /* TODO */
|
||||
while (pvaa->inuse != &(pvaa->node)) {
|
||||
SVArenaNode *pANode = pvaa->inuse;
|
||||
pvaa->inuse = pANode->prev;
|
||||
free(pANode);
|
||||
}
|
||||
}
|
||||
|
||||
static SListNode *vBufPoolNewNode(uint64_t capacity, EVMemAllocatorT type) {
|
||||
SListNode * pNode;
|
||||
SVMemAllocator *pvma;
|
||||
uint64_t msize;
|
||||
uint64_t ssize = 0; // TODO
|
||||
uint64_t lsize = 0; // TODO
|
||||
uint64_t ssize = 4096; // TODO
|
||||
uint64_t lsize = 1024; // TODO
|
||||
|
||||
msize = sizeof(SListNode) + sizeof(SVMemAllocator);
|
||||
if (type == E_V_ARENA_ALLOCATOR) {
|
||||
|
@ -317,4 +291,5 @@ static void vBufPoolDestroyMA(SMemAllocatorFactory *pmaf, SMemAllocator *pma) {
|
|||
tdListAppendNode(&(pVnode->pBufPool->free), tdListPopNode(&(pVnode->pBufPool->incycle), pNode));
|
||||
// tsem_post(); todo: sem_post
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "vnodeDef.h"
|
||||
|
||||
const SVnodeCfg defaultVnodeOptions = {0}; /* TODO */
|
||||
const SVnodeCfg defaultVnodeOptions = {.wsize = 16 * 1024 * 1024, .walCfg = {.level = TAOS_WAL_WRITE}}; /* TODO */
|
||||
|
||||
void vnodeOptionsInit(SVnodeCfg *pVnodeOptions) { /* TODO */
|
||||
vnodeOptionsCopy(pVnodeOptions, &defaultVnodeOptions);
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
static int vnodeStartCommit(SVnode *pVnode);
|
||||
static int vnodeEndCommit(SVnode *pVnode);
|
||||
|
||||
bool vnodeShouldCommit(SVnode *pVnode) { return false; }
|
||||
|
||||
int vnodeAsyncCommit(SVnode *pVnode) {
|
||||
#if 0
|
||||
if (vnodeStartCommit(pVnode) < 0) {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tmacro.h"
|
||||
#include "vnodeDef.h"
|
||||
|
||||
static SVnode *vnodeNew(const char *path, const SVnodeCfg *pVnodeCfg);
|
||||
|
@ -20,8 +21,14 @@ static void vnodeFree(SVnode *pVnode);
|
|||
static int vnodeOpenImpl(SVnode *pVnode);
|
||||
static void vnodeCloseImpl(SVnode *pVnode);
|
||||
|
||||
TD_DEF_MOD_INIT_FLAG(vnode);
|
||||
TD_DEF_MOD_CLEAR_FLAG(vnode);
|
||||
|
||||
int vnodeInit() {
|
||||
// TODO
|
||||
if (TD_CHECK_AND_SET_MODE_INIT(vnode) == TD_MOD_INITIALIZED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (walInit() < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -30,6 +37,10 @@ int vnodeInit() {
|
|||
}
|
||||
|
||||
void vnodeClear() {
|
||||
if (TD_CHECK_AND_SET_MOD_CLEAR(vnode) == TD_MOD_CLEARD) {
|
||||
return;
|
||||
}
|
||||
|
||||
walCleanUp();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
/*
|
||||
* 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 "vnodeDef.h"
|
||||
|
||||
SMemAllocator *vnodeCreateMemAllocator(SVnode *pVnode) {
|
||||
SMemAllocator *pma = NULL;
|
||||
/* TODO */
|
||||
return pma;
|
||||
}
|
||||
|
||||
void vnodeDestroyMemAllocator(SMemAllocator *pma) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
#if 0
|
||||
#define VNODE_HEAP_ALLOCATOR 0
|
||||
#define VNODE_ARENA_ALLOCATOR 1
|
||||
|
||||
typedef struct {
|
||||
uint64_t tsize;
|
||||
uint64_t used;
|
||||
} SVHeapAllocator;
|
||||
|
||||
typedef struct SVArenaNode {
|
||||
struct SVArenaNode *prev;
|
||||
void * nptr;
|
||||
char data[];
|
||||
} SVArenaNode;
|
||||
|
||||
typedef struct {
|
||||
SVArenaNode *inuse;
|
||||
SVArenaNode node;
|
||||
} SVArenaAllocator;
|
||||
|
||||
typedef struct {
|
||||
int8_t type;
|
||||
uint64_t tsize;
|
||||
T_REF_DECLARE()
|
||||
union {
|
||||
SVHeapAllocator vha;
|
||||
SVArenaAllocator vaa;
|
||||
};
|
||||
} SVMemAllocator;
|
||||
|
||||
SMemAllocator *vnodeCreateMemAllocator(int8_t type, uint64_t tsize, uint64_t ssize /* step size only for arena */) {
|
||||
SMemAllocator * pma;
|
||||
uint64_t msize;
|
||||
SVMemAllocator *pva;
|
||||
|
||||
msize = sizeof(*pma) + sizeof(SVMemAllocator);
|
||||
if (type == VNODE_ARENA_ALLOCATOR) {
|
||||
msize += tsize;
|
||||
}
|
||||
|
||||
pma = (SMemAllocator *)calloc(1, msize);
|
||||
if (pma == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pma->impl = POINTER_SHIFT(pma, sizeof(*pma));
|
||||
pva = (SVMemAllocator *)(pma->impl);
|
||||
pva->type = type;
|
||||
pva->tsize = tsize;
|
||||
|
||||
if (type == VNODE_HEAP_ALLOCATOR) {
|
||||
pma->malloc = NULL;
|
||||
pma->calloc = NULL;
|
||||
pma->realloc = NULL;
|
||||
pma->free = NULL;
|
||||
pma->usage = NULL;
|
||||
} else if (type == VNODE_ARENA_ALLOCATOR) {
|
||||
pma->malloc = NULL;
|
||||
pma->calloc = NULL;
|
||||
pma->realloc = NULL;
|
||||
pma->free = NULL;
|
||||
pma->usage = NULL;
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
return pma;
|
||||
}
|
||||
|
||||
void vnodeDestroyMemAllocator(SMemAllocator *pma) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void vnodeRefMemAllocator(SMemAllocator *pma) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void vnodeUnrefMemAllocator(SMemAllocator *pma) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
/* ------------------------ Heap Allocator IMPL ------------------------ */
|
||||
|
||||
/* ------------------------ Arena Allocator IMPL ------------------------ */
|
||||
|
||||
#endif
|
|
@ -4,4 +4,9 @@ target_sources(vnodeApiTests
|
|||
PRIVATE
|
||||
"vnodeApiTests.cpp"
|
||||
)
|
||||
target_link_libraries(vnodeApiTests vnode gtest gtest_main)
|
||||
target_link_libraries(vnodeApiTests vnode gtest gtest_main)
|
||||
|
||||
add_test(
|
||||
NAME vnode_api_tests
|
||||
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/vnodeApiTests
|
||||
)
|
|
@ -1,3 +1,14 @@
|
|||
/**
|
||||
* @file vnodeApiTests.cpp
|
||||
* @author hzcheng (hzcheng@taosdata.com)
|
||||
* @brief VNODE module API tests
|
||||
* @version 0.1
|
||||
* @date 2021-12-13
|
||||
*
|
||||
* @copyright Copyright (c) 2021
|
||||
*
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
|
||||
|
|
|
@ -283,8 +283,12 @@ int32_t catalogGetTableMetaFromMnode(struct SCatalog* pCatalog, void *pRpc, cons
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t catalogGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pTableName, STableMeta* pTableMeta) {
|
||||
|
||||
int32_t catalogGetAllMeta(struct SCatalog* pCatalog, const SEpSet* pMgmtEps, const SCatalogReq* pReq, SCatalogRsp* pRsp) {
|
||||
}
|
||||
|
||||
|
||||
int32_t catalogGetAllMeta(struct SCatalog* pCatalog, const SEpSet* pMgmtEps, const SCatalogReq* pReq, SMetaData* pRsp) {
|
||||
if (NULL == pCatalog || NULL == pMgmtEps || NULL == pReq || NULL == pRsp) {
|
||||
return TSDB_CODE_CTG_INVALID_INPUT;
|
||||
}
|
||||
|
|
|
@ -26,10 +26,24 @@ extern "C" {
|
|||
#include "index_fst_counting_writer.h"
|
||||
#include "index_fst_automation.h"
|
||||
|
||||
|
||||
typedef struct FstNode FstNode;
|
||||
#define OUTPUT_PREFIX(a, b) ((a) > (b) ? (b) : (a)
|
||||
|
||||
typedef struct Fst Fst;
|
||||
typedef struct FstNode FstNode;
|
||||
|
||||
typedef enum { Included, Excluded, Unbounded} FstBound;
|
||||
|
||||
typedef struct FstBoundWithData {
|
||||
FstSlice data;
|
||||
FstBound type;
|
||||
} FstBoundWithData;
|
||||
|
||||
typedef struct FstStreamBuilder {
|
||||
Fst *fst;
|
||||
AutomationCtx *aut;
|
||||
FstBoundWithData *min;
|
||||
FstBoundWithData *max;
|
||||
} FstStreamBuilder, FstStreamWithStateBuilder;
|
||||
|
||||
typedef struct FstRange {
|
||||
uint64_t start;
|
||||
|
@ -39,16 +53,9 @@ typedef struct FstRange {
|
|||
|
||||
typedef enum {GE, GT, LE, LT} RangeType;
|
||||
typedef enum { OneTransNext, OneTrans, AnyTrans, EmptyFinal} State;
|
||||
|
||||
typedef enum {Ordered, OutOfOrdered, DuplicateKey} OrderType;
|
||||
|
||||
|
||||
typedef enum { Included, Excluded, Unbounded} FstBound;
|
||||
typedef struct FstBoundWithData {
|
||||
FstSlice data;
|
||||
FstBound type;
|
||||
} FstBoundWithData;
|
||||
|
||||
FstBoundWithData* fstBoundStateCreate(FstBound type, FstSlice *data);
|
||||
bool fstBoundWithDataExceededBy(FstBoundWithData *bound, FstSlice *slice);
|
||||
bool fstBoundWithDataIsEmpty(FstBoundWithData *bound);
|
||||
|
@ -60,8 +67,6 @@ typedef struct FstOutput {
|
|||
Output out;
|
||||
} FstOutput;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* UnFinished node and helper function
|
||||
|
@ -275,6 +280,9 @@ FstNode* fstGetRoot(Fst *fst);
|
|||
FstType fstGetType(Fst *fst);
|
||||
CompiledAddr fstGetRootAddr(Fst *fst);
|
||||
Output fstEmptyFinalOutput(Fst *fst, bool *null);
|
||||
FstStreamBuilder *fstSearch(Fst *fst, AutomationCtx *ctx);
|
||||
FstStreamWithStateBuilder *fstSearchWithState(Fst *fst, AutomationCtx *ctx);
|
||||
|
||||
bool fstVerify(Fst *fst);
|
||||
|
||||
|
||||
|
@ -291,13 +299,13 @@ typedef struct StreamState {
|
|||
void streamStateDestroy(void *s);
|
||||
|
||||
typedef struct StreamWithState {
|
||||
Fst *fst;
|
||||
Automation *aut;
|
||||
SArray *inp;
|
||||
FstOutput emptyOutput;
|
||||
SArray *stack; // <StreamState>
|
||||
Fst *fst;
|
||||
AutomationCtx *aut;
|
||||
SArray *inp;
|
||||
FstOutput emptyOutput;
|
||||
SArray *stack; // <StreamState>
|
||||
FstBoundWithData *endAt;
|
||||
} StreamWithState ;
|
||||
} StreamWithState;
|
||||
|
||||
typedef struct StreamWithStateResult {
|
||||
FstSlice data;
|
||||
|
@ -310,19 +318,13 @@ StreamWithStateResult *swsResultCreate(FstSlice *data, FstOutput fOut, void *sta
|
|||
void swsResultDestroy(StreamWithStateResult *result);
|
||||
|
||||
typedef void* (*StreamCallback)(void *);
|
||||
StreamWithState *streamWithStateCreate(Fst *fst, Automation *automation, FstBoundWithData *min, FstBoundWithData *max) ;
|
||||
StreamWithState *streamWithStateCreate(Fst *fst, AutomationCtx *automation, FstBoundWithData *min, FstBoundWithData *max) ;
|
||||
void streamWithStateDestroy(StreamWithState *sws);
|
||||
bool streamWithStateSeekMin(StreamWithState *sws, FstBoundWithData *min);
|
||||
|
||||
StreamWithStateResult* streamWithStateNextWith(StreamWithState *sws, StreamCallback callback);
|
||||
|
||||
typedef struct FstStreamBuilder {
|
||||
Fst *fst;
|
||||
Automation *aut;
|
||||
FstBoundWithData *min;
|
||||
FstBoundWithData *max;
|
||||
} FstStreamBuilder;
|
||||
|
||||
FstStreamBuilder *fstStreamBuilderCreate(Fst *fst, Automation *aut);
|
||||
FstStreamBuilder *fstStreamBuilderCreate(Fst *fst, AutomationCtx *aut);
|
||||
// set up bound range
|
||||
// refator, simple code by marco
|
||||
|
||||
|
|
|
@ -19,33 +19,50 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "index_fst_util.h"
|
||||
typedef struct AutomationCtx AutomationCtx;
|
||||
|
||||
typedef enum AutomationType {
|
||||
AUTOMATION_PREFIX,
|
||||
AUTMMATION_MATCH
|
||||
} AutomationType;
|
||||
|
||||
typedef struct StartWith {
|
||||
AutomationCtx *autoSelf;
|
||||
} StartWith;
|
||||
|
||||
typedef struct Complement {
|
||||
AutomationCtx *autoSelf;
|
||||
|
||||
} Complement;
|
||||
|
||||
// automation
|
||||
typedef struct AutomationCtx {
|
||||
// automation interface
|
||||
AutomationType type;
|
||||
void *data;
|
||||
} AutomationCtx;
|
||||
|
||||
typedef struct Automation {
|
||||
void* (*start)() ;
|
||||
bool (*isMatch)(void *);
|
||||
bool (*canMatch)(void *data);
|
||||
bool (*willAlwaysMatch)(void *state);
|
||||
void* (*accept)(void *state, uint8_t byte);
|
||||
void* (*acceptEof)(void *state);
|
||||
void *data;
|
||||
} Automation;
|
||||
|
||||
|
||||
typedef enum StartWithStateKind { Done, Running } StartWithStateKind;
|
||||
|
||||
typedef struct StartWithStateValue {
|
||||
StartWithStateKind kind;
|
||||
void *value;
|
||||
} StartWithStateValue;
|
||||
|
||||
typedef struct AutomationFunc {
|
||||
void* (*start)(AutomationCtx *ctx) ;
|
||||
bool (*isMatch)(AutomationCtx *ctx, void *);
|
||||
bool (*canMatch)(AutomationCtx *ctx, void *data);
|
||||
bool (*willAlwaysMatch)(AutomationCtx *ctx, void *state);
|
||||
void* (*accept)(AutomationCtx *ctx, void *state, uint8_t byte);
|
||||
void* (*acceptEof)(AutomationCtx *ct, void *state);
|
||||
} AutomationFunc;
|
||||
|
||||
AutomationCtx *automCtxCreate(void *data, AutomationType type);
|
||||
void automCtxDestroy(AutomationCtx *ctx);
|
||||
|
||||
extern AutomationFunc automFuncs[];
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -591,14 +591,14 @@ uint64_t fstStateFindInput(FstState *s, FstNode *node, uint8_t b, bool *null) {
|
|||
uint8_t *data = fstSliceData(&t, &len);
|
||||
int i = 0;
|
||||
for(; i < len; i++) {
|
||||
//uint8_t v = slice->data[slice->start + i];
|
||||
////slice->data[slice->start + i];
|
||||
uint8_t v = data[i];
|
||||
if (v == b) {
|
||||
fstSliceDestroy(&t);
|
||||
return node->nTrans - i - 1; // bug
|
||||
}
|
||||
}
|
||||
if (i == len) { *null = true; }
|
||||
fstSliceDestroy(&t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -634,7 +634,7 @@ FstNode *fstNodeCreate(int64_t version, CompiledAddr addr, FstSlice *slice) {
|
|||
} else if (st.state == OneTrans) {
|
||||
FstSlice data = fstSliceCopy(slice, 0, addr);
|
||||
PackSizes sz = fstStateSizes(&st, &data);
|
||||
n->data = fstSliceCopy(slice, 0, addr);
|
||||
n->data = data;
|
||||
n->version = version;
|
||||
n->state = st;
|
||||
n->start = addr;
|
||||
|
@ -852,8 +852,9 @@ void fstBuilderInsertOutput(FstBuilder *b, FstSlice bs, Output in) {
|
|||
OrderType fstBuilderCheckLastKey(FstBuilder *b, FstSlice bs, bool ckDup) {
|
||||
FstSlice *input = &bs;
|
||||
if (fstSliceIsEmpty(&b->last)) {
|
||||
fstSliceDestroy(&b->last);
|
||||
// deep copy or not
|
||||
b->last = fstSliceCopy(&bs, input->start, input->end);
|
||||
b->last = fstSliceDeepCopy(&bs, input->start, input->end);
|
||||
} else {
|
||||
int comp = fstSliceCompare(&b->last, &bs);
|
||||
if (comp == 0 && ckDup) {
|
||||
|
@ -863,7 +864,7 @@ OrderType fstBuilderCheckLastKey(FstBuilder *b, FstSlice bs, bool ckDup) {
|
|||
}
|
||||
// deep copy or not
|
||||
fstSliceDestroy(&b->last);
|
||||
b->last = fstSliceCopy(&bs, input->start, input->end);
|
||||
b->last = fstSliceDeepCopy(&bs, input->start, input->end);
|
||||
}
|
||||
return Ordered;
|
||||
}
|
||||
|
@ -1071,25 +1072,30 @@ bool fstGet(Fst *fst, FstSlice *b, Output *out) {
|
|||
tOut += trn.out;
|
||||
root = fstGetNode(fst, trn.addr);
|
||||
taosArrayPush(nodes, &root);
|
||||
//fstNodeDestroy(root);
|
||||
}
|
||||
if (!FST_NODE_IS_FINAL(root)) {
|
||||
return false;
|
||||
} else {
|
||||
tOut = tOut + FST_NODE_FINAL_OUTPUT(root);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < taosArrayGetSize(nodes); i++) {
|
||||
FstNode **node = (FstNode **)taosArrayGet(nodes, i);
|
||||
fstNodeDestroy(*node);
|
||||
}
|
||||
taosArrayDestroy(nodes);
|
||||
|
||||
fst->root = NULL;
|
||||
|
||||
|
||||
*out = tOut;
|
||||
|
||||
return true;
|
||||
}
|
||||
FstStreamBuilder *fstSearch(Fst *fst, AutomationCtx *ctx) {
|
||||
return fstStreamBuilderCreate(fst, ctx);
|
||||
}
|
||||
FstStreamWithStateBuilder *fstSearchWithState(Fst *fst, AutomationCtx *ctx) {
|
||||
return fstStreamBuilderCreate(fst, ctx);
|
||||
}
|
||||
|
||||
FstNode *fstGetRoot(Fst *fst) {
|
||||
if (fst->root != NULL) {
|
||||
|
@ -1176,7 +1182,7 @@ void fstBoundDestroy(FstBoundWithData *bound) {
|
|||
free(bound);
|
||||
}
|
||||
|
||||
StreamWithState *streamWithStateCreate(Fst *fst, Automation *automation, FstBoundWithData *min, FstBoundWithData *max) {
|
||||
StreamWithState *streamWithStateCreate(Fst *fst, AutomationCtx *automation, FstBoundWithData *min, FstBoundWithData *max) {
|
||||
StreamWithState *sws = calloc(1, sizeof(StreamWithState));
|
||||
if (sws == NULL) { return NULL; }
|
||||
|
||||
|
@ -1203,6 +1209,8 @@ void streamWithStateDestroy(StreamWithState *sws) {
|
|||
}
|
||||
|
||||
bool streamWithStateSeekMin(StreamWithState *sws, FstBoundWithData *min) {
|
||||
|
||||
AutomationCtx *aut = sws->aut;
|
||||
if (fstBoundWithDataIsEmpty(min)) {
|
||||
if (fstBoundWithDataIsIncluded(min)) {
|
||||
sws->emptyOutput.out = fstEmptyFinalOutput(sws->fst, &(sws->emptyOutput.null));
|
||||
|
@ -1210,7 +1218,7 @@ bool streamWithStateSeekMin(StreamWithState *sws, FstBoundWithData *min) {
|
|||
StreamState s = {.node = fstGetRoot(sws->fst),
|
||||
.trans = 0,
|
||||
.out = {.null = false, .out = 0},
|
||||
.autState = sws->aut->start()}; // auto.start callback
|
||||
.autState = automFuncs[aut->type].start(aut)}; // auto.start callback
|
||||
taosArrayPush(sws->stack, &s);
|
||||
return true;
|
||||
}
|
||||
|
@ -1228,7 +1236,8 @@ bool streamWithStateSeekMin(StreamWithState *sws, FstBoundWithData *min) {
|
|||
|
||||
FstNode *node = fstGetRoot(sws->fst);
|
||||
Output out = 0;
|
||||
void* autState = sws->aut->start();
|
||||
//void* autState = sws->aut->start();
|
||||
void* autState = automFuncs[aut->type].start(aut);
|
||||
|
||||
int32_t len;
|
||||
uint8_t *data = fstSliceData(key, &len);
|
||||
|
@ -1240,7 +1249,8 @@ bool streamWithStateSeekMin(StreamWithState *sws, FstBoundWithData *min) {
|
|||
FstTransition trn;
|
||||
fstNodeGetTransitionAt(node, res, &trn);
|
||||
void *preState = autState;
|
||||
autState = sws->aut->accept(preState, b);
|
||||
// autState = sws->aut->accept(preState, b);
|
||||
autState = automFuncs[aut->type].accept(aut, preState, b);
|
||||
taosArrayPush(sws->inp, &b);
|
||||
StreamState s = {.node = node,
|
||||
.trans = res + 1,
|
||||
|
@ -1297,6 +1307,7 @@ bool streamWithStateSeekMin(StreamWithState *sws, FstBoundWithData *min) {
|
|||
}
|
||||
|
||||
StreamWithStateResult *streamWithStateNextWith(StreamWithState *sws, StreamCallback callback) {
|
||||
AutomationCtx *aut = sws->aut;
|
||||
FstOutput output = sws->emptyOutput;
|
||||
if (output.null == false) {
|
||||
FstSlice emptySlice = fstSliceCreate(NULL, 0);
|
||||
|
@ -1305,15 +1316,15 @@ StreamWithStateResult *streamWithStateNextWith(StreamWithState *sws, StreamCallb
|
|||
sws->stack = (SArray *)taosArrayInit(256, sizeof(StreamState));
|
||||
return NULL;
|
||||
}
|
||||
void* start = sws->aut->start();
|
||||
if (sws->aut->isMatch(start)) {
|
||||
void *start = automFuncs[aut->type].start(aut);
|
||||
if (automFuncs[aut->type].isMatch(aut, start)) {
|
||||
FstSlice s = fstSliceCreate(NULL, 0);
|
||||
return swsResultCreate(&s, output, callback(start));
|
||||
}
|
||||
}
|
||||
while (taosArrayGetSize(sws->stack) > 0) {
|
||||
StreamState *p = (StreamState *)taosArrayPop(sws->stack);
|
||||
if (p->trans >= FST_NODE_LEN(p->node) || !sws->aut->canMatch(p->autState)) {
|
||||
if (p->trans >= FST_NODE_LEN(p->node) || automFuncs[aut->type].canMatch(aut, p->autState)) {
|
||||
if (FST_NODE_ADDR(p->node) != fstGetRootAddr(sws->fst)) {
|
||||
taosArrayPop(sws->inp);
|
||||
}
|
||||
|
@ -1323,16 +1334,18 @@ StreamWithStateResult *streamWithStateNextWith(StreamWithState *sws, StreamCallb
|
|||
FstTransition trn;
|
||||
fstNodeGetTransitionAt(p->node, p->trans, &trn);
|
||||
Output out = p->out.out + trn.out;
|
||||
void* nextState = sws->aut->accept(p->autState, trn.inp);
|
||||
void* nextState = automFuncs[aut->type].accept(aut, p->autState, trn.inp);
|
||||
void* tState = callback(nextState);
|
||||
bool isMatch = sws->aut->isMatch(nextState);
|
||||
bool isMatch = automFuncs[aut->type].isMatch(aut, nextState);
|
||||
//bool isMatch = sws->aut->isMatch(nextState);
|
||||
FstNode *nextNode = fstGetNode(sws->fst, trn.addr);
|
||||
taosArrayPush(sws->inp, &(trn.inp));
|
||||
|
||||
if (FST_NODE_IS_FINAL(nextNode)) {
|
||||
void *eofState = sws->aut->acceptEof(nextState);
|
||||
//void *eofState = sws->aut->acceptEof(nextState);
|
||||
void *eofState = automFuncs[aut->type].acceptEof(aut, nextState);
|
||||
if (eofState != NULL) {
|
||||
isMatch = sws->aut->isMatch(eofState);
|
||||
isMatch = automFuncs[aut->type].isMatch(aut, eofState);
|
||||
}
|
||||
}
|
||||
StreamState s1 = { .node = p->node, .trans = p->trans + 1, .out = p->out, .autState = p->autState};
|
||||
|
@ -1390,7 +1403,7 @@ void streamStateDestroy(void *s) {
|
|||
//free(s->autoState);
|
||||
}
|
||||
|
||||
FstStreamBuilder *fstStreamBuilderCreate(Fst *fst, Automation *aut) {
|
||||
FstStreamBuilder *fstStreamBuilderCreate(Fst *fst, AutomationCtx *aut) {
|
||||
FstStreamBuilder *b = calloc(1, sizeof(FstStreamBuilder));
|
||||
if (NULL == b) { return NULL; }
|
||||
|
||||
|
@ -1433,3 +1446,5 @@ FstStreamBuilder *fstStreamBuilderRange(FstStreamBuilder *b, FstSlice *val, Rang
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -13,3 +13,94 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "index_fst_automation.h"
|
||||
|
||||
|
||||
// prefix query, impl later
|
||||
static void* prefixStart(AutomationCtx *ctx) {
|
||||
StartWithStateValue *data = (StartWithStateValue *)(ctx->data);
|
||||
return data;
|
||||
};
|
||||
static bool prefixIsMatch(AutomationCtx *ctx, void *data) {
|
||||
return true;
|
||||
}
|
||||
static bool prefixCanMatch(AutomationCtx *ctx, void *data) {
|
||||
return true;
|
||||
}
|
||||
static bool prefixWillAlwaysMatch(AutomationCtx *ctx, void *state) {
|
||||
return true;
|
||||
}
|
||||
static void* prefixAccept(AutomationCtx *ctx, void *state, uint8_t byte) {
|
||||
return NULL;
|
||||
}
|
||||
static void* prefixAcceptEof(AutomationCtx *ctx, void *state) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// pattern query, impl later
|
||||
|
||||
static void* patternStart(AutomationCtx *ctx) {
|
||||
return NULL;
|
||||
}
|
||||
static bool patternIsMatch(AutomationCtx *ctx, void *data) {
|
||||
return true;
|
||||
}
|
||||
static bool patternCanMatch(AutomationCtx *ctx, void *data) {
|
||||
return true;
|
||||
}
|
||||
static bool patternWillAlwaysMatch(AutomationCtx *ctx, void *state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void* patternAccept(AutomationCtx *ctx, void *state, uint8_t byte) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* patternAcceptEof(AutomationCtx *ctx, void *state) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AutomationFunc automFuncs[] = {{
|
||||
prefixStart,
|
||||
prefixIsMatch,
|
||||
prefixCanMatch,
|
||||
prefixWillAlwaysMatch,
|
||||
prefixAccept,
|
||||
prefixAcceptEof
|
||||
},
|
||||
{
|
||||
patternStart,
|
||||
patternIsMatch,
|
||||
patternCanMatch,
|
||||
patternWillAlwaysMatch,
|
||||
patternAccept,
|
||||
patternAcceptEof
|
||||
}
|
||||
// add more search type
|
||||
};
|
||||
|
||||
AutomationCtx* automCtxCreate(void *data, AutomationType type) {
|
||||
AutomationCtx *ctx = calloc(1, sizeof(AutomationCtx));
|
||||
if (ctx == NULL) { return NULL; }
|
||||
|
||||
if (type == AUTOMATION_PREFIX) {
|
||||
StartWithStateValue *swsv = (StartWithStateValue *)calloc(1, sizeof(StartWithStateValue));
|
||||
swsv->kind = Done;
|
||||
swsv->value = NULL;
|
||||
ctx->data = (void *)swsv;
|
||||
} else if (type == AUTMMATION_MATCH) {
|
||||
|
||||
} else {
|
||||
// add more search type
|
||||
}
|
||||
|
||||
ctx->type = type;
|
||||
return ctx;
|
||||
}
|
||||
void automCtxDestroy(AutomationCtx *ctx) {
|
||||
if (ctx->type == AUTOMATION_PREFIX) {
|
||||
free(ctx->data);
|
||||
} else if (ctx->type == AUTMMATION_MATCH) {
|
||||
}
|
||||
free(ctx);
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ class FstReadMemory {
|
|||
|
||||
~FstReadMemory() {
|
||||
fstCountingWriterDestroy(_w);
|
||||
fstDestroy(_fst);
|
||||
fstSliceDestroy(&_s);
|
||||
}
|
||||
|
||||
|
@ -129,10 +130,12 @@ class FstReadMemory {
|
|||
//}
|
||||
|
||||
|
||||
#define L 100
|
||||
#define M 100
|
||||
#define N 100
|
||||
|
||||
int Performance_fstWriteRecords(FstWriter *b) {
|
||||
std::string str("aa");
|
||||
int L = 100, M = 100, N = 10;
|
||||
for (int i = 0; i < L; i++) {
|
||||
str[0] = 'a' + i;
|
||||
str.resize(2);
|
||||
|
@ -150,22 +153,29 @@ int Performance_fstWriteRecords(FstWriter *b) {
|
|||
}
|
||||
|
||||
void Performance_fstReadRecords(FstReadMemory *m) {
|
||||
std::string str("a");
|
||||
for (int i = 0; i < 50; i++) {
|
||||
//std::string str("aa");
|
||||
str.push_back('a');
|
||||
uint64_t out, cost;
|
||||
bool ok = m->GetWithTimeCostUs(str, &out, &cost);
|
||||
if (ok == true) {
|
||||
printf("success to get (%s, %" PRId64"), time cost: %" PRId64")\n", str.c_str(), out, cost);
|
||||
} else {
|
||||
printf("failed to get(%s)\n", str.c_str());
|
||||
}
|
||||
}
|
||||
std::string str("aa");
|
||||
for (int i = 0; i < M; i++) {
|
||||
str[0] = 'a' + i;
|
||||
str.resize(2);
|
||||
for(int j = 0; j < N; j++) {
|
||||
str[1] = 'a' + j;
|
||||
str.resize(2);
|
||||
for (int k = 0; k < L; k++) {
|
||||
str.push_back('a');
|
||||
uint64_t val, cost;
|
||||
if (m->GetWithTimeCostUs(str, &val, &cost)) {
|
||||
printf("succes to get kv(%s, %" PRId64"), cost: %" PRId64"\n", str.c_str(), val, cost);
|
||||
} else {
|
||||
printf("failed to get key: %s\n", str.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void checkFstPerf() {
|
||||
FstWriter *fw = new FstWriter;
|
||||
int64_t s = taosGetTimestampUs();
|
||||
|
||||
int num = Performance_fstWriteRecords(fw);
|
||||
int64_t e = taosGetTimestampUs();
|
||||
printf("write %d record cost %" PRId64"us\n", num, e - s);
|
||||
|
@ -173,13 +183,11 @@ void checkFstPerf() {
|
|||
|
||||
FstReadMemory *m = new FstReadMemory(1024 * 64);
|
||||
if (m->init()) {
|
||||
uint64_t val;
|
||||
if(m->Get("aaaaaaa", &val)) {
|
||||
std::cout << "succes to Get val: " << val << std::endl;
|
||||
} else {
|
||||
std::cout << "failed to Get " << std::endl;
|
||||
}
|
||||
printf("success to init fst read");
|
||||
}
|
||||
Performance_fstReadRecords(m);
|
||||
|
||||
delete m;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ typedef struct SRelationInfo {
|
|||
|
||||
typedef struct SCreatedTableInfo {
|
||||
SToken name; // table name token
|
||||
SToken stableName; // super table name token , for using clause
|
||||
SToken stbName; // super table name token , for using clause
|
||||
SArray *pTagNames; // create by using super table, tag name
|
||||
SArray *pTagVals; // create by using super table, tag value
|
||||
char *fullname; // table full name
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* 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 TDENGINE_DATABLOCKMGT_H
|
||||
#define TDENGINE_DATABLOCKMGT_H
|
||||
|
||||
#include "catalog.h"
|
||||
#include "os.h"
|
||||
#include "ttypes.h"
|
||||
#include "tname.h"
|
||||
|
||||
#define IS_DATA_COL_ORDERED(spd) ((spd->orderStatus) == (int8_t)ORDER_STATUS_ORDERED)
|
||||
|
||||
typedef enum EOrderStatus {
|
||||
ORDER_STATUS_UNKNOWN = 0,
|
||||
ORDER_STATUS_ORDERED = 1,
|
||||
ORDER_STATUS_DISORDERED = 2,
|
||||
} EOrderStatus;
|
||||
|
||||
typedef enum EValStat {
|
||||
VAL_STAT_HAS = 0x0, // 0 means has val
|
||||
VAL_STAT_NONE = 0x01, // 1 means no val
|
||||
} EValStat;
|
||||
|
||||
typedef enum ERowCompareStat {
|
||||
ROW_COMPARE_NO_NEED = 0,
|
||||
ROW_COMPARE_NEED = 1,
|
||||
} ERowCompareStat;
|
||||
|
||||
typedef struct SBoundColumn {
|
||||
int32_t offset; // all column offset value
|
||||
int32_t toffset; // first part offset for SDataRow TODO: get offset from STSchema on future
|
||||
uint8_t valStat; // EValStat. denote if current column bound or not(0 means has val, 1 means no val)
|
||||
} SBoundColumn;
|
||||
|
||||
typedef struct {
|
||||
uint16_t schemaColIdx;
|
||||
uint16_t boundIdx;
|
||||
uint16_t finalIdx;
|
||||
} SBoundIdxInfo;
|
||||
|
||||
typedef struct SParsedDataColInfo {
|
||||
int16_t numOfCols;
|
||||
int16_t numOfBound;
|
||||
uint16_t flen; // TODO: get from STSchema
|
||||
uint16_t allNullLen; // TODO: get from STSchema
|
||||
uint16_t extendedVarLen;
|
||||
int32_t *boundedColumns; // bound column idx according to schema
|
||||
SBoundColumn *cols;
|
||||
SBoundIdxInfo *colIdxInfo;
|
||||
int8_t orderStatus; // bound columns
|
||||
} SParsedDataColInfo;
|
||||
|
||||
typedef struct SMemRowInfo {
|
||||
int32_t dataLen; // len of SDataRow
|
||||
int32_t kvLen; // len of SKVRow
|
||||
} SMemRowInfo;
|
||||
|
||||
typedef struct {
|
||||
uint8_t memRowType; // default is 0, that is SDataRow
|
||||
uint8_t compareStat; // 0 no need, 1 need compare
|
||||
TDRowTLenT kvRowInitLen;
|
||||
SMemRowInfo *rowInfo;
|
||||
} SMemRowBuilder;
|
||||
|
||||
typedef struct STableDataBlocks {
|
||||
int8_t tsSource; // where does the UNIX timestamp come from, server or client
|
||||
bool ordered; // if current rows are ordered or not
|
||||
int64_t vgId; // virtual group id
|
||||
int64_t prevTS; // previous timestamp, recorded to decide if the records array is ts ascending
|
||||
int32_t numOfTables; // number of tables in current submit block
|
||||
int32_t rowSize; // row size for current table
|
||||
uint32_t nAllocSize;
|
||||
uint32_t headerSize; // header for table info (uid, tid, submit metadata)
|
||||
uint32_t size;
|
||||
STableMeta *pTableMeta; // the tableMeta of current table, the table meta will be used during submit, keep a ref to avoid to be removed from cache
|
||||
char *pData;
|
||||
bool cloned;
|
||||
STagData tagData;
|
||||
|
||||
SParsedDataColInfo boundColumnInfo;
|
||||
SMemRowBuilder rowBuilder;
|
||||
} STableDataBlocks;
|
||||
|
||||
static FORCE_INLINE void initSMemRow(SMemRow row, uint8_t memRowType, STableDataBlocks *pBlock, int16_t nBoundCols) {
|
||||
memRowSetType(row, memRowType);
|
||||
if (isDataRowT(memRowType)) {
|
||||
dataRowSetVersion(memRowDataBody(row), pBlock->pTableMeta->sversion);
|
||||
dataRowSetLen(memRowDataBody(row), (TDRowLenT)(TD_DATA_ROW_HEAD_SIZE + pBlock->boundColumnInfo.flen));
|
||||
} else {
|
||||
ASSERT(nBoundCols > 0);
|
||||
memRowSetKvVersion(row, pBlock->pTableMeta->sversion);
|
||||
kvRowSetNCols(memRowKvBody(row), nBoundCols);
|
||||
kvRowSetLen(memRowKvBody(row), (TDRowLenT)(TD_KV_ROW_HEAD_SIZE + sizeof(SColIdx) * nBoundCols));
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t getExtendedRowSize(STableDataBlocks *pBlock) {
|
||||
ASSERT(pBlock->rowSize == pBlock->pTableMeta->tableInfo.rowSize);
|
||||
return pBlock->rowSize + TD_MEM_ROW_DATA_HEAD_SIZE + pBlock->boundColumnInfo.extendedVarLen;
|
||||
}
|
||||
|
||||
// Applicable to consume by one row
|
||||
static FORCE_INLINE void appendMemRowColValEx(SMemRow row, const void *value, bool isCopyVarData, int16_t colId,
|
||||
int8_t colType, int32_t toffset, int32_t *dataLen, int32_t *kvLen,
|
||||
uint8_t compareStat) {
|
||||
tdAppendMemRowColVal(row, value, isCopyVarData, colId, colType, toffset);
|
||||
if (compareStat == ROW_COMPARE_NEED) {
|
||||
tdGetColAppendDeltaLen(value, colType, dataLen, kvLen);
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void getMemRowAppendInfo(SSchema *pSchema, uint8_t memRowType, SParsedDataColInfo *spd,
|
||||
int32_t idx, int32_t *toffset) {
|
||||
int32_t schemaIdx = 0;
|
||||
if (IS_DATA_COL_ORDERED(spd)) {
|
||||
schemaIdx = spd->boundedColumns[idx];
|
||||
if (isDataRowT(memRowType)) {
|
||||
*toffset = (spd->cols + schemaIdx)->toffset; // the offset of firstPart
|
||||
} else {
|
||||
*toffset = idx * sizeof(SColIdx); // the offset of SColIdx
|
||||
}
|
||||
} else {
|
||||
ASSERT(idx == (spd->colIdxInfo + idx)->boundIdx);
|
||||
schemaIdx = (spd->colIdxInfo + idx)->schemaColIdx;
|
||||
if (isDataRowT(memRowType)) {
|
||||
*toffset = (spd->cols + schemaIdx)->toffset;
|
||||
} else {
|
||||
*toffset = ((spd->colIdxInfo + idx)->finalIdx) * sizeof(SColIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void convertMemRow(SMemRow row, int32_t dataLen, int32_t kvLen) {
|
||||
if (isDataRow(row)) {
|
||||
if (kvLen < (dataLen * KVRatioConvert)) {
|
||||
memRowSetConvert(row);
|
||||
}
|
||||
} else if (kvLen > dataLen) {
|
||||
memRowSetConvert(row);
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t setBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows) {
|
||||
pBlocks->tid = pTableMeta->suid;
|
||||
pBlocks->uid = pTableMeta->uid;
|
||||
pBlocks->sversion = pTableMeta->sversion;
|
||||
|
||||
if (pBlocks->numOfRows + numOfRows >= INT16_MAX) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
} else {
|
||||
pBlocks->numOfRows += numOfRows;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t schemaIdxCompar(const void *lhs, const void *rhs);
|
||||
int32_t boundIdxCompar(const void *lhs, const void *rhs);
|
||||
void setBoundColumnInfo(SParsedDataColInfo* pColList, SSchema* pSchema, int32_t numOfCols);
|
||||
void destroyBoundColumnInfo(SParsedDataColInfo* pColList);
|
||||
int32_t initMemRowBuilder(SMemRowBuilder *pBuilder, uint32_t nRows, uint32_t nCols, uint32_t nBoundCols, int32_t allNullLen);
|
||||
int32_t allocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t * numOfRows);
|
||||
int32_t getDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, int32_t startOffset, int32_t rowSize,
|
||||
const STableMeta* pTableMeta, STableDataBlocks** dataBlocks, SArray* pBlockList);
|
||||
int32_t mergeTableDataBlocks(SHashObj* pHashObj, int8_t schemaAttached, uint8_t payloadType, bool freeBlockMap);
|
||||
|
||||
#endif // TDENGINE_DATABLOCKMGT_H
|
|
@ -16,4 +16,16 @@
|
|||
#ifndef TDENGINE_INSERTPARSER_H
|
||||
#define TDENGINE_INSERTPARSER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
int32_t parseInsertSql(SParseContext* pContext, SInsertStmtInfo** pInfo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TDENGINE_INSERTPARSER_H
|
||||
|
|
|
@ -26,14 +26,6 @@ extern "C" {
|
|||
|
||||
struct SSqlNode;
|
||||
|
||||
typedef struct SInsertStmtInfo {
|
||||
SHashObj *pTableBlockHashList; // data block for each table
|
||||
SArray *pDataBlocks; // SArray<STableDataBlocks*>. Merged submit block for each vgroup
|
||||
int8_t schemaAttached; // denote if submit block is built with table schema or not
|
||||
uint8_t payloadType; // EPayloadType. 0: K-V payload for non-prepare insert, 1: rawPayload for prepare insert
|
||||
uint32_t insertType; // insert data from [file|sql statement| bound statement]
|
||||
char *sql; // current sql statement position
|
||||
} SInsertStmtInfo;
|
||||
|
||||
typedef struct SInternalField {
|
||||
TAOS_FIELD field;
|
||||
|
|
|
@ -46,7 +46,7 @@ SInternalField* getInternalField(SFieldInfo* pFieldInfo, int32_t index);
|
|||
|
||||
int32_t parserValidateIdToken(SToken* pToken);
|
||||
int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg);
|
||||
int32_t buildSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalInfo, const char* sourceStr);
|
||||
int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr);
|
||||
|
||||
STableMetaInfo* addEmptyMetaInfo(SQueryStmtInfo* pQueryInfo);
|
||||
|
||||
|
@ -61,6 +61,8 @@ void cleanupColumnCond(SArray** pCond);
|
|||
uint32_t convertRelationalOperator(SToken *pToken);
|
||||
int32_t getExprFunctionId(SExprInfo *pExprInfo);
|
||||
|
||||
STableMeta* tableMetaDup(const STableMeta* pTableMeta);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue