未验证 提交 5513e3a7 编写于 作者: S Shengliang Guan 提交者: GitHub

Merge pull request #2028 from taosdata/feature/td-407

TD-407: add config for binary column display width
...@@ -202,6 +202,8 @@ char tsTimezone[64] = {0}; ...@@ -202,6 +202,8 @@ char tsTimezone[64] = {0};
char tsLocale[TSDB_LOCALE_LEN] = {0}; char tsLocale[TSDB_LOCALE_LEN] = {0};
char tsCharset[TSDB_LOCALE_LEN] = {0}; // default encode string char tsCharset[TSDB_LOCALE_LEN] = {0}; // default encode string
int32_t tsMaxBinaryDisplayWidth = 30;
static pthread_once_t tsInitGlobalCfgOnce = PTHREAD_ONCE_INIT; static pthread_once_t tsInitGlobalCfgOnce = PTHREAD_ONCE_INIT;
void taosSetAllDebugFlag() { void taosSetAllDebugFlag() {
...@@ -1227,6 +1229,16 @@ static void doInitGlobalConfig() { ...@@ -1227,6 +1229,16 @@ static void doInitGlobalConfig() {
cfg.ptrLength = 0; cfg.ptrLength = 0;
cfg.unitType = TAOS_CFG_UTYPE_NONE; cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg); taosInitConfigOption(cfg);
cfg.option = "maxBinaryDisplayWidth";
cfg.ptr = &tsMaxBinaryDisplayWidth;
cfg.valType = TAOS_CFG_VTYPE_INT32;
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT;
cfg.minValue = 1;
cfg.maxValue = 0x7fffffff;
cfg.ptrLength = 0;
cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg);
} }
void taosInitGlobalCfg() { void taosInitGlobalCfg() {
......
...@@ -29,18 +29,6 @@ ...@@ -29,18 +29,6 @@
#define MAX_COMMAND_SIZE 65536 #define MAX_COMMAND_SIZE 65536
#define HISTORY_FILE ".taos_history" #define HISTORY_FILE ".taos_history"
#define BOOL_OUTPUT_LENGTH 6
#define TINYINT_OUTPUT_LENGTH 6
#define SMALLINT_OUTPUT_LENGTH 7
#define INT_OUTPUT_LENGTH 11
#define BIGINT_OUTPUT_LENGTH 21
#define FLOAT_OUTPUT_LENGTH 20
#define DOUBLE_OUTPUT_LENGTH 25
#define BINARY_OUTPUT_LENGTH 20
// dynamic config timestamp width according to maximum time precision
extern int32_t TIMESTAMP_OUTPUT_LENGTH;
typedef struct SShellHistory { typedef struct SShellHistory {
char* hist[MAX_HISTORY_SIZE]; char* hist[MAX_HISTORY_SIZE];
int hstart; int hstart;
...@@ -80,7 +68,7 @@ void get_history_path(char* history); ...@@ -80,7 +68,7 @@ void get_history_path(char* history);
void cleanup_handler(void* arg); void cleanup_handler(void* arg);
void exitShell(); void exitShell();
int shellDumpResult(TAOS* con, char* fname, int* error_no, bool printMode); int shellDumpResult(TAOS* con, char* fname, int* error_no, bool printMode);
void shellPrintNChar(char* str, int width, bool printMode); void shellPrintNChar(const char* str, int length, int width);
void shellGetGrantInfo(void *con); void shellGetGrantInfo(void *con);
int isCommentLine(char *line); int isCommentLine(char *line);
......
...@@ -352,37 +352,31 @@ void *shellLoopQuery(void *arg) { ...@@ -352,37 +352,31 @@ void *shellLoopQuery(void *arg) {
return NULL; return NULL;
} }
void shellPrintNChar(char *str, int width, bool printMode) { void shellPrintNChar(const char *str, int length, int width) {
int col_left = width; int pos = 0, cols = 0;
while (pos < length) {
wchar_t wc; wchar_t wc;
while (col_left > 0) { pos += mbtowc(&wc, str + pos, MB_CUR_MAX);
if (*str == '\0') break; if (pos > length) {
char *tstr = str; break;
int byte_width = mbtowc(&wc, tstr, MB_CUR_MAX);
if (byte_width <= 0) break;
int col_width = wcwidth(wc);
if (col_width <= 0) {
str += byte_width;
continue;
}
if (col_left < col_width) break;
printf("%lc", wc);
str += byte_width;
col_left -= col_width;
} }
while (col_left > 0) { int w = wcwidth(wc);
printf(" "); if (w > 0) {
col_left--; if (width > 0 && cols + w > width) {
break;
}
printf("%lc", wc);
cols += w;
}
} }
if (!printMode) { for (; cols < width; cols++) {
printf("|"); putchar(' ');
} else {
printf("\n");
} }
} }
int get_old_terminal_mode(struct termios *tio) { int get_old_terminal_mode(struct termios *tio) {
/* Make sure stdin is a terminal. */ /* Make sure stdin is a terminal. */
if (!isatty(STDIN_FILENO)) { if (!isatty(STDIN_FILENO)) {
......
...@@ -35,6 +35,9 @@ int prompt_size = 6; ...@@ -35,6 +35,9 @@ int prompt_size = 6;
TAOS_RES *result = NULL; TAOS_RES *result = NULL;
SShellHistory history; SShellHistory history;
#define DEFAULT_MAX_BINARY_DISPLAY_WIDTH 30
extern int32_t tsMaxBinaryDisplayWidth;
/* /*
* FUNCTION: Initialize the shell. * FUNCTION: Initialize the shell.
*/ */
...@@ -195,7 +198,15 @@ int32_t shellRunCommand(TAOS *con, char *command) { ...@@ -195,7 +198,15 @@ int32_t shellRunCommand(TAOS *con, char *command) {
} else if (regex_match(command, "^[\t ]*clear[ \t;]*$", REG_EXTENDED | REG_ICASE)) { } else if (regex_match(command, "^[\t ]*clear[ \t;]*$", REG_EXTENDED | REG_ICASE)) {
// If clear the screen. // If clear the screen.
system("clear"); system("clear");
return 0; } else if (regex_match(command, "^[\t ]*set[ \t]+max_binary_display_width[ \t]+(default|[1-9][0-9]*)[ \t;]*$", REG_EXTENDED | REG_ICASE)) {
strtok(command, " \t");
strtok(NULL, " \t");
char* p = strtok(NULL, " \t");
if (strcasecmp(p, "default") == 0) {
tsMaxBinaryDisplayWidth = DEFAULT_MAX_BINARY_DISPLAY_WIDTH;
} else {
tsMaxBinaryDisplayWidth = atoi(p);
}
} else if (regex_match(command, "^[ \t]*source[\t ]+[^ ]+[ \t;]*$", REG_EXTENDED | REG_ICASE)) { } else if (regex_match(command, "^[ \t]*source[\t ]+[^ ]+[ \t;]*$", REG_EXTENDED | REG_ICASE)) {
/* If source file. */ /* If source file. */
char *c_ptr = strtok(command, " ;"); char *c_ptr = strtok(command, " ;");
...@@ -310,360 +321,347 @@ int regex_match(const char *s, const char *reg, int cflags) { ...@@ -310,360 +321,347 @@ int regex_match(const char *s, const char *reg, int cflags) {
return 0; return 0;
} }
int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
TAOS_ROW row = NULL;
int numOfRows = 0;
time_t tt;
char buf[25] = "\0";
struct tm *ptm;
int output_bytes = 0;
FILE * fp = NULL;
int num_fields = taos_field_count(con);
wordexp_t full_path;
assert(num_fields != 0); static char* formatTimestamp(char* buf, int64_t val, int precision) {
if (args.is_raw_time) {
result = taos_use_result(con); sprintf(buf, "%" PRId64, val);
if (result == NULL) { return buf;
taos_error(con);
return -1;
} }
if (fname != NULL) { time_t tt;
if (wordexp(fname, &full_path, 0) != 0) { if (precision == TSDB_TIME_PRECISION_MICRO) {
fprintf(stderr, "ERROR: invalid file name: %s\n", fname); tt = (time_t)(val / 1000000);
return -1; } else {
tt = (time_t)(val / 1000);
} }
fp = fopen(full_path.we_wordv[0], "w"); struct tm* ptm = localtime(&tt);
if (fp == NULL) { size_t pos = strftime(buf, 32, "%Y-%m-%d %H:%M:%S", ptm);
fprintf(stderr, "ERROR: failed to open file: %s\n", full_path.we_wordv[0]);
wordfree(&full_path);
return -1;
}
wordfree(&full_path); if (precision == TSDB_TIME_PRECISION_MICRO) {
sprintf(buf + pos, ".%06d", (int)(val % 1000000));
} else {
sprintf(buf + pos, ".%03d", (int)(val % 1000));
} }
TAOS_FIELD *fields = taos_fetch_fields(result); return buf;
}
row = taos_fetch_row(result);
int32_t* length = taos_fetch_lengths(result);
char t_str[TSDB_MAX_BYTES_PER_ROW] = "\0"; static void dumpFieldToFile(FILE* fp, const char* val, TAOS_FIELD* field, int32_t length, int precision) {
int l[TSDB_MAX_COLUMNS] = {0}; if (val == NULL) {
int maxLenColumnName = 0; fprintf(fp, "%s", TSDB_DATA_NULL_STR);
return;
}
if (row) { char buf[TSDB_MAX_BYTES_PER_ROW];
// Print the header indicator switch (field->type) {
if (fname == NULL) { // print to standard output
if (!printMode) {
for (int col = 0; col < num_fields; col++) {
switch (fields[col].type) {
case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_BOOL:
l[col] = MAX(BOOL_OUTPUT_LENGTH, strlen(fields[col].name)); fprintf(fp, "%d", ((((int)(*((char *)val))) == 1) ? 1 : 0));
break; break;
case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_TINYINT:
l[col] = MAX(TINYINT_OUTPUT_LENGTH, strlen(fields[col].name)); fprintf(fp, "%d", (int)(*((char *)val)));
break; break;
case TSDB_DATA_TYPE_SMALLINT: case TSDB_DATA_TYPE_SMALLINT:
l[col] = MAX(SMALLINT_OUTPUT_LENGTH, strlen(fields[col].name)); fprintf(fp, "%d", (int)(*((short *)val)));
break; break;
case TSDB_DATA_TYPE_INT: case TSDB_DATA_TYPE_INT:
l[col] = MAX(INT_OUTPUT_LENGTH, strlen(fields[col].name)); fprintf(fp, "%d", *((int *)val));
break; break;
case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_BIGINT:
l[col] = MAX(BIGINT_OUTPUT_LENGTH, strlen(fields[col].name)); fprintf(fp, "%" PRId64, *((int64_t *)val));
break; break;
case TSDB_DATA_TYPE_FLOAT: case TSDB_DATA_TYPE_FLOAT:
l[col] = MAX(FLOAT_OUTPUT_LENGTH, strlen(fields[col].name)); fprintf(fp, "%.5f", GET_FLOAT_VAL(val));
break; break;
case TSDB_DATA_TYPE_DOUBLE: case TSDB_DATA_TYPE_DOUBLE:
l[col] = MAX(DOUBLE_OUTPUT_LENGTH, strlen(fields[col].name)); fprintf(fp, "%.9f", GET_DOUBLE_VAL(val));
break; break;
case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_NCHAR:
l[col] = MAX(fields[col].bytes, strlen(fields[col].name)); memcpy(buf, val, length);
/* l[col] = max(BINARY_OUTPUT_LENGTH, strlen(fields[col].name)); */ buf[length] = 0;
fprintf(fp, "\'%s\'", buf);
break; break;
case TSDB_DATA_TYPE_TIMESTAMP: { case TSDB_DATA_TYPE_TIMESTAMP:
int32_t defaultWidth = TIMESTAMP_OUTPUT_LENGTH; formatTimestamp(buf, *(int64_t*)val, precision);
if (args.is_raw_time) { fprintf(fp, "'%s'", buf);
defaultWidth = 14;
}
if (taos_result_precision(result) == TSDB_TIME_PRECISION_MICRO) {
defaultWidth += 3;
}
l[col] = MAX(defaultWidth, strlen(fields[col].name));
break; break;
}
default: default:
break; break;
} }
}
int spaces = (int)(l[col] - strlen(fields[col].name)); static int dumpResultToFile(const char* fname, TAOS_RES* result) {
int left_space = spaces / 2; TAOS_ROW row = taos_fetch_row(result);
int right_space = (spaces % 2 ? left_space + 1 : left_space); if (row == NULL) {
printf("%*.s%s%*.s|", left_space, " ", fields[col].name, right_space, " "); return 0;
output_bytes += (l[col] + 1);
} }
printf("\n");
for (int k = 0; k < output_bytes; k++) printf("="); wordexp_t full_path;
printf("\n");
} else { if (wordexp(fname, &full_path, 0) != 0) {
fprintf(stderr, "ERROR: invalid file name: %s\n", fname);
return -1;
}
FILE* fp = fopen(full_path.we_wordv[0], "w");
if (fp == NULL) {
fprintf(stderr, "ERROR: failed to open file: %s\n", full_path.we_wordv[0]);
wordfree(&full_path);
return -1;
}
wordfree(&full_path);
int num_fields = taos_num_fields(result);
TAOS_FIELD *fields = taos_fetch_fields(result);
int32_t* length = taos_fetch_lengths(result);
int precision = taos_result_precision(result);
for (int col = 0; col < num_fields; col++) { for (int col = 0; col < num_fields; col++) {
if (strlen(fields[col].name) > maxLenColumnName) maxLenColumnName = strlen(fields[col].name); if (col > 0) {
fprintf(fp, ",");
} }
fprintf(fp, "%s", fields[col].name);
} }
fputc('\n', fp);
// print the elements int numOfRows = 0;
do { do {
if (!printMode) {
for (int i = 0; i < num_fields; i++) { for (int i = 0; i < num_fields; i++) {
if (row[i] == NULL) { if (i > 0) {
printf("%*s|", l[i], TSDB_DATA_NULL_STR); fputc(',', fp);
continue;
} }
dumpFieldToFile(fp, row[i], fields +i, length[i], precision);
switch (fields[i].type) {
case TSDB_DATA_TYPE_BOOL:
printf("%*s|", l[i], ((((int)(*((char *)row[i]))) == 1) ? "true" : "false"));
break;
case TSDB_DATA_TYPE_TINYINT:
printf("%*d|", l[i], (int)(*((char *)row[i])));
break;
case TSDB_DATA_TYPE_SMALLINT:
printf("%*d|", l[i], (int)(*((short *)row[i])));
break;
case TSDB_DATA_TYPE_INT:
printf("%*d|", l[i], *((int *)row[i]));
break;
case TSDB_DATA_TYPE_BIGINT:
printf("%*" PRId64 "|", l[i], *((int64_t *)row[i]));
break;
case TSDB_DATA_TYPE_FLOAT: {
float fv = 0;
fv = GET_FLOAT_VAL(row[i]);
printf("%*.5f|", l[i], fv);
}
break;
case TSDB_DATA_TYPE_DOUBLE: {
double dv = 0;
dv = GET_DOUBLE_VAL(row[i]);
printf("%*.9f|", l[i], dv);
}
break;
case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR:
memset(t_str, 0, TSDB_MAX_BYTES_PER_ROW);
memcpy(t_str, row[i], length[i]);
/* printf("%-*s|",max(fields[i].bytes, strlen(fields[i].name)),
* t_str); */
/* printf("%-*s|", l[i], t_str); */
shellPrintNChar(t_str, l[i], printMode);
break;
case TSDB_DATA_TYPE_TIMESTAMP:
if (args.is_raw_time) {
printf(" %" PRId64 "|", *(int64_t *)row[i]);
} else {
if (taos_result_precision(result) == TSDB_TIME_PRECISION_MICRO) {
tt = (time_t)((*(int64_t *)row[i]) / 1000000);
} else {
tt = (time_t)((*(int64_t *)row[i]) / 1000);
} }
fputc('\n', fp);
ptm = localtime(&tt); numOfRows++;
strftime(buf, 64, "%y-%m-%d %H:%M:%S", ptm); row = taos_fetch_row(result);
} while( row != NULL);
if (taos_result_precision(result) == TSDB_TIME_PRECISION_MICRO) { fclose(fp);
printf(" %s.%06d|", buf, (int)(*(int64_t *)row[i] % 1000000)); return numOfRows;
} else { }
printf(" %s.%03d|", buf, (int)(*(int64_t *)row[i] % 1000));
}
} static void printField(const char* val, TAOS_FIELD* field, int width, int32_t length, int precision) {
break; if (val == NULL) {
default: int w = width;
break; if (field->type < TSDB_DATA_TYPE_TINYINT || field->type > TSDB_DATA_TYPE_DOUBLE) {
w = 0;
} }
w = printf("%*s", w, TSDB_DATA_NULL_STR);
for (; w < width; w++) {
putchar(' ');
} }
printf("\n"); return;
} else {
printf("*************************** %d.row ***************************\n", numOfRows + 1);
for (int i = 0; i < num_fields; i++) {
// 1. print column name
int left_space = (int)(maxLenColumnName - strlen(fields[i].name));
printf("%*.s%s: ", left_space, " ", fields[i].name);
// 2. print column value
if (row[i] == NULL) {
printf("%s\n", TSDB_DATA_NULL_STR);
continue;
} }
switch (fields[i].type) { char buf[TSDB_MAX_BYTES_PER_ROW];
switch (field->type) {
case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_BOOL:
printf("%s\n", ((((int)(*((char *)row[i]))) == 1) ? "true" : "false")); printf("%*s", width, ((((int)(*((char *)val))) == 1) ? "true" : "false"));
break; break;
case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_TINYINT:
printf("%d\n", (int)(*((char *)row[i]))); printf("%*d", width, (int)(*((char *)val)));
break; break;
case TSDB_DATA_TYPE_SMALLINT: case TSDB_DATA_TYPE_SMALLINT:
printf("%d\n", (int)(*((short *)row[i]))); printf("%*d", width, (int)(*((short *)val)));
break; break;
case TSDB_DATA_TYPE_INT: case TSDB_DATA_TYPE_INT:
printf("%d\n", *((int *)row[i])); printf("%*d", width, *((int *)val));
break; break;
case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_BIGINT:
printf("%" PRId64 "\n", *((int64_t *)row[i])); printf("%*" PRId64, width, *((int64_t *)val));
break; break;
case TSDB_DATA_TYPE_FLOAT: { case TSDB_DATA_TYPE_FLOAT:
float fv = 0; printf("%*.5f", width, GET_FLOAT_VAL(val));
fv = GET_FLOAT_VAL(row[i]);
printf("%.5f\n", fv);
}
break; break;
case TSDB_DATA_TYPE_DOUBLE: { case TSDB_DATA_TYPE_DOUBLE:
double dv = 0; printf("%*.9f", width, GET_DOUBLE_VAL(val));
dv = GET_DOUBLE_VAL(row[i]);
printf("%.9f\n", dv);
}
break; break;
case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_NCHAR:
memset(t_str, 0, TSDB_MAX_BYTES_PER_ROW); shellPrintNChar(val, length, width);
memcpy(t_str, row[i], length[i]);
l[i] = MAX(fields[i].bytes, strlen(fields[i].name));
shellPrintNChar(t_str, l[i], printMode);
break; break;
case TSDB_DATA_TYPE_TIMESTAMP: case TSDB_DATA_TYPE_TIMESTAMP:
if (args.is_raw_time) { formatTimestamp(buf, *(int64_t*)val, precision);
printf("%" PRId64 "\n", *(int64_t *)row[i]); printf("%s", buf);
} else {
if (taos_result_precision(result) == TSDB_TIME_PRECISION_MICRO) {
tt = (time_t)((*(int64_t *)row[i]) / 1000000);
} else {
tt = (time_t)((*(int64_t *)row[i]) / 1000);
}
ptm = localtime(&tt);
strftime(buf, 64, "%y-%m-%d %H:%M:%S", ptm);
if (taos_result_precision(result) == TSDB_TIME_PRECISION_MICRO) {
printf("%s.%06d\n", buf, (int)(*(int64_t *)row[i] % 1000000));
} else {
printf("%s.%03d\n", buf, (int)(*(int64_t *)row[i] % 1000));
}
}
break; break;
default: default:
break; break;
} }
} }
static int verticalPrintResult(TAOS_RES* result) {
TAOS_ROW row = taos_fetch_row(result);
if (row == NULL) {
return 0;
} }
numOfRows++; int num_fields = taos_num_fields(result);
} while ((row = taos_fetch_row(result))); TAOS_FIELD *fields = taos_fetch_fields(result);
int32_t* length = taos_fetch_lengths(result);
int precision = taos_result_precision(result);
} else { // dump to file int maxColNameLen = 0;
// first write column
for (int col = 0; col < num_fields; col++) { for (int col = 0; col < num_fields; col++) {
fprintf(fp, "%s", fields[col].name); int len = strlen(fields[col].name);
if (col < num_fields - 1) { if (len > maxColNameLen) {
fprintf(fp, ","); maxColNameLen = len;
} else {
fprintf(fp, "\n");
} }
} }
int numOfRows = 0;
do { do {
printf("*************************** %d.row ***************************\n", numOfRows + 1);
for (int i = 0; i < num_fields; i++) { for (int i = 0; i < num_fields; i++) {
if (row[i]) { TAOS_FIELD* field = fields + i;
switch (fields[i].type) {
int padding = (int)(maxColNameLen - strlen(field->name));
printf("%*.s%s: ", padding, " ", field->name);
printField(row[i], field, 0, length[i], precision);
putchar('\n');
}
numOfRows++;
row = taos_fetch_row(result);
} while(row != NULL);
return numOfRows;
}
static int calcColWidth(TAOS_FIELD* field, int precision) {
int width = strlen(field->name);
switch (field->type) {
case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_BOOL:
fprintf(fp, "%d", ((((int)(*((char *)row[i]))) == 1) ? 1 : 0)); return MAX(5, width); // 'false'
break;
case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_TINYINT:
fprintf(fp, "%d", (int)(*((char *)row[i]))); return MAX(4, width); // '-127'
break;
case TSDB_DATA_TYPE_SMALLINT: case TSDB_DATA_TYPE_SMALLINT:
fprintf(fp, "%d", (int)(*((short *)row[i]))); return MAX(6, width); // '-32767'
break;
case TSDB_DATA_TYPE_INT: case TSDB_DATA_TYPE_INT:
fprintf(fp, "%d", *((int *)row[i])); return MAX(11, width); // '-2147483648'
break;
case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_BIGINT:
fprintf(fp, "%" PRId64, *((int64_t *)row[i])); return MAX(21, width); // '-9223372036854775807'
break;
case TSDB_DATA_TYPE_FLOAT: { case TSDB_DATA_TYPE_FLOAT:
float fv = 0; return MAX(20, width);
fv = GET_FLOAT_VAL(row[i]);
fprintf(fp, "%.5f", fv); case TSDB_DATA_TYPE_DOUBLE:
} return MAX(25, width);
break;
case TSDB_DATA_TYPE_DOUBLE: {
double dv = 0;
dv = GET_DOUBLE_VAL(row[i]);
fprintf(fp, "%.9f", dv);
}
break;
case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_NCHAR:
memset(t_str, 0, TSDB_MAX_BYTES_PER_ROW); if (field->bytes > tsMaxBinaryDisplayWidth) {
memcpy(t_str, row[i], length[i]); return MAX(tsMaxBinaryDisplayWidth, width);
fprintf(fp, "\'%s\'", t_str);
break;
case TSDB_DATA_TYPE_TIMESTAMP:
if (args.is_raw_time) {
fprintf(fp, "%" PRId64, *(int64_t *)row[i]);
} else {
if (taos_result_precision(result) == TSDB_TIME_PRECISION_MICRO) {
tt = (time_t)((*(int64_t *)row[i]) / 1000000);
} else { } else {
tt = (time_t)((*(int64_t *)row[i]) / 1000); return MAX(field->bytes, width);
} }
ptm = localtime(&tt); case TSDB_DATA_TYPE_TIMESTAMP:
strftime(buf, 64, "%Y-%m-%d %H:%M:%S", ptm); if (args.is_raw_time) {
return MAX(14, width);
if (taos_result_precision(result) == TSDB_TIME_PRECISION_MICRO) { } else if (precision == TSDB_TIME_PRECISION_MICRO) {
fprintf(fp, "\'%s.%06d\'", buf, (int)(*(int64_t *)row[i] % 1000000)); return MAX(26, width); // '2020-01-01 00:00:00.000000'
} else { } else {
fprintf(fp, "\'%s.%03d\'", buf, (int)(*(int64_t *)row[i] % 1000)); return MAX(23, width); // '2020-01-01 00:00:00.000'
}
} }
break;
default: default:
break; assert(false);
} }
} else {
fprintf(fp, "%s", TSDB_DATA_NULL_STR); return 0;
}
static void printHeader(TAOS_FIELD* fields, int* width, int num_fields) {
int rowWidth = 0;
for (int col = 0; col < num_fields; col++) {
TAOS_FIELD* field = fields + col;
int padding = (int)(width[col] - strlen(field->name));
int left = padding / 2;
printf(" %*.s%s%*.s |", left, " ", field->name, padding - left, " ");
rowWidth += width[col] + 3;
} }
if (i < num_fields - 1) {
fprintf(fp, ","); putchar('\n');
} else { for (int i = 0; i < rowWidth; i++) {
fprintf(fp, "\n"); putchar('=');
} }
putchar('\n');
}
static int horizontalPrintResult(TAOS_RES* result) {
TAOS_ROW row = taos_fetch_row(result);
if (row == NULL) {
return 0;
} }
numOfRows++; int num_fields = taos_num_fields(result);
} while ((row = taos_fetch_row(result))); TAOS_FIELD *fields = taos_fetch_fields(result);
int32_t* length = taos_fetch_lengths(result);
int precision = taos_result_precision(result);
int width[TSDB_MAX_COLUMNS];
for (int col = 0; col < num_fields; col++) {
width[col] = calcColWidth(fields + col, precision);
} }
printHeader(fields, width, num_fields);
int numOfRows = 0;
do {
for (int i = 0; i < num_fields; i++) {
putchar(' ');
printField(row[i], fields + i, width[i], length[i], precision);
putchar(' ');
putchar('|');
} }
putchar('\n');
numOfRows++;
row = taos_fetch_row(result);
} while(row != NULL);
*error_no = taos_errno(con); return numOfRows;
}
taos_free_result(result);
result = NULL; int shellDumpResult(TAOS *con, char *fname, int *error_no, bool vertical) {
int numOfRows = 0;
TAOS_RES* result = taos_use_result(con);
if (result == NULL) {
taos_error(con);
return -1;
}
if (fname != NULL) { if (fname != NULL) {
fclose(fp); numOfRows = dumpResultToFile(fname, result);
} else if(vertical) {
numOfRows = verticalPrintResult(result);
} else {
numOfRows = horizontalPrintResult(result);
} }
*error_no = taos_errno(con);
taos_free_result(result);
return numOfRows; return numOfRows;
} }
void read_history() { void read_history() {
// Initialize history // Initialize history
memset(history.hist, 0, sizeof(char *) * MAX_HISTORY_SIZE); memset(history.hist, 0, sizeof(char *) * MAX_HISTORY_SIZE);
......
...@@ -329,34 +329,27 @@ void *shellLoopQuery(void *arg) { ...@@ -329,34 +329,27 @@ void *shellLoopQuery(void *arg) {
return NULL; return NULL;
} }
void shellPrintNChar(char *str, int width, bool printMode) { void shellPrintNChar(const char *str, int length, int width) {
int col_left = width; int pos = 0, cols = 0;
while (pos < length) {
wchar_t wc; wchar_t wc;
while (col_left > 0) { pos += mbtowc(&wc, str + pos, MB_CUR_MAX);
if (*str == '\0') break; if (pos > length) {
char *tstr = str; break;
int byte_width = mbtowc(&wc, tstr, MB_CUR_MAX);
if (byte_width <= 0) break;
int col_width = wcwidth(wc);
if (col_width <= 0) {
str += byte_width;
continue;
}
if (col_left < col_width) break;
printf("%lc", wc);
str += byte_width;
col_left -= col_width;
} }
while (col_left > 0) { int w = wcwidth(wc);
printf(" "); if (w > 0) {
col_left--; if (width > 0 && cols + w > width) {
break;
}
printf("%lc", wc);
cols += w;
}
} }
if (!printMode) { for (; cols < width; cols++) {
printf("|"); putchar(' ');
} else {
printf("\n");
} }
} }
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
TAOS* con; TAOS* con;
pthread_t pid; pthread_t pid;
int32_t TIMESTAMP_OUTPUT_LENGTH = 22;
// TODO: IMPLEMENT INTERRUPT HANDLER. // TODO: IMPLEMENT INTERRUPT HANDLER.
void interruptHandler(int signum) { void interruptHandler(int signum) {
......
...@@ -217,32 +217,32 @@ void *shellLoopQuery(void *arg) { ...@@ -217,32 +217,32 @@ void *shellLoopQuery(void *arg) {
return NULL; return NULL;
} }
void shellPrintNChar(char *str, int width, bool printMode) { void shellPrintNChar(const char *str, int length, int width) {
int col_left = width; int pos = 0, cols = 0;
while (pos < length) {
wchar_t wc; wchar_t wc;
while (col_left > 0) { int bytes = mbtowc(&wc, str + pos, MB_CUR_MAX);
if (*str == '\0') break; pos += bytes;
char *tstr = str; if (pos > length) {
int byte_width = mbtowc(&wc, tstr, MB_CUR_MAX); break;
int col_width = byte_width;
if (col_left < col_width) break;
printf("%lc", wc);
str += byte_width;
col_left -= col_width;
} }
while (col_left > 0) { int w = bytes;
printf(" "); if (w > 0) {
col_left--; if (width > 0 && cols + w > width) {
break;
}
printf("%lc", wc);
cols += w;
}
} }
if (!printMode) { for (; cols < width; cols++) {
printf("|"); putchar(' ');
} else {
printf("\n");
} }
} }
void get_history_path(char *history) { sprintf(history, "%s/%s", ".", HISTORY_FILE); } void get_history_path(char *history) { sprintf(history, "%s/%s", ".", HISTORY_FILE); }
void exitShell() { exit(EXIT_SUCCESS); } void exitShell() { exit(EXIT_SUCCESS); }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册