From aec3a06431ab395709e6839cd720c388b5bc7f68 Mon Sep 17 00:00:00 2001 From: afwerar <1296468573@qq.com> Date: Tue, 30 Aug 2022 16:11:42 +0800 Subject: [PATCH 1/7] feature: shell csv rfc 4180 --- tools/shell/inc/shellInt.h | 2 +- tools/shell/src/shellEngine.c | 56 +++++++++++++++++++++----------- tools/shell/src/shellWebsocket.c | 24 ++++++++------ 3 files changed, 52 insertions(+), 30 deletions(-) diff --git a/tools/shell/inc/shellInt.h b/tools/shell/inc/shellInt.h index 26ca6895ac..6a9d6cb0df 100644 --- a/tools/shell/inc/shellInt.h +++ b/tools/shell/inc/shellInt.h @@ -113,7 +113,7 @@ int32_t shellExecute(); int32_t shellCalcColWidth(TAOS_FIELD *field, int32_t precision); void shellPrintHeader(TAOS_FIELD *fields, int32_t *width, int32_t num_fields); void shellPrintField(const char *val, TAOS_FIELD *field, int32_t width, int32_t length, int32_t precision); -void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, int32_t length, int32_t precision); +void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, int32_t length, int32_t precision, bool quotation); // shellUtil.c int32_t shellCheckIntSize(); void shellPrintVersion(); diff --git a/tools/shell/src/shellEngine.c b/tools/shell/src/shellEngine.c index 68e3a272c3..10e806e041 100644 --- a/tools/shell/src/shellEngine.c +++ b/tools/shell/src/shellEngine.c @@ -264,9 +264,15 @@ char *shellFormatTimestamp(char *buf, int64_t val, int32_t precision) { return buf; } -void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, int32_t length, int32_t precision) { +void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, int32_t length, int32_t precision, bool quotation) { + char quotationStr[2]; + quotationStr[0] = 0; + quotationStr[1] = 0; + if (quotation) { + quotationStr[0] = '\"'; + } if (val == NULL) { - taosFprintfFile(pFile, "%s", TSDB_DATA_NULL_STR); + taosFprintfFile(pFile, "%s%s%s", quotationStr, TSDB_DATA_NULL_STR, quotationStr); return; } @@ -274,39 +280,39 @@ void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, i char buf[TSDB_MAX_BYTES_PER_ROW]; switch (field->type) { case TSDB_DATA_TYPE_BOOL: - taosFprintfFile(pFile, "%d", ((((int32_t)(*((char *)val))) == 1) ? 1 : 0)); + taosFprintfFile(pFile, "%s%d%s", quotationStr, ((((int32_t)(*((char *)val))) == 1) ? 1 : 0), quotationStr); break; case TSDB_DATA_TYPE_TINYINT: - taosFprintfFile(pFile, "%d", *((int8_t *)val)); + taosFprintfFile(pFile, "%s%d%s", quotationStr, *((int8_t *)val), quotationStr); break; case TSDB_DATA_TYPE_UTINYINT: - taosFprintfFile(pFile, "%u", *((uint8_t *)val)); + taosFprintfFile(pFile, "%s%u%s", quotationStr, *((uint8_t *)val), quotationStr); break; case TSDB_DATA_TYPE_SMALLINT: - taosFprintfFile(pFile, "%d", *((int16_t *)val)); + taosFprintfFile(pFile, "%s%d%s", quotationStr, *((int16_t *)val), quotationStr); break; case TSDB_DATA_TYPE_USMALLINT: - taosFprintfFile(pFile, "%u", *((uint16_t *)val)); + taosFprintfFile(pFile, "%s%u%s", quotationStr, *((uint16_t *)val), quotationStr); break; case TSDB_DATA_TYPE_INT: - taosFprintfFile(pFile, "%d", *((int32_t *)val)); + taosFprintfFile(pFile, "%s%d%s", quotationStr, *((int32_t *)val), quotationStr); break; case TSDB_DATA_TYPE_UINT: - taosFprintfFile(pFile, "%u", *((uint32_t *)val)); + taosFprintfFile(pFile, "%s%u%s", quotationStr, *((uint32_t *)val), quotationStr); break; case TSDB_DATA_TYPE_BIGINT: - taosFprintfFile(pFile, "%" PRId64, *((int64_t *)val)); + taosFprintfFile(pFile, "%s%" PRId64 "%s", quotationStr, *((int64_t *)val), quotationStr); break; case TSDB_DATA_TYPE_UBIGINT: - taosFprintfFile(pFile, "%" PRIu64, *((uint64_t *)val)); + taosFprintfFile(pFile, "%s%" PRIu64 "%s", quotationStr, *((uint64_t *)val), quotationStr); break; case TSDB_DATA_TYPE_FLOAT: - taosFprintfFile(pFile, "%.5f", GET_FLOAT_VAL(val)); + taosFprintfFile(pFile, "%s%.5f%s", quotationStr, GET_FLOAT_VAL(val), quotationStr); break; case TSDB_DATA_TYPE_DOUBLE: - n = snprintf(buf, TSDB_MAX_BYTES_PER_ROW, "%*.9f", length, GET_DOUBLE_VAL(val)); + n = snprintf(buf, TSDB_MAX_BYTES_PER_ROW, "%s%*.9f%s", quotationStr, length, GET_DOUBLE_VAL(val), quotationStr); if (n > TMAX(25, length)) { - taosFprintfFile(pFile, "%*.15e", length, GET_DOUBLE_VAL(val)); + taosFprintfFile(pFile, "%s%*.15e%s", quotationStr, length, GET_DOUBLE_VAL(val), quotationStr); } else { taosFprintfFile(pFile, "%s", buf); } @@ -314,13 +320,21 @@ void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, i case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_JSON: - memcpy(buf, val, length); - buf[length] = 0; - taosFprintfFile(pFile, "\'%s\'", buf); + int32_t bufIndex = 0; + for (int32_t i = 0; i < length; i++) { + buf[bufIndex] = val[i]; + bufIndex++; + if (val[i] == '\"') { + buf[bufIndex] = val[i]; + bufIndex++; + } + } + buf[bufIndex] = 0; + taosFprintfFile(pFile, "%s%s%s", quotationStr, buf, quotationStr); break; case TSDB_DATA_TYPE_TIMESTAMP: shellFormatTimestamp(buf, *(int64_t *)val, precision); - taosFprintfFile(pFile, "'%s'", buf); + taosFprintfFile(pFile, "%s%s%s", quotationStr, buf, quotationStr); break; default: break; @@ -347,12 +361,16 @@ int32_t shellDumpResultToFile(const char *fname, TAOS_RES *tres) { TAOS_FIELD *fields = taos_fetch_fields(tres); int32_t num_fields = taos_num_fields(tres); int32_t precision = taos_result_precision(tres); + bool quotation = false; for (int32_t col = 0; col < num_fields; col++) { if (col > 0) { taosFprintfFile(pFile, ","); } taosFprintfFile(pFile, "%s", fields[col].name); + if (fields[col].type == TSDB_DATA_TYPE_BINARY || fields[col].type == TSDB_DATA_TYPE_NCHAR || fields[col].type == TSDB_DATA_TYPE_JSON) { + quotation = true; + } } taosFprintfFile(pFile, "\r\n"); @@ -363,7 +381,7 @@ int32_t shellDumpResultToFile(const char *fname, TAOS_RES *tres) { if (i > 0) { taosFprintfFile(pFile, ","); } - shellDumpFieldToFile(pFile, (const char *)row[i], fields + i, length[i], precision); + shellDumpFieldToFile(pFile, (const char *)row[i], fields + i, length[i], precision, quotation); } taosFprintfFile(pFile, "\r\n"); diff --git a/tools/shell/src/shellWebsocket.c b/tools/shell/src/shellWebsocket.c index 2dcab04b3f..37961b75c7 100644 --- a/tools/shell/src/shellWebsocket.c +++ b/tools/shell/src/shellWebsocket.c @@ -132,17 +132,21 @@ static int dumpWebsocketToFile(const char* fname, WS_RES* wres, double* pexecute *pexecute_time += (double)(ws_take_timing(wres)/1E6); if (!rows) { taosCloseFile(&pFile); - return 0; + return 0; } int numOfRows = 0; TAOS_FIELD* fields = (TAOS_FIELD*)ws_fetch_fields(wres); int num_fields = ws_field_count(wres); int precision = ws_result_precision(wres); + bool quotation = false; for (int col = 0; col < num_fields; col++) { if (col > 0) { taosFprintfFile(pFile, ","); } taosFprintfFile(pFile, "%s", fields[col].name); + if (fields[col].type == TSDB_DATA_TYPE_BINARY || fields[col].type == TSDB_DATA_TYPE_NCHAR || fields[col].type == TSDB_DATA_TYPE_JSON) { + quotation = true; + } } taosFprintfFile(pFile, "\r\n"); do { @@ -155,7 +159,7 @@ static int dumpWebsocketToFile(const char* fname, WS_RES* wres, double* pexecute taosFprintfFile(pFile, ","); } const void *value = ws_get_value_in_block(wres, i, j, &ty, &len); - shellDumpFieldToFile(pFile, (const char*)value, fields + j, len, precision); + shellDumpFieldToFile(pFile, (const char*)value, fields + j, len, precision, quotation); } taosFprintfFile(pFile, "\r\n"); } @@ -233,17 +237,17 @@ void shellRunSingleCommandWebsocketImp(char *command) { if (shellRegexMatch(command, "^\\s*use\\s+[a-zA-Z0-9_]+\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) { fprintf(stdout, "Database changed.\r\n\r\n"); fflush(stdout); - ws_free_result(res); + ws_free_result(res); return; } int numOfRows = 0; if (ws_is_update_query(res)) { - numOfRows = ws_affected_rows(res); - et = taosGetTimestampUs(); + numOfRows = ws_affected_rows(res); + et = taosGetTimestampUs(); double total_time = (et - st)/1E3; double net_time = total_time - (double)execute_time; - printf("Query Ok, %d of %d row(s) in database\n", numOfRows, numOfRows); + printf("Query Ok, %d of %d row(s) in database\n", numOfRows, numOfRows); printf("Execute: %.2f ms Network: %.2f ms Total: %.2f ms\n", execute_time, net_time, total_time); } else { int error_no = 0; @@ -253,15 +257,15 @@ void shellRunSingleCommandWebsocketImp(char *command) { return; } et = taosGetTimestampUs(); - double total_time = (et - st) / 1E3; - double net_time = total_time - execute_time; + double total_time = (et - st) / 1E3; + double net_time = total_time - execute_time; if (error_no == 0 && !shell.stop_query) { printf("Query OK, %d row(s) in set\n", numOfRows); - printf("Execute: %.2f ms Network: %.2f ms Total: %.2f ms\n", execute_time, net_time, total_time); + printf("Execute: %.2f ms Network: %.2f ms Total: %.2f ms\n", execute_time, net_time, total_time); } else { printf("Query interrupted, %d row(s) in set (%.6fs)\n", numOfRows, (et - st)/1E6); - printf("Execute: %.2f ms Network: %.2f ms Total: %.2f ms\n", execute_time, net_time, total_time); + printf("Execute: %.2f ms Network: %.2f ms Total: %.2f ms\n", execute_time, net_time, total_time); } } printf("\n"); From 8a34a321c76e5587c759320be85b8ca0a18b3d80 Mon Sep 17 00:00:00 2001 From: afwerar <1296468573@qq.com> Date: Tue, 30 Aug 2022 16:30:20 +0800 Subject: [PATCH 2/7] feature: shell csv rfc 4180 --- source/util/src/version.c.in | 2 +- tools/shell/src/shellEngine.c | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/source/util/src/version.c.in b/source/util/src/version.c.in index be1a4a4048..cb307b57fc 100644 --- a/source/util/src/version.c.in +++ b/source/util/src/version.c.in @@ -1,4 +1,4 @@ -char version[12] = "${TD_VER_NUMBER}"; +char version[64] = "${TD_VER_NUMBER}"; char compatible_version[12] = "${TD_VER_COMPATIBLE}"; char gitinfo[48] = "${TD_VER_GIT}"; char buildinfo[64] = "Built at ${TD_VER_DATE}"; diff --git a/tools/shell/src/shellEngine.c b/tools/shell/src/shellEngine.c index 10e806e041..84987f80ec 100644 --- a/tools/shell/src/shellEngine.c +++ b/tools/shell/src/shellEngine.c @@ -320,17 +320,19 @@ void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, i case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_JSON: - int32_t bufIndex = 0; - for (int32_t i = 0; i < length; i++) { - buf[bufIndex] = val[i]; - bufIndex++; - if (val[i] == '\"') { + { + int32_t bufIndex = 0; + for (int32_t i = 0; i < length; i++) { buf[bufIndex] = val[i]; bufIndex++; + if (val[i] == '\"') { + buf[bufIndex] = val[i]; + bufIndex++; + } } + buf[bufIndex] = 0; + taosFprintfFile(pFile, "%s%s%s", quotationStr, buf, quotationStr); } - buf[bufIndex] = 0; - taosFprintfFile(pFile, "%s%s%s", quotationStr, buf, quotationStr); break; case TSDB_DATA_TYPE_TIMESTAMP: shellFormatTimestamp(buf, *(int64_t *)val, precision); From 4632c3751b0b6623a0e79c9c9937ac14225228a3 Mon Sep 17 00:00:00 2001 From: afwerar <1296468573@qq.com> Date: Tue, 30 Aug 2022 17:21:38 +0800 Subject: [PATCH 3/7] feature: shell csv rfc 4180 --- tools/shell/inc/shellInt.h | 2 +- tools/shell/src/shellEngine.c | 43 ++++++++++++++++++----------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/tools/shell/inc/shellInt.h b/tools/shell/inc/shellInt.h index 6a9d6cb0df..15f6f6dc6a 100644 --- a/tools/shell/inc/shellInt.h +++ b/tools/shell/inc/shellInt.h @@ -113,7 +113,7 @@ int32_t shellExecute(); int32_t shellCalcColWidth(TAOS_FIELD *field, int32_t precision); void shellPrintHeader(TAOS_FIELD *fields, int32_t *width, int32_t num_fields); void shellPrintField(const char *val, TAOS_FIELD *field, int32_t width, int32_t length, int32_t precision); -void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, int32_t length, int32_t precision, bool quotation); +void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, int32_t length, int32_t precision); // shellUtil.c int32_t shellCheckIntSize(); void shellPrintVersion(); diff --git a/tools/shell/src/shellEngine.c b/tools/shell/src/shellEngine.c index 84987f80ec..fdc28c92ec 100644 --- a/tools/shell/src/shellEngine.c +++ b/tools/shell/src/shellEngine.c @@ -264,15 +264,9 @@ char *shellFormatTimestamp(char *buf, int64_t val, int32_t precision) { return buf; } -void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, int32_t length, int32_t precision, bool quotation) { - char quotationStr[2]; - quotationStr[0] = 0; - quotationStr[1] = 0; - if (quotation) { - quotationStr[0] = '\"'; - } +void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, int32_t length, int32_t precision) { if (val == NULL) { - taosFprintfFile(pFile, "%s%s%s", quotationStr, TSDB_DATA_NULL_STR, quotationStr); + taosFprintfFile(pFile, "%s", TSDB_DATA_NULL_STR); return; } @@ -280,39 +274,39 @@ void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, i char buf[TSDB_MAX_BYTES_PER_ROW]; switch (field->type) { case TSDB_DATA_TYPE_BOOL: - taosFprintfFile(pFile, "%s%d%s", quotationStr, ((((int32_t)(*((char *)val))) == 1) ? 1 : 0), quotationStr); + taosFprintfFile(pFile, "%d", ((((int32_t)(*((char *)val))) == 1) ? 1 : 0)); break; case TSDB_DATA_TYPE_TINYINT: - taosFprintfFile(pFile, "%s%d%s", quotationStr, *((int8_t *)val), quotationStr); + taosFprintfFile(pFile, "%d", *((int8_t *)val)); break; case TSDB_DATA_TYPE_UTINYINT: - taosFprintfFile(pFile, "%s%u%s", quotationStr, *((uint8_t *)val), quotationStr); + taosFprintfFile(pFile, "%u", *((uint8_t *)val)); break; case TSDB_DATA_TYPE_SMALLINT: - taosFprintfFile(pFile, "%s%d%s", quotationStr, *((int16_t *)val), quotationStr); + taosFprintfFile(pFile, "%d", *((int16_t *)val)); break; case TSDB_DATA_TYPE_USMALLINT: - taosFprintfFile(pFile, "%s%u%s", quotationStr, *((uint16_t *)val), quotationStr); + taosFprintfFile(pFile, "%u", *((uint16_t *)val)); break; case TSDB_DATA_TYPE_INT: - taosFprintfFile(pFile, "%s%d%s", quotationStr, *((int32_t *)val), quotationStr); + taosFprintfFile(pFile, "%d", *((int32_t *)val)); break; case TSDB_DATA_TYPE_UINT: - taosFprintfFile(pFile, "%s%u%s", quotationStr, *((uint32_t *)val), quotationStr); + taosFprintfFile(pFile, "%u", *((uint32_t *)val)); break; case TSDB_DATA_TYPE_BIGINT: - taosFprintfFile(pFile, "%s%" PRId64 "%s", quotationStr, *((int64_t *)val), quotationStr); + taosFprintfFile(pFile, "%" PRId64, *((int64_t *)val)); break; case TSDB_DATA_TYPE_UBIGINT: - taosFprintfFile(pFile, "%s%" PRIu64 "%s", quotationStr, *((uint64_t *)val), quotationStr); + taosFprintfFile(pFile, "%" PRIu64, *((uint64_t *)val)); break; case TSDB_DATA_TYPE_FLOAT: - taosFprintfFile(pFile, "%s%.5f%s", quotationStr, GET_FLOAT_VAL(val), quotationStr); + taosFprintfFile(pFile, "%.5f", GET_FLOAT_VAL(val)); break; case TSDB_DATA_TYPE_DOUBLE: - n = snprintf(buf, TSDB_MAX_BYTES_PER_ROW, "%s%*.9f%s", quotationStr, length, GET_DOUBLE_VAL(val), quotationStr); + n = snprintf(buf, TSDB_MAX_BYTES_PER_ROW, "%*.9f", length, GET_DOUBLE_VAL(val)); if (n > TMAX(25, length)) { - taosFprintfFile(pFile, "%s%*.15e%s", quotationStr, length, GET_DOUBLE_VAL(val), quotationStr); + taosFprintfFile(pFile, "%*.15e", length, GET_DOUBLE_VAL(val)); } else { taosFprintfFile(pFile, "%s", buf); } @@ -321,13 +315,20 @@ void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, i case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_JSON: { + char quotationStr[2]; int32_t bufIndex = 0; + quotationStr[0] = 0; + quotationStr[1] = 0; for (int32_t i = 0; i < length; i++) { buf[bufIndex] = val[i]; bufIndex++; if (val[i] == '\"') { buf[bufIndex] = val[i]; bufIndex++; + quotationStr[0] = '\"'; + } + if (val[i] == ',') { + quotationStr[0] = '\"'; } } buf[bufIndex] = 0; @@ -336,7 +337,7 @@ void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, i break; case TSDB_DATA_TYPE_TIMESTAMP: shellFormatTimestamp(buf, *(int64_t *)val, precision); - taosFprintfFile(pFile, "%s%s%s", quotationStr, buf, quotationStr); + taosFprintfFile(pFile, "%s", buf); break; default: break; From 3220a9547f8fb0c79069713fce4fc5166d73999a Mon Sep 17 00:00:00 2001 From: afwerar <1296468573@qq.com> Date: Tue, 30 Aug 2022 17:23:02 +0800 Subject: [PATCH 4/7] feature: shell csv rfc 4180 --- tools/shell/src/shellWebsocket.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/shell/src/shellWebsocket.c b/tools/shell/src/shellWebsocket.c index 37961b75c7..84d083e1c1 100644 --- a/tools/shell/src/shellWebsocket.c +++ b/tools/shell/src/shellWebsocket.c @@ -138,15 +138,11 @@ static int dumpWebsocketToFile(const char* fname, WS_RES* wres, double* pexecute TAOS_FIELD* fields = (TAOS_FIELD*)ws_fetch_fields(wres); int num_fields = ws_field_count(wres); int precision = ws_result_precision(wres); - bool quotation = false; for (int col = 0; col < num_fields; col++) { if (col > 0) { taosFprintfFile(pFile, ","); } taosFprintfFile(pFile, "%s", fields[col].name); - if (fields[col].type == TSDB_DATA_TYPE_BINARY || fields[col].type == TSDB_DATA_TYPE_NCHAR || fields[col].type == TSDB_DATA_TYPE_JSON) { - quotation = true; - } } taosFprintfFile(pFile, "\r\n"); do { @@ -159,7 +155,7 @@ static int dumpWebsocketToFile(const char* fname, WS_RES* wres, double* pexecute taosFprintfFile(pFile, ","); } const void *value = ws_get_value_in_block(wres, i, j, &ty, &len); - shellDumpFieldToFile(pFile, (const char*)value, fields + j, len, precision, quotation); + shellDumpFieldToFile(pFile, (const char*)value, fields + j, len, precision); } taosFprintfFile(pFile, "\r\n"); } From c5f270abcbb5c49117462f57a94ebafeede749fb Mon Sep 17 00:00:00 2001 From: afwerar <1296468573@qq.com> Date: Tue, 30 Aug 2022 17:24:24 +0800 Subject: [PATCH 5/7] feature: shell csv rfc 4180 --- tools/shell/src/shellEngine.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/shell/src/shellEngine.c b/tools/shell/src/shellEngine.c index fdc28c92ec..3b760a097f 100644 --- a/tools/shell/src/shellEngine.c +++ b/tools/shell/src/shellEngine.c @@ -364,16 +364,12 @@ int32_t shellDumpResultToFile(const char *fname, TAOS_RES *tres) { TAOS_FIELD *fields = taos_fetch_fields(tres); int32_t num_fields = taos_num_fields(tres); int32_t precision = taos_result_precision(tres); - bool quotation = false; for (int32_t col = 0; col < num_fields; col++) { if (col > 0) { taosFprintfFile(pFile, ","); } taosFprintfFile(pFile, "%s", fields[col].name); - if (fields[col].type == TSDB_DATA_TYPE_BINARY || fields[col].type == TSDB_DATA_TYPE_NCHAR || fields[col].type == TSDB_DATA_TYPE_JSON) { - quotation = true; - } } taosFprintfFile(pFile, "\r\n"); @@ -384,7 +380,7 @@ int32_t shellDumpResultToFile(const char *fname, TAOS_RES *tres) { if (i > 0) { taosFprintfFile(pFile, ","); } - shellDumpFieldToFile(pFile, (const char *)row[i], fields + i, length[i], precision, quotation); + shellDumpFieldToFile(pFile, (const char *)row[i], fields + i, length[i], precision); } taosFprintfFile(pFile, "\r\n"); From 52bedb2b532f605059915541e719b1bb532192bf Mon Sep 17 00:00:00 2001 From: afwerar <1296468573@qq.com> Date: Tue, 30 Aug 2022 17:27:35 +0800 Subject: [PATCH 6/7] feature: shell csv rfc 4180 --- tools/shell/src/shellWebsocket.c | 102 +++++++++++++++---------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/tools/shell/src/shellWebsocket.c b/tools/shell/src/shellWebsocket.c index 84d083e1c1..b8b8392b96 100644 --- a/tools/shell/src/shellWebsocket.c +++ b/tools/shell/src/shellWebsocket.c @@ -18,19 +18,19 @@ #include "shellInt.h" int shell_conn_ws_server(bool first) { - shell.ws_conn = ws_connect_with_dsn(shell.args.dsn); - if (!shell.ws_conn) { - fprintf(stderr, "failed to connect %s, reason: %s\n", - shell.args.dsn, ws_errstr(NULL)); - return -1; - } - if (first && shell.args.restful) { - fprintf(stdout, "successfully connect to %s\n\n", - shell.args.dsn); - } else if (first && shell.args.cloud) { - fprintf(stdout, "successfully connect to cloud service\n"); - } - return 0; + shell.ws_conn = ws_connect_with_dsn(shell.args.dsn); + if (!shell.ws_conn) { + fprintf(stderr, "failed to connect %s, reason: %s\n", + shell.args.dsn, ws_errstr(NULL)); + return -1; + } + if (first && shell.args.restful) { + fprintf(stdout, "successfully connect to %s\n\n", + shell.args.dsn); + } else if (first && shell.args.cloud) { + fprintf(stdout, "successfully connect to cloud service\n"); + } + return 0; } static int horizontalPrintWebsocket(WS_RES* wres, double* execute_time) { @@ -39,7 +39,7 @@ static int horizontalPrintWebsocket(WS_RES* wres, double* execute_time) { ws_fetch_block(wres, &data, &rows); *execute_time += (double)(ws_take_timing(wres)/1E6); if (!rows) { - return 0; + return 0; } int num_fields = ws_field_count(wres); TAOS_FIELD* fields = (TAOS_FIELD*)ws_fetch_fields(wres); @@ -64,7 +64,7 @@ static int horizontalPrintWebsocket(WS_RES* wres, double* execute_time) { putchar(' '); putchar('|'); } - putchar('\r'); + putchar('\r'); putchar('\n'); } numOfRows += rows; @@ -79,7 +79,7 @@ static int verticalPrintWebsocket(WS_RES* wres, double* pexecute_time) { ws_fetch_block(wres, &data, &rows); *pexecute_time += (double)(ws_take_timing(wres)/1E6); if (!rows) { - return 0; + return 0; } int num_fields = ws_field_count(wres); TAOS_FIELD* fields = (TAOS_FIELD*)ws_fetch_fields(wres); @@ -98,7 +98,7 @@ static int verticalPrintWebsocket(WS_RES* wres, double* pexecute_time) { uint32_t len; for (int i = 0; i < rows; i++) { printf("*************************** %d.row ***************************\n", - numOfRows + 1); + numOfRows + 1); for (int j = 0; j < num_fields; j++) { TAOS_FIELD* field = fields + j; int padding = (int)(maxColNameLen - strlen(field->name)); @@ -121,7 +121,7 @@ static int dumpWebsocketToFile(const char* fname, WS_RES* wres, double* pexecute } TdFilePtr pFile = taosOpenFile(fullname, - TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_STREAM); + TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_STREAM); if (pFile == NULL) { fprintf(stderr, "failed to open file: %s\r\n", fullname); return -1; @@ -132,7 +132,7 @@ static int dumpWebsocketToFile(const char* fname, WS_RES* wres, double* pexecute *pexecute_time += (double)(ws_take_timing(wres)/1E6); if (!rows) { taosCloseFile(&pFile); - return 0; + return 0; } int numOfRows = 0; TAOS_FIELD* fields = (TAOS_FIELD*)ws_fetch_fields(wres); @@ -207,7 +207,7 @@ void shellRunSingleCommandWebsocketImp(char *command) { } if (!shell.ws_conn && shell_conn_ws_server(0)) { - return; + return; } shell.stop_query = false; @@ -216,16 +216,16 @@ void shellRunSingleCommandWebsocketImp(char *command) { WS_RES* res = ws_query_timeout(shell.ws_conn, command, shell.args.timeout); int code = ws_errno(res); if (code != 0) { - et = taosGetTimestampUs(); - fprintf(stderr, "\nDB: error: %s (%.6fs)\n", ws_errstr(res), (et - st)/1E6); - if (code == TSDB_CODE_WS_SEND_TIMEOUT || code == TSDB_CODE_WS_RECV_TIMEOUT) { - fprintf(stderr, "Hint: use -t to increase the timeout in seconds\n"); - } else if (code == TSDB_CODE_WS_INTERNAL_ERRO || code == TSDB_CODE_WS_CLOSED) { - fprintf(stderr, "TDengine server is down, will try to reconnect\n"); - shell.ws_conn = NULL; - } - ws_free_result(res); - return; + et = taosGetTimestampUs(); + fprintf(stderr, "\nDB: error: %s (%.6fs)\n", ws_errstr(res), (et - st)/1E6); + if (code == TSDB_CODE_WS_SEND_TIMEOUT || code == TSDB_CODE_WS_RECV_TIMEOUT) { + fprintf(stderr, "Hint: use -t to increase the timeout in seconds\n"); + } else if (code == TSDB_CODE_WS_INTERNAL_ERRO || code == TSDB_CODE_WS_CLOSED) { + fprintf(stderr, "TDengine server is down, will try to reconnect\n"); + shell.ws_conn = NULL; + } + ws_free_result(res); + return; } double execute_time = ws_take_timing(res)/1E6; @@ -233,36 +233,36 @@ void shellRunSingleCommandWebsocketImp(char *command) { if (shellRegexMatch(command, "^\\s*use\\s+[a-zA-Z0-9_]+\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) { fprintf(stdout, "Database changed.\r\n\r\n"); fflush(stdout); - ws_free_result(res); + ws_free_result(res); return; } int numOfRows = 0; if (ws_is_update_query(res)) { - numOfRows = ws_affected_rows(res); - et = taosGetTimestampUs(); + numOfRows = ws_affected_rows(res); + et = taosGetTimestampUs(); double total_time = (et - st)/1E3; double net_time = total_time - (double)execute_time; - printf("Query Ok, %d of %d row(s) in database\n", numOfRows, numOfRows); + printf("Query Ok, %d of %d row(s) in database\n", numOfRows, numOfRows); printf("Execute: %.2f ms Network: %.2f ms Total: %.2f ms\n", execute_time, net_time, total_time); } else { - int error_no = 0; - numOfRows = shellDumpWebsocket(res, fname, &error_no, printMode, &execute_time); - if (numOfRows < 0) { - ws_free_result(res); - return; - } - et = taosGetTimestampUs(); - double total_time = (et - st) / 1E3; - double net_time = total_time - execute_time; - if (error_no == 0 && !shell.stop_query) { - printf("Query OK, %d row(s) in set\n", numOfRows); - printf("Execute: %.2f ms Network: %.2f ms Total: %.2f ms\n", execute_time, net_time, total_time); - } else { - printf("Query interrupted, %d row(s) in set (%.6fs)\n", numOfRows, - (et - st)/1E6); - printf("Execute: %.2f ms Network: %.2f ms Total: %.2f ms\n", execute_time, net_time, total_time); - } + int error_no = 0; + numOfRows = shellDumpWebsocket(res, fname, &error_no, printMode, &execute_time); + if (numOfRows < 0) { + ws_free_result(res); + return; + } + et = taosGetTimestampUs(); + double total_time = (et - st) / 1E3; + double net_time = total_time - execute_time; + if (error_no == 0 && !shell.stop_query) { + printf("Query OK, %d row(s) in set\n", numOfRows); + printf("Execute: %.2f ms Network: %.2f ms Total: %.2f ms\n", execute_time, net_time, total_time); + } else { + printf("Query interrupted, %d row(s) in set (%.6fs)\n", numOfRows, + (et - st)/1E6); + printf("Execute: %.2f ms Network: %.2f ms Total: %.2f ms\n", execute_time, net_time, total_time); + } } printf("\n"); ws_free_result(res); From 500cf0c758747ec5f92d52cdbcea3a3af2900273 Mon Sep 17 00:00:00 2001 From: afwerar <1296468573@qq.com> Date: Wed, 31 Aug 2022 13:30:35 +0800 Subject: [PATCH 7/7] feature: shell csv rfc 4180 --- tests/test/c/tmqSim.c | 30 +++++++++++++++++++++++++----- tools/shell/src/shellEngine.c | 5 ++++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/tests/test/c/tmqSim.c b/tests/test/c/tmqSim.c index d39ade7e91..71b31ba107 100644 --- a/tests/test/c/tmqSim.c +++ b/tests/test/c/tmqSim.c @@ -492,7 +492,6 @@ static char* shellFormatTimestamp(char* buf, int64_t val, int32_t precision) { static void shellDumpFieldToFile(TdFilePtr pFile, const char* val, TAOS_FIELD* field, int32_t length, int32_t precision) { if (val == NULL) { - taosFprintfFile(pFile, "%s", TSDB_DATA_NULL_STR); return; } @@ -540,13 +539,34 @@ static void shellDumpFieldToFile(TdFilePtr pFile, const char* val, TAOS_FIELD* f case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_JSON: - memcpy(buf, val, length); - buf[length] = 0; - taosFprintfFile(pFile, "\'%s\'", buf); + { + char quotationStr[2]; + int32_t bufIndex = 0; + quotationStr[0] = 0; + quotationStr[1] = 0; + for (int32_t i = 0; i < length; i++) { + buf[bufIndex] = val[i]; + bufIndex++; + if (val[i] == '\"') { + buf[bufIndex] = val[i]; + bufIndex++; + quotationStr[0] = '\"'; + } + if (val[i] == ',') { + quotationStr[0] = '\"'; + } + } + buf[bufIndex] = 0; + if (length == 0) { + quotationStr[0] = '\"'; + } + + taosFprintfFile(pFile, "%s%s%s", quotationStr, buf, quotationStr); + } break; case TSDB_DATA_TYPE_TIMESTAMP: shellFormatTimestamp(buf, *(int64_t*)val, precision); - taosFprintfFile(pFile, "'%s'", buf); + taosFprintfFile(pFile, "%s", buf); break; default: break; diff --git a/tools/shell/src/shellEngine.c b/tools/shell/src/shellEngine.c index 3b760a097f..e54b98a0a6 100644 --- a/tools/shell/src/shellEngine.c +++ b/tools/shell/src/shellEngine.c @@ -266,7 +266,6 @@ char *shellFormatTimestamp(char *buf, int64_t val, int32_t precision) { void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, int32_t length, int32_t precision) { if (val == NULL) { - taosFprintfFile(pFile, "%s", TSDB_DATA_NULL_STR); return; } @@ -332,6 +331,10 @@ void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, i } } buf[bufIndex] = 0; + if (length == 0) { + quotationStr[0] = '\"'; + } + taosFprintfFile(pFile, "%s%s%s", quotationStr, buf, quotationStr); } break;