• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / taos-tools / 13135713772

04 Feb 2025 12:42PM UTC coverage: 75.074% (-0.03%) from 75.104%
13135713772

Pull #843

github

web-flow
Merge 7e4333581 into 85e3589c2
Pull Request #843: taos-tools Merge 3.0 to Main Branch

433 of 593 new or added lines in 6 files covered. (73.02%)

41 existing lines in 6 files now uncovered.

12457 of 16593 relevant lines covered (75.07%)

327996.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.31
/src/benchJsonOpt.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the MIT license as published by the Free Software
6
 * Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 */
12

13
#include <stdlib.h>
14
#include <sys/stat.h>
15
#include <bench.h>
16
#include "benchLog.h"
17

18
extern char      g_configDir[MAX_PATH_LEN];
19

20
char funsName [FUNTYPE_CNT] [32] = {
21
    "sin(",
22
    "cos(",
23
    "count(",
24
    "saw(",
25
    "square(",
26
    "tri(",
27
};
28

29
int32_t parseFunArgs(char* value, uint8_t funType, int64_t* min ,int64_t* max, int32_t* step ,int32_t* period ,int32_t* offset) {
×
30
    char* buf = strdup(value);
×
31
    char* p[4] = {NULL};
×
32
    int32_t i = 0; 
×
33
    // find ")" fun end brance
34
    char* end = strstr(buf,")");
×
35
    if(end) {
×
36
        *end = 0;
×
37
    }
38
    int32_t argsLen = strlen(buf) + 1;
×
39

40
    // find first
41
    char* token = strtok(buf, ",");
×
42
    if(token == NULL) {
×
43
        free(buf);
×
44
        return 0;
×
45
    }
46
    p[i++] = token; 
×
47

48
    // find others
49
    while((token = strtok(NULL, ",")) && i < 4) {
×
50
        p[i++] = token; 
×
51
    }
52

53
    if(i != 4) {
×
54
        // must 4 params
55
        free(buf);
×
56
        return 0;
×
57
    }
58

59
    // parse fun
60
    if(funType == FUNTYPE_COUNT) {
×
61
        *min    = atoi(p[0]);
×
62
        *max    = atoi(p[1]);
×
63
        *step   = atoi(p[2]);
×
64
        *offset = atoi(p[3]);
×
65
    } else {
66
        *min    = atoi(p[0]);
×
67
        *max    = atoi(p[1]);
×
68
        *period = atoi(p[2]);
×
69
        *offset = atoi(p[3]);
×
70
    }
71

72
    free(buf);
×
73
    return argsLen;
×
74
}
75

76
uint8_t parseFuns(char* expr, float* multiple, float* addend, float* base, int32_t* random, 
×
77
            int64_t* min ,int64_t* max, int32_t* step ,int32_t* period ,int32_t* offset) {
78
    // check valid
79
    if (expr == NULL || multiple == NULL || addend == NULL || base == NULL) {
×
80
        return FUNTYPE_NONE;
×
81
    }
82

83
    size_t len = strlen(expr); 
×
84
    if(len > 100) {
×
85
        return FUNTYPE_NONE;
×
86
    }
87

88
    //parse format 10*sin(x) + 100 * random(5)
89
    char value[128];
90
    size_t n = 0;
×
91
    // remove blank
92
    for (size_t i = 0; i < len; i++) {
×
93
        if (expr[i] != ' ') {
×
94
            value[n++] = expr[i];
×
95
        }
96
    }
97
    // set end
98
    value[n] = 0;
×
99

100
    // multiple
101
    char* key1 = strstr(value, "*");
×
102
    if(key1) {
×
103
        // excpet tri(-20,40,20,5)+20+50*random(12)
104
        bool found = true;
×
105
        char* p1 = strstr(value+1, "+");
×
106
        char* p2 = strstr(value+1, "-");
×
107
        if(p1 && key1 > p1 ) 
×
108
           found = false;
×
109
        if(p2 && key1 > p2 ) 
×
110
           found = false;
×
111

112
        if(found) {
×
113
            *key1 = 0;
×
114
            *multiple = atof(value);
×
115
            key1 += 1;
×
116
        } else {
117
            key1 = value;
×
118
        }
119
    } else {
120
        key1 = value;
×
121
    }
122

123
    // funType
124
    uint8_t funType = FUNTYPE_NONE;
×
125
    char* key2 = NULL;
×
126
    for (int i = 0; i < FUNTYPE_CNT - 1; i++) {
×
127
        key2 = strstr(key1, funsName[i]);
×
128
        if(key2) {
×
129
            funType = i + 1;
×
130
            key2 += strlen(funsName[i]);
×
131
            int32_t argsLen = parseFunArgs(key2, funType, min, max, step, period, offset);
×
132
            if(len <= 0){
×
133
                return FUNTYPE_NONE;
×
134
            }
135
            key2 += argsLen;
×
136

137
            break;
×
138
        }
139
    }
140
    if (key2 == NULL)
×
141
        return FUNTYPE_NONE;
×
142

143
    char* key3 = strstr(key2, "+");
×
144
    if(key3) {
×
145
        *addend = atof(key3 + 1);
×
146
        key3 += 1;
×
147
    } else {
148
        key3 = strstr(key2, "-");
×
149
        if(key3) {
×
150
           *addend = atof(key3 + 1) * -1;
×
151
           key3 += 1;
×
152
        }
153
    }
154
    
155

156
    // random
157
    if(key3) {
×
158
        char* key4 = strstr(key3, "*random(");
×
159
        if(key4) {
×
160
            *random = atoi(key4 + 8);
×
161
            key3 += 9;
×
162
        }
163
    }
164

165
    // base
166
    if(key3) {
×
167
        char* key5 = strstr(key3, "+");
×
168
        if(key5){
×
169
            *base = atof(key5+1);
×
170
        } else {
171
            key5 = strstr(key3, "-");
×
172
            if(key5)
×
173
              *base = atof(key5+1) * -1;
×
174
        }
175
    }
176

177
    return funType;
×
178
}
179

180
static int getColumnAndTagTypeFromInsertJsonFile(
151✔
181
    tools_cJSON * superTblObj, SSuperTable *stbInfo) {
182
    int32_t code = -1;
151✔
183

184
    // columns
185
    tools_cJSON *columnsObj =
186
        tools_cJSON_GetObjectItem(superTblObj, "columns");
151✔
187
    if (!tools_cJSON_IsArray(columnsObj)) {
151✔
188
        goto PARSE_OVER;
×
189
    }
190
    benchArrayClear(stbInfo->cols);
151✔
191

192
    int columnSize = tools_cJSON_GetArraySize(columnsObj);
151✔
193

194
    int index = 0;
151✔
195
    for (int k = 0; k < columnSize; ++k) {
763✔
196
        bool sma = false;
612✔
197
        bool customName = false;
612✔
198
        uint8_t type = 0;
612✔
199
        int count = 1;
612✔
200
        int64_t max = RAND_MAX >> 1;
612✔
201
        int64_t min = 0;
612✔
202
        double  maxInDbl = max;
612✔
203
        double  minInDbl = min;
612✔
204
        uint32_t scalingFactor = 1;
612✔
205
        int32_t length = 4;
612✔
206
        // fun type
207
        uint8_t funType = FUNTYPE_NONE;
612✔
208
        float   multiple = 0;
612✔
209
        float   addend   = 0;
612✔
210
        float   base     = 0;
612✔
211
        int32_t random   = 0;
612✔
212
        int32_t step     = 0;
612✔
213
        int32_t period   = 0;
612✔
214
        int32_t offset   = 0;
612✔
215
        uint8_t gen      = GEN_RANDOM;
612✔
216
        bool    fillNull = true;
612✔
217
        char*   encode   = NULL;
612✔
218
        char*   compress = NULL;
612✔
219
        char*   level    = NULL;
612✔
220

221
        tools_cJSON *column = tools_cJSON_GetArrayItem(columnsObj, k);
612✔
222
        if (!tools_cJSON_IsObject(column)) {
612✔
223
            errorPrint("%s", "Invalid column format in json\n");
×
224
            goto PARSE_OVER;
×
225
        }
226
        tools_cJSON *countObj = tools_cJSON_GetObjectItem(column, "count");
612✔
227
        if (tools_cJSON_IsNumber(countObj)) {
612✔
228
            count = (int)countObj->valueint;
127✔
229
        } else {
230
            count = 1;
485✔
231
        }
232

233
        tools_cJSON *dataName = tools_cJSON_GetObjectItem(column, "name");
612✔
234
        if (tools_cJSON_IsString(dataName)) {
612✔
235
            customName = true;
154✔
236
        }
237

238
        // column info
239
        tools_cJSON *dataType = tools_cJSON_GetObjectItem(column, "type");
612✔
240
        if (!tools_cJSON_IsString(dataType)) {
612✔
241
            goto PARSE_OVER;
×
242
        }
243
        type = convertStringToDatatype(dataType->valuestring, 0);
612✔
244

245
        tools_cJSON *dataMax = tools_cJSON_GetObjectItem(column, "max");
612✔
246
        if (tools_cJSON_IsNumber(dataMax)) {
612✔
247
            max = dataMax->valueint;
152✔
248
            maxInDbl = dataMax->valuedouble;
152✔
249
        } else {
250
            max = convertDatatypeToDefaultMax(type);
460✔
251
            maxInDbl = max;
460✔
252
        }
253

254
        tools_cJSON *dataMin = tools_cJSON_GetObjectItem(column, "min");
612✔
255
        if (tools_cJSON_IsNumber(dataMin)) {
612✔
256
            min = dataMin->valueint;
159✔
257
            minInDbl = dataMin->valuedouble;
159✔
258
        } else {
259
            min = convertDatatypeToDefaultMin(type);
453✔
260
            minInDbl = min;
453✔
261
        }
262

263
        if (type == TSDB_DATA_TYPE_FLOAT || type == TSDB_DATA_TYPE_DOUBLE) {
612✔
264
            double valueRange = maxInDbl - minInDbl;
119✔
265
            tools_cJSON *dataScalingFactor = tools_cJSON_GetObjectItem(column, "scalingFactor");
119✔
266
            if (tools_cJSON_IsNumber(dataScalingFactor)) {
119✔
NEW
267
                scalingFactor = dataScalingFactor->valueint;
×
NEW
268
                if (1< scalingFactor && scalingFactor <= 1000000) {
×
NEW
269
                    max = maxInDbl * scalingFactor;
×
NEW
270
                    min = minInDbl * scalingFactor;
×
271
                } else {
NEW
272
                    scalingFactor = 1;
×
273
                }
274
            } else {
275
                if (0 < valueRange && valueRange <= 1) {
119✔
276
                    scalingFactor = 1000;
16✔
277
                    max = maxInDbl * scalingFactor;
16✔
278
                    min = minInDbl * scalingFactor;
16✔
279
                } else {
280
                    scalingFactor = 1;
103✔
281
                }
282
            }
283
        }
284

285
        // gen
286
        tools_cJSON *dataGen = tools_cJSON_GetObjectItem(column, "gen");
612✔
287
        if (tools_cJSON_IsString(dataGen)) {
612✔
288
            if (strcasecmp(dataGen->valuestring, "order") == 0) {
23✔
289
                gen = GEN_ORDER;
23✔
290
            }
291
        }
292
        // fillNull
293
        tools_cJSON *dataNull = tools_cJSON_GetObjectItem(column, "fillNull");
612✔
294
        if (tools_cJSON_IsString(dataNull)) {
612✔
295
            if (strcasecmp(dataNull->valuestring, "false") == 0) {
6✔
296
                fillNull = false;
6✔
297
            }
298
        }
299

300
        // encode
301
        tools_cJSON *dataEncode = tools_cJSON_GetObjectItem(column, "encode");
612✔
302
        if (tools_cJSON_IsString(dataEncode)) {
612✔
303
            encode = dataEncode->valuestring;
×
304
        }
305
        // compress
306
        tools_cJSON *dataCompress = tools_cJSON_GetObjectItem(column, "compress");
612✔
307
        if (tools_cJSON_IsString(dataCompress)) {
612✔
308
            compress = dataCompress->valuestring;
×
309
        }
310
        // level
311
        tools_cJSON *dataLevel = tools_cJSON_GetObjectItem(column, "level");
612✔
312
        if (tools_cJSON_IsString(dataLevel)) {
612✔
313
            level = dataLevel->valuestring;
×
314
        }
315

316
        // fun
317
        tools_cJSON *fun = tools_cJSON_GetObjectItem(column, "fun");
612✔
318
        if (tools_cJSON_IsString(fun)) {
612✔
319
            funType = parseFuns(fun->valuestring, &multiple, &addend, &base, &random, &min, &max, &step, &period, &offset);
×
320
        }
321

322
        tools_cJSON *dataValues = tools_cJSON_GetObjectItem(column, "values");
612✔
323

324
        if (g_arguments->taosc_version == 3) {
612✔
325
            tools_cJSON *sma_value = tools_cJSON_GetObjectItem(column, "sma");
612✔
326
            if (tools_cJSON_IsString(sma_value) &&
612✔
327
                (0 == strcasecmp(sma_value->valuestring, "yes"))) {
×
328
                sma = true;
×
329
            }
330
        }
331

332
        tools_cJSON * dataLen = tools_cJSON_GetObjectItem(column, "len");
612✔
333
        if (tools_cJSON_IsNumber(dataLen)) {
612✔
334
            length = (int32_t)dataLen->valueint;
116✔
335
        } else {
336
            if (type == TSDB_DATA_TYPE_BINARY
496✔
337
                || type == TSDB_DATA_TYPE_JSON
494✔
338
                || type == TSDB_DATA_TYPE_NCHAR
494✔
339
                || type == TSDB_DATA_TYPE_GEOMETRY) {
492✔
340
                length = g_arguments->binwidth;
4✔
341
            } else {
342
                length = convertTypeToLength(type);
492✔
343
            }
344
        }
345

346
        for (int n = 0; n < count; ++n) {
1,438✔
347
            Field * col = benchCalloc(1, sizeof(Field), true);
826✔
348
            benchArrayPush(stbInfo->cols, col);
826✔
349
            col = benchArrayGet(stbInfo->cols, stbInfo->cols->size - 1);
826✔
350
            col->type = type;
826✔
351
            col->length = length;
826✔
352
            if (length == 0) {
826✔
353
                col->null = true;
2✔
354
            }
355
            col->sma = sma;
826✔
356
            col->max = max;
826✔
357
            col->min = min;
826✔
358
            col->maxInDbl = maxInDbl;
826✔
359
            col->minInDbl = minInDbl;
826✔
360
            col->scalingFactor = scalingFactor;
826✔
361
            col->gen = gen;
826✔
362
            col->fillNull = fillNull;
826✔
363
            col->values = dataValues;
826✔
364
            // fun
365
            col->funType  = funType;
826✔
366
            col->multiple = multiple;
826✔
367
            col->addend   = addend;
826✔
368
            col->base     = base;
826✔
369
            col->random   = random;
826✔
370
            col->step     = step;
826✔
371
            col->period   = period;
826✔
372
            col->offset   = offset;
826✔
373

374
            if (customName) {
826✔
375
                if (n >= 1) {
160✔
376
                    snprintf(col->name, TSDB_COL_NAME_LEN,
6✔
377
                             "%s_%d", dataName->valuestring, n);
378
                } else {
379
                    snprintf(col->name, TSDB_COL_NAME_LEN,
154✔
380
                            "%s", dataName->valuestring);
381
                }
382
            } else {
383
                snprintf(col->name, TSDB_COL_NAME_LEN, "c%d", index);
666✔
384
            }
385

386
            // encode
387
            if(encode) {
826✔
388
                if (strlen(encode) < COMP_NAME_LEN) {
×
389
                    strcpy(col->encode, encode);
×
390
                } else {
391
                    errorPrint("encode name length over (%d) bytes, ignore. name=%s", COMP_NAME_LEN, encode);
×
392
                }
393
            }
394
            // compress
395
            if(compress) {
826✔
396
                if (strlen(compress) < COMP_NAME_LEN) {
×
397
                    strcpy(col->compress, compress);
×
398
                } else {
399
                    errorPrint("compress name length over (%d) bytes, ignore. name=%s", COMP_NAME_LEN, compress);
×
400
                }
401
            }
402
            // level
403
            if(level) {
826✔
404
                if (strlen(level) < COMP_NAME_LEN) {
×
405
                    strcpy(col->level, level);
×
406
                } else {
407
                    errorPrint("level name length over (%d) bytes, ignore. name=%s", COMP_NAME_LEN, level);
×
408
                }
409
            }
410

411
            index++;
826✔
412
        }
413
    }
414

415
    index = 0;
151✔
416
    // tags
417
    benchArrayClear(stbInfo->tags);
151✔
418
    tools_cJSON *tags = tools_cJSON_GetObjectItem(superTblObj, "tags");
151✔
419
    if (!tools_cJSON_IsArray(tags)) {
151✔
420
        return 0;
×
421
    }
422

423
    int tagSize = tools_cJSON_GetArraySize(tags);
151✔
424

425
    stbInfo->use_metric = true;
151✔
426
    for (int k = 0; k < tagSize; ++k) {
1,075✔
427
        bool customName = false;
925✔
428
        uint8_t type = 0;
925✔
429
        int count = 1;
925✔
430
        int64_t max = RAND_MAX >> 1;
925✔
431
        int64_t min = 0;
925✔
432
        double  maxInDbl = max;
925✔
433
        double  minInDbl = min;
925✔
434
        uint32_t scalingFactor = 1;
925✔
435
        int32_t length = 4;
925✔
436
        tools_cJSON *tagObj = tools_cJSON_GetArrayItem(tags, k);
925✔
437
        if (!tools_cJSON_IsObject(tagObj)) {
925✔
438
            errorPrint("%s", "Invalid tag format in json\n");
×
439
            goto PARSE_OVER;
×
440
        }
441
        tools_cJSON *countObj = tools_cJSON_GetObjectItem(tagObj, "count");
925✔
442
        if (tools_cJSON_IsNumber(countObj)) {
925✔
443
            count = (int)countObj->valueint;
189✔
444
        } else {
445
            count = 1;
736✔
446
        }
447

448
        tools_cJSON *dataName = tools_cJSON_GetObjectItem(tagObj, "name");
925✔
449
        if (tools_cJSON_IsString(dataName)) {
925✔
450
            customName = true;
62✔
451
        }
452

453
        tools_cJSON *dataType = tools_cJSON_GetObjectItem(tagObj, "type");
925✔
454
        if (!tools_cJSON_IsString(dataType)) {
925✔
455
            goto PARSE_OVER;
×
456
        }
457
        type = convertStringToDatatype(dataType->valuestring, 0);
925✔
458

459
        if(type == TSDB_DATA_TYPE_JSON) {
925✔
460
            if (tagSize > 1) {
1✔
461
                // if tag type is json, must one tag column
462
                errorPrint("tag datatype is json, only one column tag is allowed, currently tags columns count is %d. quit programe.\n", tagSize);
×
463
                code = -1;
×
464
                goto PARSE_OVER;
×
465
            }
466

467
            // create on stbInfo->tags
468
            Field * tag = benchCalloc(1, sizeof(Field), true);
1✔
469
            benchArrayPush(stbInfo->tags, tag);
1✔
470
            tag = benchArrayGet(stbInfo->tags, stbInfo->tags->size - 1);
1✔
471
            if (customName) {
1✔
472
                snprintf(tag->name, TSDB_COL_NAME_LEN,
×
473
                         "%s", dataName->valuestring);
474
            } else {
475
                snprintf(tag->name, TSDB_COL_NAME_LEN, "jtag");
1✔
476
            }
477
            tag->type = type;
1✔
478
            tag->length = JSON_FIXED_LENGTH; // json datatype is fixed length: 4096
1✔
479
            return 0;
1✔
480
        }
481

482
        tools_cJSON *dataMax = tools_cJSON_GetObjectItem(tagObj, "max");
924✔
483
        if (tools_cJSON_IsNumber(dataMax)) {
924✔
484
            max = dataMax->valueint;
113✔
485
            maxInDbl = dataMax->valuedouble;
113✔
486
        } else {
487
            max = convertDatatypeToDefaultMax(type);
811✔
488
            maxInDbl = max;
811✔
489
        }
490

491
        tools_cJSON *dataMin = tools_cJSON_GetObjectItem(tagObj, "min");
924✔
492
        if (tools_cJSON_IsNumber(dataMin)) {
924✔
493
            min = dataMin->valueint;
113✔
494
            minInDbl = dataMin->valuedouble;
113✔
495
        } else {
496
            min = convertDatatypeToDefaultMin(type);
811✔
497
            minInDbl = min;
811✔
498
        }
499

500

501
        if (type == TSDB_DATA_TYPE_FLOAT || type == TSDB_DATA_TYPE_DOUBLE) {
924✔
502
            double valueRange = maxInDbl - minInDbl;
141✔
503
            tools_cJSON *dataScalingFactor = tools_cJSON_GetObjectItem(tagObj, "scalingFactor");
141✔
504
            if (tools_cJSON_IsNumber(dataScalingFactor)) {
141✔
NEW
505
                scalingFactor = dataScalingFactor->valueint;
×
NEW
506
                if (1< scalingFactor && scalingFactor <= 1000000) {
×
NEW
507
                    max = maxInDbl * scalingFactor;
×
NEW
508
                    min = minInDbl * scalingFactor;
×
509
                } else {
NEW
510
                    scalingFactor = 1;
×
511
                }
512
            } else {
513
                if (0 < valueRange && valueRange <= 1) {
141✔
NEW
514
                    scalingFactor = 1000;
×
NEW
515
                    max = maxInDbl * scalingFactor;
×
NEW
516
                    min = minInDbl * scalingFactor;
×
517
                } else {
518
                    scalingFactor = 1;
141✔
519
                }
520
            }
521
        }
522

523
        tools_cJSON *dataValues = tools_cJSON_GetObjectItem(tagObj, "values");
924✔
524

525
        tools_cJSON * dataLen = tools_cJSON_GetObjectItem(tagObj, "len");
924✔
526
        if (tools_cJSON_IsNumber(dataLen)) {
924✔
527
            length = (int32_t)dataLen->valueint;
175✔
528
        } else {
529
            if (type == TSDB_DATA_TYPE_BINARY
749✔
530
                || type == TSDB_DATA_TYPE_JSON
732✔
531
                || type == TSDB_DATA_TYPE_VARBINARY
732✔
532
                || type == TSDB_DATA_TYPE_GEOMETRY
732✔
533
                || type == TSDB_DATA_TYPE_NCHAR) {
732✔
534
                length = g_arguments->binwidth;
19✔
535
            } else {
536
                length = convertTypeToLength(type);
730✔
537
            }
538
        }
539

540
        for (int n = 0; n < count; ++n) {
1,988✔
541
            Field * tag = benchCalloc(1, sizeof(Field), true);
1,064✔
542
            benchArrayPush(stbInfo->tags, tag);
1,064✔
543
            tag = benchArrayGet(stbInfo->tags, stbInfo->tags->size - 1);
1,064✔
544
            tag->type = type;
1,064✔
545
            tag->length = length;
1,064✔
546
            if (length == 0) {
1,064✔
547
                tag->null = true;
×
548
            }
549
            tag->max = max;
1,064✔
550
            tag->min = min;
1,064✔
551
            tag->maxInDbl = maxInDbl;
1,064✔
552
            tag->minInDbl = minInDbl;
1,064✔
553
            tag->scalingFactor = scalingFactor;
1,064✔
554
            tag->values = dataValues;
1,064✔
555
            if (customName) {
1,064✔
556
                if (n >= 1) {
68✔
557
                    snprintf(tag->name, TSDB_COL_NAME_LEN,
6✔
558
                             "%s_%d", dataName->valuestring, n);
559
                } else {
560
                    snprintf(tag->name, TSDB_COL_NAME_LEN,
62✔
561
                             "%s", dataName->valuestring);
562
                }
563
            } else {
564
                snprintf(tag->name, TSDB_COL_NAME_LEN, "t%d", index);
996✔
565
            }
566
            index++;
1,064✔
567
        }
568
    }
569
    code = 0;
150✔
570
PARSE_OVER:
150✔
571
    return code;
150✔
572
}
573

574
int32_t getDurationVal(tools_cJSON *jsonObj) {
3✔
575
    int32_t durMinute = 0;
3✔
576
    // get duration value
577
    if (tools_cJSON_IsString(jsonObj)) {
3✔
578
        char *val = jsonObj->valuestring;
2✔
579
        // like 10d or 10h or 10m
580
        int32_t len = strlen(val);
2✔
581
        if (len == 0) return 0;
2✔
582
        durMinute = atoi(val);
2✔
583
        if (strchr(val, 'h') || strchr(val, 'H')) {
2✔
584
            // hour
585
            durMinute *= 60;
×
586
        } else if (strchr(val, 'm') || strchr(val, 'M')) {
2✔
587
            // minute
588
            durMinute *= 1;
2✔
589
        } else {
590
            // day
591
            durMinute *= 24 * 60;
×
592
        }
593
    } else if (tools_cJSON_IsNumber(jsonObj)) {
1✔
594
        durMinute = jsonObj->valueint * 24 * 60;
1✔
595
    }
596

597
    return durMinute;
3✔
598
}
599

600
void setDBCfgString(SDbCfg* cfg , char * value) {
7✔
601
    int32_t len = strlen(value);
7✔
602

603
    // need add quotation
604
    bool add = false;
7✔
605
    if (0 == strcasecmp(cfg->name, "cachemodel") ||
7✔
606
        0 == strcasecmp(cfg->name, "dnodes"    ) ||
2✔
607
        0 == strcasecmp(cfg->name, "precision" ) ) {
2✔
608
            add = true;
5✔
609
    }    
610

611
    if (value[0] == '\'' || value[0] == '\"') {
7✔
612
        // already have quotation
613
        add = false;
4✔
614
    }
615

616
    if (!add) {
7✔
617
        // unnecesary add
618
        cfg->valuestring = value;
6✔
619
        cfg->free = false;
6✔
620
        return ;
6✔
621
    }
622

623
    // new
624
    int32_t nlen = len + 2 + 1;
1✔
625
    char * nval  = calloc(nlen, sizeof(char));
1✔
626
    nval[0]      = '\'';
1✔
627
    memcpy(nval + 1, value, len);
1✔
628
    nval[nlen - 2] = '\'';
1✔
629
    nval[nlen - 1] = 0;
1✔
630
    cfg->valuestring = nval;
1✔
631
    cfg->free = true;
1✔
632
    return ;
1✔
633
}
634

635
static int getDatabaseInfo(tools_cJSON *dbinfos, int index) {
83✔
636
    SDataBase *database;
637
    if (index > 0) {
83✔
638
        database = benchCalloc(1, sizeof(SDataBase), true);
1✔
639
        database->superTbls = benchArrayInit(1, sizeof(SSuperTable));
1✔
640
        benchArrayPush(g_arguments->databases, database);
1✔
641
    }
642
    database = benchArrayGet(g_arguments->databases, index);
83✔
643
    if (database->cfgs == NULL) {
83✔
644
        database->cfgs = benchArrayInit(1, sizeof(SDbCfg));
1✔
645
    }
646

647
    // check command line input no
648
    if(!(g_argFlag & ARG_OPT_NODROP)) {
83✔
649
        database->drop = true;
82✔
650
    }
651
  
652
    database->flush = false;
83✔
653
    database->precision = TSDB_TIME_PRECISION_MILLI;
83✔
654
    database->sml_precision = TSDB_SML_TIMESTAMP_MILLI_SECONDS;
83✔
655
    tools_cJSON *dbinfo = tools_cJSON_GetArrayItem(dbinfos, index);
83✔
656
    tools_cJSON *db = tools_cJSON_GetObjectItem(dbinfo, "dbinfo");
83✔
657
    if (!tools_cJSON_IsObject(db)) {
83✔
658
        errorPrint("%s", "Invalid dbinfo format in json\n");
×
659
        return -1;
×
660
    }
661

662
    tools_cJSON* cfg_object = db->child;
83✔
663

664
    while (cfg_object) {
353✔
665
        if (0 == strcasecmp(cfg_object->string, "name")) {
270✔
666
            if (tools_cJSON_IsString(cfg_object)) {
83✔
667
                database->dbName = cfg_object->valuestring;
83✔
668
            }
669
        } else if (0 == strcasecmp(cfg_object->string, "drop")) {
187✔
670
            if (tools_cJSON_IsString(cfg_object)
79✔
671
                && (0 == strcasecmp(cfg_object->valuestring, "no"))) {
79✔
672
                database->drop = false;
9✔
673
            }
674
        } else if (0 == strcasecmp(cfg_object->string, "flush_each_batch")) {
108✔
675
            if (tools_cJSON_IsString(cfg_object)
1✔
676
                && (0 == strcasecmp(cfg_object->valuestring, "yes"))) {
1✔
677
                database->flush = true;
1✔
678
            }
679
        } else if (0 == strcasecmp(cfg_object->string, "precision")) {
107✔
680
            if (tools_cJSON_IsString(cfg_object)) {
38✔
681
                if (0 == strcasecmp(cfg_object->valuestring, "us")) {
38✔
682
                    database->precision = TSDB_TIME_PRECISION_MICRO;
2✔
683
                    database->sml_precision = TSDB_SML_TIMESTAMP_MICRO_SECONDS;
2✔
684
                } else if (0 == strcasecmp(cfg_object->valuestring, "ns")) {
36✔
685
                    database->precision = TSDB_TIME_PRECISION_NANO;
1✔
686
                    database->sml_precision = TSDB_SML_TIMESTAMP_NANO_SECONDS;
1✔
687
                }
688
            }
689
        } else {
690
            SDbCfg* cfg = benchCalloc(1, sizeof(SDbCfg), true);
69✔
691
            cfg->name = cfg_object->string;
69✔
692

693
            // get duration value
694
            if (0 == strcasecmp(cfg_object->string, "duration")) {
69✔
695
                database->durMinute = getDurationVal(cfg_object);
3✔
696
            }
697

698
            if (tools_cJSON_IsString(cfg_object)) {
69✔
699
                setDBCfgString(cfg, cfg_object->valuestring);
7✔
700
            } else if (tools_cJSON_IsNumber(cfg_object)) {
62✔
701
                cfg->valueint = (int)cfg_object->valueint;
62✔
702
                cfg->valuestring = NULL;
62✔
703
            } else {
704
                errorPrint("Invalid value format for %s\n", cfg->name);
×
705
                free(cfg);
×
706
                return -1;
×
707
            }
708
            benchArrayPush(database->cfgs, cfg);
69✔
709
        }
710
        cfg_object = cfg_object->next;
270✔
711
    }
712

713
    // set default
714
    if (database->durMinute == 0) {
83✔
715
        database->durMinute = TSDB_DEFAULT_DURATION_PER_FILE;
80✔
716
    }
717

718
    if (database->dbName  == NULL) {
83✔
719
        errorPrint("%s", "miss name in dbinfo\n");
×
720
        return -1;
×
721
    }
722

723
    return 0;
83✔
724
}
725

726
static int get_tsma_info(tools_cJSON* stb_obj, SSuperTable* stbInfo) {
151✔
727
    stbInfo->tsmas = benchArrayInit(1, sizeof(TSMA));
151✔
728
    tools_cJSON* tsmas_obj = tools_cJSON_GetObjectItem(stb_obj, "tsmas");
151✔
729
    if (tsmas_obj == NULL) {
151✔
730
        return 0;
151✔
731
    }
732
    if (!tools_cJSON_IsArray(tsmas_obj)) {
×
733
        errorPrint("%s", "invalid tsmas format in json\n");
×
734
        return -1;
×
735
    }
736
    for (int i = 0; i < tools_cJSON_GetArraySize(tsmas_obj); ++i) {
×
737
        tools_cJSON* tsma_obj = tools_cJSON_GetArrayItem(tsmas_obj, i);
×
738
        if (!tools_cJSON_IsObject(tsma_obj)) {
×
739
            errorPrint("%s", "Invalid tsma format in json\n");
×
740
            return -1;
×
741
        }
742
        TSMA* tsma = benchCalloc(1, sizeof(TSMA), true);
×
743
        if (NULL == tsma) {
×
744
            errorPrint("%s() failed to allocate memory\n", __func__);
×
745
        }
746
        tools_cJSON* tsma_name_obj = tools_cJSON_GetObjectItem(tsma_obj,
×
747
                                                               "name");
748
        if (!tools_cJSON_IsString(tsma_name_obj)) {
×
749
            errorPrint("%s", "Invalid tsma name format in json\n");
×
750
            free(tsma);
×
751
            return -1;
×
752
        }
753
        tsma->name = tsma_name_obj->valuestring;
×
754

755
        tools_cJSON* tsma_func_obj =
756
            tools_cJSON_GetObjectItem(tsma_obj, "function");
×
757
        if (!tools_cJSON_IsString(tsma_func_obj)) {
×
758
            errorPrint("%s", "Invalid tsma function format in json\n");
×
759
            free(tsma);
×
760
            return -1;
×
761
        }
762
        tsma->func = tsma_func_obj->valuestring;
×
763

764
        tools_cJSON* tsma_interval_obj =
765
            tools_cJSON_GetObjectItem(tsma_obj, "interval");
×
766
        if (!tools_cJSON_IsString(tsma_interval_obj)) {
×
767
            errorPrint("%s", "Invalid tsma interval format in json\n");
×
768
            free(tsma);
×
769
            return -1;
×
770
        }
771
        tsma->interval = tsma_interval_obj->valuestring;
×
772

773
        tools_cJSON* tsma_sliding_obj =
774
            tools_cJSON_GetObjectItem(tsma_obj, "sliding");
×
775
        if (!tools_cJSON_IsString(tsma_sliding_obj)) {
×
776
            errorPrint("%s", "Invalid tsma sliding format in json\n");
×
777
            free(tsma);
×
778
            return -1;
×
779
        }
780
        tsma->sliding = tsma_sliding_obj->valuestring;
×
781

782
        tools_cJSON* tsma_custom_obj =
783
            tools_cJSON_GetObjectItem(tsma_obj, "custom");
×
784
        tsma->custom = tsma_custom_obj->valuestring;
×
785

786
        tools_cJSON* tsma_start_obj =
787
            tools_cJSON_GetObjectItem(tsma_obj, "start_when_inserted");
×
788
        if (!tools_cJSON_IsNumber(tsma_start_obj)) {
×
789
            tsma->start_when_inserted = 0;
×
790
        } else {
791
            tsma->start_when_inserted = (int)tsma_start_obj->valueint;
×
792
        }
793

794
        benchArrayPush(stbInfo->tsmas, tsma);
×
795
    }
796

797
    return 0;
×
798
}
799

800
void parseStringToIntArray(char *str, BArray *arr) {
2✔
801
    benchArrayClear(arr);
2✔
802
    if (NULL == strstr(str, ",")) {
2✔
803
        int *val = benchCalloc(1, sizeof(int), true);
×
804
        *val = atoi(str);
×
805
        benchArrayPush(arr, val);
×
806
    } else {
807
        char *dup_str = strdup(str);
2✔
808
        char *running = dup_str;
2✔
809
        char *token = strsep(&running, ",");
2✔
810
        while (token) {
10✔
811
            int *val = benchCalloc(1, sizeof(int), true);
8✔
812
            *val = atoi(token);
8✔
813
            benchArrayPush(arr, val);
8✔
814
            token = strsep(&running, ",");
8✔
815
        }
816
        tmfree(dup_str);
2✔
817
    }
818
}
2✔
819

820
// get interface name
821
uint16_t getInterface(char *name) {
144✔
822
    uint16_t iface = TAOSC_IFACE;
144✔
823
    if (0 == strcasecmp(name, "rest")) {
144✔
824
        iface = REST_IFACE;
2✔
825
    } else if (0 == strcasecmp(name, "stmt")) {
142✔
826
        iface = STMT_IFACE;
17✔
827
    } else if (0 == strcasecmp(name, "stmt2")) {
125✔
828
        iface = STMT2_IFACE;
1✔
829
    } else if (0 == strcasecmp(name, "sml")) {
124✔
830
        iface = SML_IFACE;
48✔
831
    } else if (0 == strcasecmp(name, "sml-rest")) {
76✔
832
        iface = SML_REST_IFACE;
8✔
833
    }
834

835
    return iface;
144✔
836
}
837

838
static int getStableInfo(tools_cJSON *dbinfos, int index) {
83✔
839
    SDataBase *database = benchArrayGet(g_arguments->databases, index);
83✔
840
    tools_cJSON *dbinfo = tools_cJSON_GetArrayItem(dbinfos, index);
83✔
841
    tools_cJSON *stables = tools_cJSON_GetObjectItem(dbinfo, "super_tables");
83✔
842
    if (!tools_cJSON_IsArray(stables)) {
83✔
843
        infoPrint("create database %s without stables\n", database->dbName);
1✔
844
        return 0;
1✔
845
    }
846
    for (int i = 0; i < tools_cJSON_GetArraySize(stables); ++i) {
233✔
847
        SSuperTable *superTable;
848
        if (index > 0 || i > 0) {
151✔
849
            superTable = benchCalloc(1, sizeof(SSuperTable), true);
69✔
850
            benchArrayPush(database->superTbls, superTable);
69✔
851
            superTable = benchArrayGet(database->superTbls, i);
69✔
852
            superTable->cols = benchArrayInit(1, sizeof(Field));
69✔
853
            superTable->tags = benchArrayInit(1, sizeof(Field));
69✔
854
        } else {
855
            superTable = benchArrayGet(database->superTbls, i);
82✔
856
        }
857
        superTable->autoTblCreating = false;
151✔
858
        superTable->batchTblCreatingNum = DEFAULT_CREATE_BATCH;
151✔
859
        superTable->batchTblCreatingNumbers = NULL;
151✔
860
        superTable->batchTblCreatingIntervals = NULL;
151✔
861
        superTable->childTblExists = false;
151✔
862
        superTable->random_data_source = true;
151✔
863
        superTable->iface = TAOSC_IFACE;
151✔
864
        superTable->lineProtocol = TSDB_SML_LINE_PROTOCOL;
151✔
865
        superTable->tcpTransfer = false;
151✔
866
        superTable->childTblOffset = 0;
151✔
867
        superTable->timestamp_step = 1;
151✔
868
        superTable->angle_step = 1;
151✔
869
        superTable->useSampleTs = false;
151✔
870
        superTable->non_stop = false;
151✔
871
        superTable->insertRows = 0;
151✔
872
        superTable->interlaceRows = 0;
151✔
873
        superTable->disorderRatio = 0;
151✔
874
        superTable->disorderRange = DEFAULT_DISORDER_RANGE;
151✔
875
        superTable->insert_interval = g_arguments->insert_interval;
151✔
876
        superTable->max_sql_len = TSDB_MAX_ALLOWED_SQL_LEN;
151✔
877
        superTable->partialColNum = 0;
151✔
878
        superTable->partialColFrom = 0;
151✔
879
        superTable->comment = NULL;
151✔
880
        superTable->delay = -1;
151✔
881
        superTable->file_factor = -1;
151✔
882
        superTable->rollup = NULL;
151✔
883
        tools_cJSON *stbInfo = tools_cJSON_GetArrayItem(stables, i);
151✔
884
        tools_cJSON *itemObj;
885

886
        tools_cJSON *stbName = tools_cJSON_GetObjectItem(stbInfo, "name");
151✔
887
        if (tools_cJSON_IsString(stbName)) {
151✔
888
            superTable->stbName = stbName->valuestring;
151✔
889
        }
890

891
        tools_cJSON *prefix =
892
            tools_cJSON_GetObjectItem(stbInfo, "childtable_prefix");
151✔
893
        if (tools_cJSON_IsString(prefix)) {
151✔
894
            superTable->childTblPrefix = prefix->valuestring;
151✔
895
        }
896
        tools_cJSON *childTbleSample =
897
            tools_cJSON_GetObjectItem(stbInfo, "childtable_sample_file");
151✔
898
        if (tools_cJSON_IsString(childTbleSample)) {
151✔
899
            superTable->childTblSample = childTbleSample->valuestring;
2✔
900
        }
901
        tools_cJSON *autoCreateTbl =
902
            tools_cJSON_GetObjectItem(stbInfo, "auto_create_table");
151✔
903
        if (tools_cJSON_IsString(autoCreateTbl)
151✔
904
                && (0 == strcasecmp(autoCreateTbl->valuestring, "yes"))) {
139✔
905
            superTable->autoTblCreating = true;
11✔
906
        }
907
        tools_cJSON *batchCreateTbl =
908
            tools_cJSON_GetObjectItem(stbInfo, "batch_create_tbl_num");
151✔
909
        if (tools_cJSON_IsNumber(batchCreateTbl)) {
151✔
910
            superTable->batchTblCreatingNum = batchCreateTbl->valueint;
137✔
911
        }
912
        tools_cJSON *batchTblCreatingNumbers =
913
            tools_cJSON_GetObjectItem(stbInfo, "batch_create_tbl_numbers");
151✔
914
        if (tools_cJSON_IsString(batchTblCreatingNumbers)) {
151✔
915
            superTable->batchTblCreatingNumbers
916
                = batchTblCreatingNumbers->valuestring;
1✔
917
            superTable->batchTblCreatingNumbersArray =
1✔
918
                benchArrayInit(1, sizeof(int));
1✔
919
            parseStringToIntArray(superTable->batchTblCreatingNumbers,
1✔
920
                                  superTable->batchTblCreatingNumbersArray);
921
        }
922
        tools_cJSON *batchTblCreatingIntervals =
923
            tools_cJSON_GetObjectItem(stbInfo, "batch_create_tbl_intervals");
151✔
924
        if (tools_cJSON_IsString(batchTblCreatingIntervals)) {
151✔
925
            superTable->batchTblCreatingIntervals
926
                = batchTblCreatingIntervals->valuestring;
1✔
927
            superTable->batchTblCreatingIntervalsArray =
1✔
928
                benchArrayInit(1, sizeof(int));
1✔
929
            parseStringToIntArray(superTable->batchTblCreatingIntervals,
1✔
930
                                  superTable->batchTblCreatingIntervalsArray);
931
        }
932
        tools_cJSON *childTblExists =
933
            tools_cJSON_GetObjectItem(stbInfo, "child_table_exists");
151✔
934
        if (tools_cJSON_IsString(childTblExists)
151✔
935
                && (0 == strcasecmp(childTblExists->valuestring, "yes"))
146✔
936
                && !database->drop) {
13✔
937
            superTable->childTblExists = true;
9✔
938
            superTable->autoTblCreating = false;
9✔
939
        }
940

941
        tools_cJSON *childTableCount =
942
            tools_cJSON_GetObjectItem(stbInfo, "childtable_count");
151✔
943
        if (tools_cJSON_IsNumber(childTableCount)) {
151✔
944
            superTable->childTblCount = childTableCount->valueint;
151✔
945
            g_arguments->totalChildTables += superTable->childTblCount;
151✔
946
        } else {
947
            superTable->childTblCount = 0;
×
948
            g_arguments->totalChildTables += superTable->childTblCount;
×
949
        }
950

951
        tools_cJSON *dataSource =
952
            tools_cJSON_GetObjectItem(stbInfo, "data_source");
151✔
953
        if (tools_cJSON_IsString(dataSource)
151✔
954
                && (0 == strcasecmp(dataSource->valuestring, "sample"))) {
139✔
955
            superTable->random_data_source = false;
8✔
956
        }
957

958
        tools_cJSON *stbIface =
959
            tools_cJSON_GetObjectItem(stbInfo, "insert_mode");
151✔
960
        if (tools_cJSON_IsString(stbIface)) {
151✔
961
            superTable->iface = getInterface(stbIface->valuestring);
143✔
962
            if (superTable->iface == STMT_IFACE) {
143✔
963
                if (g_arguments->reqPerReq > g_arguments->prepared_rand) {
17✔
964
                    g_arguments->prepared_rand = g_arguments->reqPerReq;
×
965
                }
966
            } else if (superTable->iface == SML_IFACE) {
126✔
967
                if (g_arguments->reqPerReq > SML_MAX_BATCH) {
48✔
968
                    errorPrint("reqPerReq (%u) larger than maximum (%d)\n",
×
969
                               g_arguments->reqPerReq, SML_MAX_BATCH);
970
                    return -1;
×
971
                }
972
            } else if (isRest(superTable->iface)) {
78✔
973
                if (g_arguments->reqPerReq > SML_MAX_BATCH) {
9✔
974
                    errorPrint("reqPerReq (%u) larger than maximum (%d)\n",
×
975
                               g_arguments->reqPerReq, SML_MAX_BATCH);
976
                    return -1;
×
977
                }
978
                if (0 != convertServAddr(REST_IFACE,
9✔
979
                                         false,
980
                                         1)) {
981
                    errorPrint("%s", "Failed to convert server address\n");
×
982
                    return -1;
×
983
                }
984
                encodeAuthBase64();
9✔
985
                g_arguments->rest_server_ver_major =
9✔
986
                    getServerVersionRest(g_arguments->port + TSDB_PORT_HTTP);
9✔
987
            }
988
#ifdef WEBSOCKET
989
            if (g_arguments->websocket) {
143✔
990
                infoPrint("Since WebSocket interface is enabled, "
1✔
991
                        "the interface %s is changed to use WebSocket.\n",
992
                        stbIface->valuestring);
993
                superTable->iface = TAOSC_IFACE;
1✔
994
            }
995
#endif
996
        }
997

998

999
        tools_cJSON *stbLineProtocol =
1000
            tools_cJSON_GetObjectItem(stbInfo, "line_protocol");
151✔
1001
        if (tools_cJSON_IsString(stbLineProtocol)) {
151✔
1002
            if (0 == strcasecmp(stbLineProtocol->valuestring, "line")) {
85✔
1003
                superTable->lineProtocol = TSDB_SML_LINE_PROTOCOL;
34✔
1004
            } else if (0 == strcasecmp(stbLineProtocol->valuestring,
51✔
1005
                                       "telnet")) {
1006
                superTable->lineProtocol = TSDB_SML_TELNET_PROTOCOL;
19✔
1007
            } else if (0 == strcasecmp(stbLineProtocol->valuestring, "json")) {
32✔
1008
                superTable->lineProtocol = TSDB_SML_JSON_PROTOCOL;
22✔
1009
            } else if (0 == strcasecmp(
10✔
1010
                        stbLineProtocol->valuestring, "taosjson")) {
10✔
1011
                superTable->lineProtocol = SML_JSON_TAOS_FORMAT;
10✔
1012
            }
1013
        }
1014
        tools_cJSON *transferProtocol =
1015
            tools_cJSON_GetObjectItem(stbInfo, "tcp_transfer");
151✔
1016
        if (tools_cJSON_IsString(transferProtocol)
151✔
1017
                && (0 == strcasecmp(transferProtocol->valuestring, "yes"))) {
5✔
1018
            superTable->tcpTransfer = true;
2✔
1019
        }
1020
        tools_cJSON *childTbl_limit =
1021
            tools_cJSON_GetObjectItem(stbInfo, "childtable_limit");
151✔
1022
        if (tools_cJSON_IsNumber(childTbl_limit)) {
151✔
1023
            if (childTbl_limit->valueint >= 0) {
119✔
1024
                superTable->childTblLimit = childTbl_limit->valueint;
113✔
1025
                if (superTable->childTblLimit > superTable->childTblCount) {
113✔
1026
                    warnPrint("child table limit %"PRId64" "
12✔
1027
                            "is more than %"PRId64", set to %"PRId64"\n",
1028
                          childTbl_limit->valueint,
1029
                          superTable->childTblCount,
1030
                          superTable->childTblCount);
1031
                    superTable->childTblLimit = superTable->childTblCount;
12✔
1032
                }
1033
            } else {
1034
                warnPrint("child table limit %"PRId64" is invalid, set to zero. \n",childTbl_limit->valueint);
6✔
1035
                superTable->childTblLimit = 0;
6✔
1036
            }
1037
        }
1038
        tools_cJSON *childTbl_offset =
1039
            tools_cJSON_GetObjectItem(stbInfo, "childtable_offset");
151✔
1040
        if (tools_cJSON_IsNumber(childTbl_offset)) {
151✔
1041
            superTable->childTblOffset = childTbl_offset->valueint;
119✔
1042
        }
1043

1044
        // check limit offset 
1045
        if( superTable->childTblOffset + superTable->childTblLimit > superTable->childTblCount ) {
151✔
1046
            errorPrint("json config invalid. childtable_offset(%"PRId64") + childtable_limit(%"PRId64") > childtable_count(%"PRId64")",
×
1047
                  superTable->childTblOffset, superTable->childTblLimit, superTable->childTblCount);
1048
            return -1;          
×
1049
        }
1050

1051
        tools_cJSON *childTbl_from =
1052
            tools_cJSON_GetObjectItem(stbInfo, "childtable_from");
151✔
1053
        if (tools_cJSON_IsNumber(childTbl_from)) {
151✔
1054
            if (childTbl_from->valueint >= 0) {
4✔
1055
                superTable->childTblFrom = childTbl_from->valueint;
4✔
1056
            } else {
1057
                warnPrint("child table _from_ %"PRId64" is invalid, set to 0\n",
×
1058
                          childTbl_from->valueint);
1059
                superTable->childTblFrom = 0;
×
1060
            }
1061
        }
1062
        tools_cJSON *childTbl_to =
1063
            tools_cJSON_GetObjectItem(stbInfo, "childtable_to");
151✔
1064
        if (tools_cJSON_IsNumber(childTbl_to)) {
151✔
1065
            superTable->childTblTo = childTbl_to->valueint;
4✔
1066
            if (superTable->childTblTo < superTable->childTblFrom) {
4✔
1067
                errorPrint("json config invalid. child table _to_ is invalid number,"
×
1068
                    "%"PRId64" < %"PRId64"\n",
1069
                    superTable->childTblTo, superTable->childTblFrom);
1070
                return -1;
×
1071
            }
1072
        }
1073

1074
        // check childtable_from and childtable_to valid
1075
        if (superTable->childTblFrom >= superTable->childTblCount) {
151✔
1076
            errorPrint("json config invalid. childtable_from(%"PRId64") is equal or large than childtable_count(%"PRId64")\n", superTable->childTblFrom, superTable->childTblCount);
×
1077
            return -1;
×
1078
        }  
1079
        if (superTable->childTblTo > superTable->childTblCount) {
151✔
1080
            errorPrint("json config invalid. childtable_to(%"PRId64") is large than childtable_count(%"PRId64")\n", superTable->childTblTo, superTable->childTblCount);
×
1081
            return -1;
×
1082
        }
1083

1084
        // read from super table
1085
        tools_cJSON *continueIfFail =
1086
            tools_cJSON_GetObjectItem(stbInfo, "continue_if_fail");  // yes, no,
151✔
1087
        if (tools_cJSON_IsString(continueIfFail)) {
151✔
1088
            if (0 == strcasecmp(continueIfFail->valuestring, "no")) {
3✔
1089
                superTable->continueIfFail = NO_IF_FAILED;
1✔
1090
            } else if (0 == strcasecmp(continueIfFail->valuestring, "yes")) {
2✔
1091
                superTable->continueIfFail = YES_IF_FAILED;
1✔
1092
            } else if (0 == strcasecmp(continueIfFail->valuestring, "smart")) {
1✔
1093
                superTable->continueIfFail = SMART_IF_FAILED;
1✔
1094
            } else {
1095
                errorPrint("cointinue_if_fail has unknown mode %s\n",
×
1096
                           continueIfFail->valuestring);
1097
                return -1;
×
1098
            }
1099
        } else {
1100
            // default value is common specialed
1101
            superTable->continueIfFail = g_arguments->continueIfFail;
148✔
1102
        }
1103

1104
        // start_fillback_time
1105
        superTable->startFillbackTime = 0;
151✔
1106
        tools_cJSON *ts = tools_cJSON_GetObjectItem(stbInfo, "start_fillback_time");
151✔
1107
        if (tools_cJSON_IsString(ts)) {
151✔
1108
            if(0 == strcasecmp(ts->valuestring, "auto")) {
×
1109
                superTable->autoFillback = true;
×
1110
                superTable->startFillbackTime = 0;
×
1111
            }
1112
            else if (toolsParseTime(ts->valuestring,
×
1113
                                &(superTable->startFillbackTime),
1114
                                (int32_t)strlen(ts->valuestring),
×
1115
                                database->precision, 0)) {
1116
                errorPrint("failed to parse time %s\n", ts->valuestring);
×
1117
                return -1;
×
1118
            }
1119
        } else {
1120
            if (tools_cJSON_IsNumber(ts)) {
151✔
1121
                superTable->startFillbackTime = ts->valueint;
×
1122
            }
1123
        }
1124

1125
        // start_timestamp
1126
        ts = tools_cJSON_GetObjectItem(stbInfo, "start_timestamp");
151✔
1127
        if (tools_cJSON_IsString(ts)) {
151✔
1128
            if (0 == strcasecmp(ts->valuestring, "now")) {
140✔
1129
                superTable->startTimestamp =
68✔
1130
                    toolsGetTimestamp(database->precision);
68✔
1131
                superTable->useNow = true;
68✔
1132
                //  fill time with now conflict with check_sql
1133
                g_arguments->check_sql = false;
68✔
1134
            } else if (0 == strncasecmp(ts->valuestring, "now", 3)) {
72✔
1135
                // like now - 7d expression
1136
                superTable->calcNow = ts->valuestring;
×
1137
            } else {
1138
                if (toolsParseTime(ts->valuestring,
72✔
1139
                                   &(superTable->startTimestamp),
1140
                                   (int32_t)strlen(ts->valuestring),
72✔
1141
                                   database->precision, 0)) {
1142
                    errorPrint("failed to parse time %s\n",
×
1143
                               ts->valuestring);
1144
                    return -1;
×
1145
                }
1146
            }
1147
        } else {
1148
            if (tools_cJSON_IsNumber(ts)) {
11✔
1149
                superTable->startTimestamp = ts->valueint;
7✔
1150
            } else {
1151
                superTable->startTimestamp =
4✔
1152
                    toolsGetTimestamp(database->precision);
4✔
1153
            }
1154
        }
1155

1156
        tools_cJSON *timestampStep =
1157
            tools_cJSON_GetObjectItem(stbInfo, "timestamp_step");
151✔
1158
        if (tools_cJSON_IsNumber(timestampStep)) {
151✔
1159
            superTable->timestamp_step = timestampStep->valueint;
147✔
1160
        }
1161

1162
        tools_cJSON *angleStep =
1163
            tools_cJSON_GetObjectItem(stbInfo, "angle_step");
151✔
1164
        if (tools_cJSON_IsNumber(angleStep)) {
151✔
1165
            superTable->angle_step = angleStep->valueint;
×
1166
        }
1167

1168
        tools_cJSON *keepTrying =
1169
            tools_cJSON_GetObjectItem(stbInfo, "keep_trying");
151✔
1170
        if (tools_cJSON_IsNumber(keepTrying)) {
151✔
1171
            superTable->keep_trying = keepTrying->valueint;
6✔
1172
        }
1173

1174
        tools_cJSON *tryingInterval =
1175
            tools_cJSON_GetObjectItem(stbInfo, "trying_interval");
151✔
1176
        if (tools_cJSON_IsNumber(tryingInterval)) {
151✔
1177
            superTable->trying_interval = (uint32_t)tryingInterval->valueint;
6✔
1178
        }
1179

1180
        tools_cJSON *sampleFile =
1181
            tools_cJSON_GetObjectItem(stbInfo, "sample_file");
151✔
1182
        if (tools_cJSON_IsString(sampleFile)) {
151✔
1183
            tstrncpy(
122✔
1184
                superTable->sampleFile, sampleFile->valuestring,
1185
                MAX_FILE_NAME_LEN);
1186
        } else {
1187
            memset(superTable->sampleFile, 0, MAX_FILE_NAME_LEN);
29✔
1188
        }
1189

1190
        tools_cJSON *useSampleTs =
1191
            tools_cJSON_GetObjectItem(stbInfo, "use_sample_ts");
151✔
1192
        if (tools_cJSON_IsString(useSampleTs) &&
151✔
1193
            (0 == strcasecmp(useSampleTs->valuestring, "yes"))) {
84✔
1194
            superTable->useSampleTs = true;
6✔
1195
        }
1196

1197
        tools_cJSON *nonStop =
1198
            tools_cJSON_GetObjectItem(stbInfo, "non_stop_mode");
151✔
1199
        if (tools_cJSON_IsString(nonStop) &&
151✔
1200
            (0 == strcasecmp(nonStop->valuestring, "yes"))) {
12✔
1201
            superTable->non_stop = true;
×
1202
        }
1203

1204
        tools_cJSON* max_sql_len_obj =
1205
            tools_cJSON_GetObjectItem(stbInfo, "max_sql_len");
151✔
1206
        if (tools_cJSON_IsNumber(max_sql_len_obj)) {
151✔
1207
            superTable->max_sql_len = max_sql_len_obj->valueint;
43✔
1208
        }
1209

1210
        tools_cJSON *tagsFile =
1211
            tools_cJSON_GetObjectItem(stbInfo, "tags_file");
151✔
1212
        if (tools_cJSON_IsString(tagsFile)) {
151✔
1213
            tstrncpy(superTable->tagsFile, tagsFile->valuestring,
134✔
1214
                     MAX_FILE_NAME_LEN);
1215
        } else {
1216
            memset(superTable->tagsFile, 0, MAX_FILE_NAME_LEN);
17✔
1217
        }
1218

1219
        tools_cJSON *insertRows =
1220
            tools_cJSON_GetObjectItem(stbInfo, "insert_rows");
151✔
1221
        if (tools_cJSON_IsNumber(insertRows)) {
151✔
1222
            superTable->insertRows = insertRows->valueint;
151✔
1223
        }
1224

1225
        tools_cJSON *stbInterlaceRows =
1226
            tools_cJSON_GetObjectItem(stbInfo, "interlace_rows");
151✔
1227
        if (tools_cJSON_IsNumber(stbInterlaceRows)) {
151✔
1228
            superTable->interlaceRows = (uint32_t)stbInterlaceRows->valueint;
135✔
1229
        }
1230

1231
        // disorder
1232
        tools_cJSON *disorderRatio =
1233
            tools_cJSON_GetObjectItem(stbInfo, "disorder_ratio");
151✔
1234
        if (tools_cJSON_IsNumber(disorderRatio)) {
151✔
1235
            if (disorderRatio->valueint > 100) disorderRatio->valueint = 100;
129✔
1236
            if (disorderRatio->valueint < 0) disorderRatio->valueint = 0;
129✔
1237

1238
            superTable->disorderRatio = (int)disorderRatio->valueint;
129✔
1239
            superTable->disRatio = (uint8_t)disorderRatio->valueint;
129✔
1240
        }
1241
        tools_cJSON *disorderRange =
1242
            tools_cJSON_GetObjectItem(stbInfo, "disorder_range");
151✔
1243
        if (tools_cJSON_IsNumber(disorderRange)) {
151✔
1244
            superTable->disorderRange = (int)disorderRange->valueint;
127✔
1245
            superTable->disRange = disorderRange->valueint;
127✔
1246
        }
1247
        tools_cJSON *disFill =
1248
            tools_cJSON_GetObjectItem(stbInfo, "disorder_fill_interval");
151✔
1249
        if (tools_cJSON_IsNumber(disFill)) {
151✔
1250
            superTable->fillIntervalDis = (int)disFill->valueint;
3✔
1251
        }
1252

1253

1254
        // update
1255
        tools_cJSON *updRatio =
1256
            tools_cJSON_GetObjectItem(stbInfo, "update_ratio");
151✔
1257
        if (tools_cJSON_IsNumber(updRatio)) {
151✔
1258
            if (updRatio->valueint > 100) updRatio->valueint = 100;
3✔
1259
            if (updRatio->valueint < 0) updRatio->valueint = 0;
3✔
1260
            superTable->updRatio = (int8_t)updRatio->valueint;
3✔
1261
        }
1262
        tools_cJSON *updFill =
1263
            tools_cJSON_GetObjectItem(stbInfo, "update_fill_interval");
151✔
1264
        if (tools_cJSON_IsNumber(updFill)) {
151✔
1265
            superTable->fillIntervalUpd = (uint64_t)updFill->valueint;
3✔
1266
        }
1267

1268
        // delete
1269
        tools_cJSON *delRatio =
1270
            tools_cJSON_GetObjectItem(stbInfo, "delete_ratio");
151✔
1271
        if (tools_cJSON_IsNumber(delRatio)) {
151✔
1272
            if (delRatio->valueint > 100) delRatio->valueint = 100;
3✔
1273
            if (delRatio->valueint < 0) delRatio->valueint = 0;
3✔
1274
            superTable->delRatio = (int8_t)delRatio->valueint;
3✔
1275
        }
1276

1277
        // generate row rule
1278
        tools_cJSON *rowRule =
1279
            tools_cJSON_GetObjectItem(stbInfo, "generate_row_rule");
151✔
1280
        if (tools_cJSON_IsNumber(rowRule)) {
151✔
1281
            superTable->genRowRule = (int8_t)rowRule->valueint;
6✔
1282
        }
1283

1284
        // binary prefix
1285
        tools_cJSON *binPrefix =
1286
            tools_cJSON_GetObjectItem(stbInfo, "binary_prefix");
151✔
1287
        if (tools_cJSON_IsString(binPrefix)) {
151✔
1288
            superTable->binaryPrefex = binPrefix->valuestring;
×
1289
        } else {
1290
            superTable->binaryPrefex = NULL;
151✔
1291
        }
1292

1293
        // nchar prefix
1294
        tools_cJSON *ncharPrefix =
1295
            tools_cJSON_GetObjectItem(stbInfo, "nchar_prefix");
151✔
1296
        if (tools_cJSON_IsString(ncharPrefix)) {
151✔
1297
            superTable->ncharPrefex = ncharPrefix->valuestring;
×
1298
        } else {
1299
            superTable->ncharPrefex = NULL;
151✔
1300
        }
1301

1302
        // write future random
1303
        itemObj = tools_cJSON_GetObjectItem(stbInfo, "random_write_future");
151✔
1304
        if (tools_cJSON_IsString(itemObj)
151✔
1305
                && (0 == strcasecmp(itemObj->valuestring, "yes"))) {
1✔
1306
            superTable->writeFuture = true;
1✔
1307
        }
1308

1309
        // check_correct_interval
1310
        itemObj = tools_cJSON_GetObjectItem(stbInfo, "check_correct_interval");
151✔
1311
        if (tools_cJSON_IsNumber(itemObj)) {
151✔
1312
            superTable->checkInterval = itemObj->valueint;
1✔
1313
        }
1314

1315
        tools_cJSON *insertInterval =
1316
            tools_cJSON_GetObjectItem(stbInfo, "insert_interval");
151✔
1317
        if (tools_cJSON_IsNumber(insertInterval)) {
151✔
1318
            superTable->insert_interval = insertInterval->valueint;
138✔
1319
        }
1320

1321
        tools_cJSON *pPartialColNum =
1322
            tools_cJSON_GetObjectItem(stbInfo, "partial_col_num");
151✔
1323
        if (tools_cJSON_IsNumber(pPartialColNum)) {
151✔
1324
            superTable->partialColNum = pPartialColNum->valueint;
26✔
1325
        }
1326

1327
        tools_cJSON *pPartialColFrom =
1328
            tools_cJSON_GetObjectItem(stbInfo, "partial_col_from");
151✔
1329
        if (tools_cJSON_IsNumber(pPartialColFrom)) {
151✔
1330
            superTable->partialColFrom = pPartialColFrom->valueint;
×
1331
        }
1332

1333
        if (g_arguments->taosc_version == 3) {
151✔
1334
            tools_cJSON *delay = tools_cJSON_GetObjectItem(stbInfo, "delay");
151✔
1335
            if (tools_cJSON_IsNumber(delay)) {
151✔
1336
                superTable->delay = (int)delay->valueint;
×
1337
            }
1338

1339
            tools_cJSON *file_factor =
1340
                tools_cJSON_GetObjectItem(stbInfo, "file_factor");
151✔
1341
            if (tools_cJSON_IsNumber(file_factor)) {
151✔
1342
                superTable->file_factor = (int)file_factor->valueint;
×
1343
            }
1344

1345
            tools_cJSON *rollup = tools_cJSON_GetObjectItem(stbInfo, "rollup");
151✔
1346
            if (tools_cJSON_IsString(rollup)) {
151✔
1347
                superTable->rollup = rollup->valuestring;
×
1348
            }
1349

1350
            tools_cJSON *ttl = tools_cJSON_GetObjectItem(stbInfo, "ttl");
151✔
1351
            if (tools_cJSON_IsNumber(ttl)) {
151✔
1352
                superTable->ttl = (int)ttl->valueint;
7✔
1353
            }
1354

1355
            tools_cJSON *max_delay_obj =
1356
                tools_cJSON_GetObjectItem(stbInfo, "max_delay");
151✔
1357
            if (tools_cJSON_IsString(max_delay_obj)) {
151✔
1358
                superTable->max_delay = max_delay_obj->valuestring;
×
1359
            }
1360

1361
            tools_cJSON *watermark_obj =
1362
                tools_cJSON_GetObjectItem(stbInfo, "watermark");
151✔
1363
            if (tools_cJSON_IsString(watermark_obj)) {
151✔
1364
                superTable->watermark = watermark_obj->valuestring;
×
1365
            }
1366

1367
            if (get_tsma_info(stbInfo, superTable)) {
151✔
1368
                return -1;
×
1369
            }
1370
        }
1371

1372
        if (getColumnAndTagTypeFromInsertJsonFile(stbInfo, superTable)) {
151✔
1373
            return -1;
×
1374
        }
1375

1376
        // primary key
1377
        itemObj = tools_cJSON_GetObjectItem(stbInfo, "primary_key");
151✔
1378
        if (tools_cJSON_IsNumber(itemObj)) {
151✔
1379
            superTable->primary_key = itemObj->valueint == 1;
1✔
1380
        }
1381
        // repeat_ts_min
1382
        itemObj = tools_cJSON_GetObjectItem(stbInfo, "repeat_ts_min");
151✔
1383
        if (tools_cJSON_IsNumber(itemObj)) {
151✔
1384
            superTable->repeat_ts_min = (int)itemObj->valueint;
1✔
1385
        }
1386
        // repeat_ts_max
1387
        itemObj = tools_cJSON_GetObjectItem(stbInfo, "repeat_ts_max");
151✔
1388
        if (tools_cJSON_IsNumber(itemObj)) {
151✔
1389
            superTable->repeat_ts_max = (int)itemObj->valueint;
1✔
1390
        }
1391

1392
        // sqls
1393
        itemObj = tools_cJSON_GetObjectItem(stbInfo, "sqls");
151✔
1394
        if (tools_cJSON_IsArray(itemObj)) {
151✔
1395
            int cnt = tools_cJSON_GetArraySize(itemObj);
×
1396
            if(cnt > 0) {
×
1397
                char ** sqls = (char **)benchCalloc(cnt + 1, sizeof(char *), false); // +1 add end
×
1398
                superTable->sqls = sqls;
×
1399
                for(int j = 0; j < cnt; j++) {
×
1400
                    tools_cJSON *sqlObj = tools_cJSON_GetArrayItem(itemObj, j);
×
1401
                    if(sqlObj && tools_cJSON_IsString(sqlObj)) {
×
1402
                        *sqls = strdup(sqlObj->valuestring);
×
1403
                        sqls++;
×
1404
                    }
1405
                }
1406
            }
1407
        }
1408
    }
1409
    return 0;
82✔
1410
}
1411

1412
static int getStreamInfo(tools_cJSON* json) {
82✔
1413
    tools_cJSON* streamsObj = tools_cJSON_GetObjectItem(json, "streams");
82✔
1414
    if (tools_cJSON_IsArray(streamsObj)) {
82✔
1415
        int streamCnt = tools_cJSON_GetArraySize(streamsObj);
2✔
1416
        for (int i = 0; i < streamCnt; ++i) {
4✔
1417
            tools_cJSON* streamObj = tools_cJSON_GetArrayItem(streamsObj, i);
2✔
1418
            if (!tools_cJSON_IsObject(streamObj)) {
2✔
1419
                errorPrint("%s", "invalid stream format in json\n");
×
1420
                return -1;
×
1421
            }
1422
            tools_cJSON* stream_name =
1423
                tools_cJSON_GetObjectItem(streamObj, "stream_name");
2✔
1424
            tools_cJSON* stream_stb =
1425
                tools_cJSON_GetObjectItem(streamObj, "stream_stb");
2✔
1426
            tools_cJSON* source_sql =
1427
                tools_cJSON_GetObjectItem(streamObj, "source_sql");
2✔
1428
            if (!tools_cJSON_IsString(stream_name)
2✔
1429
                || !tools_cJSON_IsString(stream_stb)
2✔
1430
                || !tools_cJSON_IsString(source_sql)) {
2✔
1431
                errorPrint("%s", "Invalid or miss "
×
1432
                           "'stream_name'/'stream_stb'/'source_sql' "
1433
                           "key in json\n");
1434
                return -1;
×
1435
            }
1436
            SSTREAM * stream = benchCalloc(1, sizeof(SSTREAM), true);
2✔
1437
            tstrncpy(stream->stream_name, stream_name->valuestring,
2✔
1438
                     TSDB_TABLE_NAME_LEN);
1439
            tstrncpy(stream->stream_stb, stream_stb->valuestring,
2✔
1440
                     TSDB_TABLE_NAME_LEN);
1441
            tstrncpy(stream->source_sql, source_sql->valuestring,
2✔
1442
                     TSDB_DEFAULT_PKT_SIZE);
1443

1444
            tools_cJSON* trigger_mode =
1445
                tools_cJSON_GetObjectItem(streamObj, "trigger_mode");
2✔
1446
            if (tools_cJSON_IsString(trigger_mode)) {
2✔
1447
                tstrncpy(stream->trigger_mode, trigger_mode->valuestring,
1✔
1448
                         BIGINT_BUFF_LEN);
1449
            }
1450

1451
            tools_cJSON* watermark =
1452
                tools_cJSON_GetObjectItem(streamObj, "watermark");
2✔
1453
            if (tools_cJSON_IsString(watermark)) {
2✔
1454
                tstrncpy(stream->watermark, watermark->valuestring,
1✔
1455
                         BIGINT_BUFF_LEN);
1456
            }
1457

1458
            tools_cJSON* ignore_expired =
1459
                tools_cJSON_GetObjectItem(streamObj, "ignore_expired");
2✔
1460
            if (tools_cJSON_IsString(ignore_expired)) {
2✔
1461
                tstrncpy(stream->ignore_expired, ignore_expired->valuestring,
1✔
1462
                         BIGINT_BUFF_LEN);
1463
            }
1464

1465
            tools_cJSON* ignore_update =
1466
                tools_cJSON_GetObjectItem(streamObj, "ignore_update");
2✔
1467
            if (tools_cJSON_IsString(ignore_update)) {
2✔
1468
                tstrncpy(stream->ignore_update, ignore_update->valuestring,
1✔
1469
                         BIGINT_BUFF_LEN);
1470
            }
1471

1472
            tools_cJSON* fill_history =
1473
                tools_cJSON_GetObjectItem(streamObj, "fill_history");
2✔
1474
            if (tools_cJSON_IsString(fill_history)) {
2✔
1475
                tstrncpy(stream->fill_history, fill_history->valuestring,
1✔
1476
                         BIGINT_BUFF_LEN);
1477
            }
1478

1479
            tools_cJSON* stream_stb_field =
1480
                tools_cJSON_GetObjectItem(streamObj, "stream_stb_field");
2✔
1481
            if (tools_cJSON_IsString(stream_stb_field)) {
2✔
1482
                tstrncpy(stream->stream_stb_field,
1✔
1483
                         stream_stb_field->valuestring,
1484
                         TSDB_DEFAULT_PKT_SIZE);
1485
            }
1486

1487
            tools_cJSON* stream_tag_field =
1488
                tools_cJSON_GetObjectItem(streamObj, "stream_tag_field");
2✔
1489
            if (tools_cJSON_IsString(stream_tag_field)) {
2✔
1490
                tstrncpy(stream->stream_tag_field,
1✔
1491
                         stream_tag_field->valuestring,
1492
                         TSDB_DEFAULT_PKT_SIZE);
1493
            }
1494

1495
            tools_cJSON* subtable =
1496
                tools_cJSON_GetObjectItem(streamObj, "subtable");
2✔
1497
            if (tools_cJSON_IsString(subtable)) {
2✔
1498
                tstrncpy(stream->subtable, subtable->valuestring,
1✔
1499
                         TSDB_DEFAULT_PKT_SIZE);
1500
            }
1501

1502
            tools_cJSON* drop = tools_cJSON_GetObjectItem(streamObj, "drop");
2✔
1503
            if (tools_cJSON_IsString(drop)) {
2✔
1504
                if (0 == strcasecmp(drop->valuestring, "yes")) {
2✔
1505
                    stream->drop = true;
2✔
1506
                } else if (0 == strcasecmp(drop->valuestring, "no")) {
×
1507
                    stream->drop = false;
×
1508
                } else {
1509
                    errorPrint("invalid value for drop field: %s\n",
×
1510
                               drop->valuestring);
1511
                    return -1;
×
1512
                }
1513
            }
1514
            benchArrayPush(g_arguments->streams, stream);
2✔
1515
        }
1516
    }
1517
    return 0;
82✔
1518
}
1519

1520
// read common item
1521
static int getMetaFromCommonJsonFile(tools_cJSON *json) {
117✔
1522
    int32_t code = -1;
117✔
1523
    tools_cJSON *cfgdir = tools_cJSON_GetObjectItem(json, "cfgdir");
117✔
1524
    if (cfgdir && (cfgdir->type == tools_cJSON_String)
117✔
1525
            && (cfgdir->valuestring != NULL)) {
116✔
1526
        tstrncpy(g_configDir, cfgdir->valuestring, MAX_FILE_NAME_LEN);
116✔
1527
    }
1528

1529
    tools_cJSON *host = tools_cJSON_GetObjectItem(json, "host");
117✔
1530
    if (host && host->type == tools_cJSON_String && host->valuestring != NULL) {
117✔
1531
        if(g_arguments->host && strlen(g_arguments->host) > 0) {
114✔
1532
            warnPrint("command line already pass host is %s, json config host(%s) had been ignored.\n", g_arguments->host, host->valuestring);
×
1533
        } else {
1534
            g_arguments->host = host->valuestring;
114✔
1535
        }     
1536
    }
1537

1538
    tools_cJSON *port = tools_cJSON_GetObjectItem(json, "port");
117✔
1539
    if (port && port->type == tools_cJSON_Number) {
117✔
1540
        if(g_arguments->port != DEFAULT_PORT) {
110✔
1541
            warnPrint("command line already pass port is %d, json config port(%d) had been ignored.\n", g_arguments->port, (uint16_t)port->valueint);
×
1542
        } else {
1543
            g_arguments->port = (uint16_t)port->valueint;
110✔
1544
            if(g_arguments->port != DEFAULT_PORT) {
110✔
1545
                infoPrint("json file config special port %d .\n", g_arguments->port);
×
1546
                g_arguments->port_inputted = true;
×
1547
            }
1548
        }
1549
    }
1550

1551
    tools_cJSON *user = tools_cJSON_GetObjectItem(json, "user");
117✔
1552
    if (user && user->type == tools_cJSON_String && user->valuestring != NULL) {
117✔
1553
        g_arguments->user = user->valuestring;
114✔
1554
    }
1555

1556
    tools_cJSON *password = tools_cJSON_GetObjectItem(json, "password");
117✔
1557
    if (password && password->type == tools_cJSON_String &&
117✔
1558
        password->valuestring != NULL) {
114✔
1559
        g_arguments->password = password->valuestring;
114✔
1560
    }
1561

1562
    tools_cJSON *answerPrompt =
1563
        tools_cJSON_GetObjectItem(json,
117✔
1564
                                  "confirm_parameter_prompt");  // yes, no,
1565
    if (answerPrompt && answerPrompt->type == tools_cJSON_String
117✔
1566
            && answerPrompt->valuestring != NULL) {
116✔
1567
        if (0 == strcasecmp(answerPrompt->valuestring, "no")) {
116✔
1568
            g_arguments->answer_yes = true;
116✔
1569
        }
1570
    }
1571

1572
    // read from common
1573
    tools_cJSON *continueIfFail =
1574
        tools_cJSON_GetObjectItem(json, "continue_if_fail");  // yes, no,
117✔
1575
    if (tools_cJSON_IsString(continueIfFail)) {
117✔
1576
        if (0 == strcasecmp(continueIfFail->valuestring, "no")) {
13✔
1577
            g_arguments->continueIfFail = NO_IF_FAILED;
6✔
1578
        } else if (0 == strcasecmp(continueIfFail->valuestring, "yes")) {
7✔
1579
            g_arguments->continueIfFail = YES_IF_FAILED;
7✔
1580
        } else if (0 == strcasecmp(continueIfFail->valuestring, "smart")) {
×
1581
            g_arguments->continueIfFail = SMART_IF_FAILED;
×
1582
        } else {
1583
            errorPrint("cointinue_if_fail has unknown mode %s\n",
×
1584
                       continueIfFail->valuestring);
1585
            return -1;
×
1586
        }
1587
    }
1588

1589
    g_arguments->csvPath[0] = 0;
117✔
1590
    tools_cJSON *csv = tools_cJSON_GetObjectItem(json, "csvPath");
117✔
1591
    if (csv && (csv->type == tools_cJSON_String)
117✔
1592
            && (csv->valuestring != NULL)) {
1✔
1593
        tstrncpy(g_arguments->csvPath, csv->valuestring, MAX_FILE_NAME_LEN);
1✔
1594
    }
1595

1596
    size_t len = strlen(g_arguments->csvPath);
117✔
1597

1598
    if(len == 0) {
117✔
1599
        // set default with current path
1600
        strcpy(g_arguments->csvPath, "./output/");
116✔
1601
        mkdir(g_arguments->csvPath, 0775);
116✔
1602
    } else {
1603
        // append end
1604
        if (g_arguments->csvPath[len-1] != '/' ) {
1✔
1605
            strcat(g_arguments->csvPath, "/");
×
1606
        }
1607
        mkdir(g_arguments->csvPath, 0775);
1✔
1608
    }
1609

1610
    code = 0;
117✔
1611
    return code;
117✔
1612
}
1613

1614
static int getMetaFromInsertJsonFile(tools_cJSON *json) {
82✔
1615
    int32_t code = -1;
82✔
1616

1617
#ifdef WEBSOCKET
1618
    tools_cJSON *dsn = tools_cJSON_GetObjectItem(json, "dsn");
82✔
1619
    if (tools_cJSON_IsString(dsn)) {
82✔
1620
        g_arguments->dsn = dsn->valuestring;
2✔
1621
        g_arguments->websocket = true;
2✔
1622
        infoPrint("set websocket true from json->dsn=%s\n", g_arguments->dsn);
2✔
1623
    }
1624
#endif
1625

1626
    // check after inserted
1627
    tools_cJSON *checkSql = tools_cJSON_GetObjectItem(json, "check_sql");
82✔
1628
    if (tools_cJSON_IsString(checkSql)) {
82✔
1629
        if (0 == strcasecmp(checkSql->valuestring, "yes")) {
3✔
1630
            g_arguments->check_sql = true;
2✔
1631
        }
1632
    }
1633

1634
    g_arguments->pre_load_tb_meta = false;
82✔
1635
    tools_cJSON *preLoad = tools_cJSON_GetObjectItem(json, "pre_load_tb_meta");
82✔
1636
    if (tools_cJSON_IsString(preLoad)) {
82✔
1637
        if (0 == strcasecmp(preLoad->valuestring, "yes")) {
×
1638
            g_arguments->pre_load_tb_meta = true;
×
1639
        }
1640
    }
1641

1642
    tools_cJSON *resultfile = tools_cJSON_GetObjectItem(json, "result_file");
82✔
1643
    if (resultfile && resultfile->type == tools_cJSON_String
82✔
1644
            && resultfile->valuestring != NULL) {
74✔
1645
        g_arguments->output_file = resultfile->valuestring;
74✔
1646
    }
1647

1648
    tools_cJSON *threads = tools_cJSON_GetObjectItem(json, "thread_count");
82✔
1649
    if (threads && threads->type == tools_cJSON_Number) {
82✔
1650
        if(!(g_argFlag & ARG_OPT_THREAD)) {
81✔
1651
            // only command line no -T use json value
1652
            g_arguments->nthreads = (uint32_t)threads->valueint;
80✔
1653
        }
1654
    }
1655

1656
    tools_cJSON *bindVGroup = tools_cJSON_GetObjectItem(json, "thread_bind_vgroup");
82✔
1657
    if (tools_cJSON_IsString(bindVGroup)) {
82✔
1658
        if (0 == strcasecmp(bindVGroup->valuestring, "yes")) {
6✔
1659
            g_arguments->bind_vgroup = true;
4✔
1660
        }
1661
    }
1662

1663
    tools_cJSON *keepTrying = tools_cJSON_GetObjectItem(json, "keep_trying");
82✔
1664
    if (keepTrying && keepTrying->type == tools_cJSON_Number) {
82✔
1665
        g_arguments->keep_trying = (int32_t)keepTrying->valueint;
1✔
1666
    }
1667

1668
    tools_cJSON *tryingInterval =
1669
        tools_cJSON_GetObjectItem(json, "trying_interval");
82✔
1670
    if (tryingInterval && tryingInterval->type == tools_cJSON_Number) {
82✔
1671
        g_arguments->trying_interval = (uint32_t)tryingInterval->valueint;
1✔
1672
    }
1673

1674
    tools_cJSON *table_theads =
1675
        tools_cJSON_GetObjectItem(json, "create_table_thread_count");
82✔
1676
    if (tools_cJSON_IsNumber(table_theads)) {
82✔
1677
        g_arguments->table_threads = (uint32_t)table_theads->valueint;
31✔
1678
    }
1679

1680
#ifdef WEBSOCKET
1681
    if (!g_arguments->websocket) {
82✔
1682
#endif
1683
#ifdef LINUX
1684
    if (strlen(g_configDir)) {
80✔
1685
        wordexp_t full_path;
1686
        if (wordexp(g_configDir, &full_path, 0) != 0) {
79✔
1687
            errorPrint("Invalid path %s\n", g_configDir);
×
1688
            exit(EXIT_FAILURE);
×
1689
        }
1690
        taos_options(TSDB_OPTION_CONFIGDIR, full_path.we_wordv[0]);
79✔
1691
        wordfree(&full_path);
79✔
1692
    }
1693
#endif
1694
#ifdef WEBSOCKET
1695
    }
1696
#endif
1697

1698
    tools_cJSON *numRecPerReq =
1699
        tools_cJSON_GetObjectItem(json, "num_of_records_per_req");
82✔
1700
    if (numRecPerReq && numRecPerReq->type == tools_cJSON_Number) {
82✔
1701
        g_arguments->reqPerReq = (uint32_t)numRecPerReq->valueint;
82✔
1702
        if ((int32_t)g_arguments->reqPerReq <= 0) {
82✔
1703
            infoPrint("waring: num_of_records_per_req item in json config must over zero, current = %d. now reset to default. \n", g_arguments->reqPerReq);
×
1704
            g_arguments->reqPerReq = DEFAULT_REQ_PER_REQ;
×
1705
        }
1706

1707
        if (g_arguments->reqPerReq > INT32_MAX) {
82✔
1708
            infoPrint("warning: num_of_records_per_req item in json config need less than 32768. current = %d. now reset to default.\n", g_arguments->reqPerReq);
×
1709
            g_arguments->reqPerReq = DEFAULT_REQ_PER_REQ;
×
1710
        }
1711

1712
    }
1713

1714
    tools_cJSON *prepareRand =
1715
        tools_cJSON_GetObjectItem(json, "prepared_rand");
82✔
1716
    if (prepareRand && prepareRand->type == tools_cJSON_Number) {
82✔
1717
        g_arguments->prepared_rand = prepareRand->valueint;
54✔
1718
    }
1719

1720
    tools_cJSON *chineseOpt =
1721
        tools_cJSON_GetObjectItem(json, "chinese");  // yes, no,
82✔
1722
    if (chineseOpt && chineseOpt->type == tools_cJSON_String
82✔
1723
            && chineseOpt->valuestring != NULL) {
54✔
1724
        if (0 == strncasecmp(chineseOpt->valuestring, "yes", 3)) {
54✔
1725
            g_arguments->chinese = true;
5✔
1726
        }
1727
    }
1728

1729
    tools_cJSON *escapeChar =
1730
        tools_cJSON_GetObjectItem(json, "escape_character");  // yes, no,
82✔
1731
    if (escapeChar && escapeChar->type == tools_cJSON_String
82✔
1732
            && escapeChar->valuestring != NULL) {
7✔
1733
        if (0 == strncasecmp(escapeChar->valuestring, "yes", 3)) {
7✔
1734
            g_arguments->escape_character = true;
7✔
1735
        }
1736
    }
1737

1738
    tools_cJSON *top_insertInterval =
1739
        tools_cJSON_GetObjectItem(json, "insert_interval");
82✔
1740
    if (top_insertInterval && top_insertInterval->type == tools_cJSON_Number) {
82✔
1741
        g_arguments->insert_interval = top_insertInterval->valueint;
66✔
1742
    }
1743

1744
    tools_cJSON *insert_mode = tools_cJSON_GetObjectItem(json, "insert_mode");
82✔
1745
    if (insert_mode && insert_mode->type == tools_cJSON_String
82✔
1746
            && insert_mode->valuestring != NULL) {
1✔
1747
        g_arguments->iface = getInterface(insert_mode->valuestring);
1✔
1748
    }
1749

1750
    tools_cJSON *dbinfos = tools_cJSON_GetObjectItem(json, "databases");
82✔
1751
    if (!tools_cJSON_IsArray(dbinfos)) {
82✔
1752
        errorPrint("%s", "Invalid databases format in json\n");
×
1753
        return -1;
×
1754
    }
1755
    int dbSize = tools_cJSON_GetArraySize(dbinfos);
82✔
1756

1757
    for (int i = 0; i < dbSize; ++i) {
165✔
1758
        if (getDatabaseInfo(dbinfos, i)) {
83✔
1759
            goto PARSE_OVER;
×
1760
        }
1761
        if (getStableInfo(dbinfos, i)) {
83✔
1762
            goto PARSE_OVER;
×
1763
        }
1764
    }
1765

1766
    if (g_arguments->taosc_version == 3) {
82✔
1767
        if (getStreamInfo(json)) {
82✔
1768
            goto PARSE_OVER;
×
1769
        }
1770
    }
1771

1772
    code = 0;
82✔
1773

1774
PARSE_OVER:
82✔
1775
    return code;
82✔
1776
}
1777

1778
// Spec Query
1779
int32_t readSpecQueryJson(tools_cJSON * specifiedQuery) {
19✔
1780
    g_queryInfo.specifiedQueryInfo.concurrent = 1;
19✔
1781
    if (tools_cJSON_IsObject(specifiedQuery)) {
19✔
1782
        tools_cJSON *queryInterval =
1783
            tools_cJSON_GetObjectItem(specifiedQuery, "query_interval");
19✔
1784
        if (tools_cJSON_IsNumber(queryInterval)) {
19✔
1785
            g_queryInfo.specifiedQueryInfo.queryInterval =
11✔
1786
                queryInterval->valueint;
11✔
1787
        } else {
1788
            g_queryInfo.specifiedQueryInfo.queryInterval = 0;
8✔
1789
        }
1790

1791
        tools_cJSON *specifiedQueryTimes =
1792
            tools_cJSON_GetObjectItem(specifiedQuery, "query_times");
19✔
1793
        if (tools_cJSON_IsNumber(specifiedQueryTimes)) {
19✔
1794
            g_queryInfo.specifiedQueryInfo.queryTimes =
1✔
1795
                specifiedQueryTimes->valueint;
1✔
1796
        } else {
1797
            g_queryInfo.specifiedQueryInfo.queryTimes = g_queryInfo.query_times;
18✔
1798
        }
1799

1800
        tools_cJSON *mixedQueryObj =
1801
            tools_cJSON_GetObjectItem(specifiedQuery, "mixed_query");
19✔
1802
        if (tools_cJSON_IsString(mixedQueryObj)) {
19✔
1803
            if (0 == strcasecmp(mixedQueryObj->valuestring, "yes")) {
5✔
1804
                g_queryInfo.specifiedQueryInfo.mixed_query = true;
4✔
1805
                infoPrint("%s\n","mixed_query is True");
4✔
1806
            } else if (0 == strcasecmp(mixedQueryObj->valuestring, "no")) {
1✔
1807
                g_queryInfo.specifiedQueryInfo.mixed_query = false;
1✔
1808
                infoPrint("%s\n","mixed_query is False");
1✔
1809
            } else {
1810
                errorPrint("Invalid mixed_query value: %s\n",
×
1811
                           mixedQueryObj->valuestring);
NEW
1812
                return -1;
×
1813
            }
1814
        }
1815

1816
        tools_cJSON *concurrent =
1817
            tools_cJSON_GetObjectItem(specifiedQuery, "concurrent");
19✔
1818
        if (tools_cJSON_IsNumber(concurrent)) {
19✔
1819
            g_queryInfo.specifiedQueryInfo.concurrent =
8✔
1820
                (uint32_t)concurrent->valueint;
8✔
1821
        }
1822

1823
        tools_cJSON *threads =
1824
            tools_cJSON_GetObjectItem(specifiedQuery, "threads");
19✔
1825
        if (tools_cJSON_IsNumber(threads)) {
19✔
1826
            g_queryInfo.specifiedQueryInfo.concurrent =
10✔
1827
                (uint32_t)threads->valueint;
10✔
1828
        }
1829

1830
        tools_cJSON *specifiedAsyncMode =
1831
            tools_cJSON_GetObjectItem(specifiedQuery, "mode");
19✔
1832
        if (tools_cJSON_IsString(specifiedAsyncMode)) {
19✔
1833
            if (0 == strcmp("async", specifiedAsyncMode->valuestring)) {
×
1834
                g_queryInfo.specifiedQueryInfo.asyncMode = ASYNC_MODE;
×
1835
            } else {
1836
                g_queryInfo.specifiedQueryInfo.asyncMode = SYNC_MODE;
×
1837
            }
1838
        } else {
1839
            g_queryInfo.specifiedQueryInfo.asyncMode = SYNC_MODE;
19✔
1840
        }
1841

1842
        tools_cJSON *subscribe_interval =
1843
            tools_cJSON_GetObjectItem(specifiedQuery, "subscribe_interval");
19✔
1844
        if (tools_cJSON_IsNumber(subscribe_interval)) {
19✔
1845
            g_queryInfo.specifiedQueryInfo.subscribeInterval =
×
1846
                subscribe_interval->valueint;
×
1847
        } else {
1848
            g_queryInfo.specifiedQueryInfo.subscribeInterval =
19✔
1849
                DEFAULT_SUB_INTERVAL;
1850
        }
1851

1852
        tools_cJSON *specifiedSubscribeTimes =
1853
            tools_cJSON_GetObjectItem(specifiedQuery, "subscribe_times");
19✔
1854
        if (tools_cJSON_IsNumber(specifiedSubscribeTimes)) {
19✔
1855
            g_queryInfo.specifiedQueryInfo.subscribeTimes =
×
1856
                specifiedSubscribeTimes->valueint;
×
1857
        } else {
1858
            g_queryInfo.specifiedQueryInfo.subscribeTimes =
19✔
1859
                g_queryInfo.query_times;
19✔
1860
        }
1861

1862
        tools_cJSON *restart =
1863
            tools_cJSON_GetObjectItem(specifiedQuery, "restart");
19✔
1864
        if (tools_cJSON_IsString(restart)) {
19✔
1865
            if (0 == strcmp("no", restart->valuestring)) {
×
1866
                g_queryInfo.specifiedQueryInfo.subscribeRestart = false;
×
1867
            } else {
1868
                g_queryInfo.specifiedQueryInfo.subscribeRestart = true;
×
1869
            }
1870
        } else {
1871
            g_queryInfo.specifiedQueryInfo.subscribeRestart = true;
19✔
1872
        }
1873

1874
        tools_cJSON *keepProgress =
1875
            tools_cJSON_GetObjectItem(specifiedQuery, "keepProgress");
19✔
1876
        if (tools_cJSON_IsString(keepProgress)) {
19✔
1877
            if (0 == strcmp("yes", keepProgress->valuestring)) {
×
1878
                g_queryInfo.specifiedQueryInfo.subscribeKeepProgress = 1;
×
1879
            } else {
1880
                g_queryInfo.specifiedQueryInfo.subscribeKeepProgress = 0;
×
1881
            }
1882
        } else {
1883
            g_queryInfo.specifiedQueryInfo.subscribeKeepProgress = 0;
19✔
1884
        }
1885

1886
        // read sqls from file
1887
        tools_cJSON *sqlFileObj =
1888
            tools_cJSON_GetObjectItem(specifiedQuery, "sql_file");
19✔
1889
        if (tools_cJSON_IsString(sqlFileObj)) {
19✔
1890
            FILE * fp = fopen(sqlFileObj->valuestring, "r");
2✔
1891
            if (fp == NULL) {
2✔
1892
                errorPrint("failed to open file: %s\n",
×
1893
                           sqlFileObj->valuestring);
NEW
1894
                return -1;
×
1895
            }
1896
            char *buf = benchCalloc(1, TSDB_MAX_ALLOWED_SQL_LEN, true);
2✔
1897
            while (fgets(buf, TSDB_MAX_ALLOWED_SQL_LEN, fp)) {
7✔
1898
                SSQL * sql = benchCalloc(1, sizeof(SSQL), true);
5✔
1899
                benchArrayPush(g_queryInfo.specifiedQueryInfo.sqls, sql);
5✔
1900
                sql = benchArrayGet(g_queryInfo.specifiedQueryInfo.sqls,
5✔
1901
                        g_queryInfo.specifiedQueryInfo.sqls->size - 1);
5✔
1902
                int bufLen = strlen(buf) + 1;
5✔
1903
                sql->command = benchCalloc(1, bufLen, true);
5✔
1904
                sql->delay_list = benchCalloc(
10✔
1905
                        g_queryInfo.specifiedQueryInfo.queryTimes
5✔
1906
                        * g_queryInfo.specifiedQueryInfo.concurrent,
5✔
1907
                        sizeof(int64_t), true);
1908
                tstrncpy(sql->command, buf, bufLen - 1);
5✔
1909
                debugPrint("read file buffer: %s\n", sql->command);
5✔
1910
                memset(buf, 0, TSDB_MAX_ALLOWED_SQL_LEN);
5✔
1911
            }
1912
            free(buf);
2✔
1913
            fclose(fp);
2✔
1914
        }
1915
        // sqls
1916
        tools_cJSON *specifiedSqls =
1917
            tools_cJSON_GetObjectItem(specifiedQuery, "sqls");
19✔
1918
        if (tools_cJSON_IsArray(specifiedSqls)) {
19✔
1919
            int specifiedSqlSize = tools_cJSON_GetArraySize(specifiedSqls);
17✔
1920
            for (int j = 0; j < specifiedSqlSize; ++j) {
247✔
1921
                tools_cJSON *sqlObj =
1922
                    tools_cJSON_GetArrayItem(specifiedSqls, j);
230✔
1923
                if (tools_cJSON_IsObject(sqlObj)) {
230✔
1924
                    SSQL * sql = benchCalloc(1, sizeof(SSQL), true);
230✔
1925
                    benchArrayPush(g_queryInfo.specifiedQueryInfo.sqls, sql);
230✔
1926
                    sql = benchArrayGet(g_queryInfo.specifiedQueryInfo.sqls,
230✔
1927
                            g_queryInfo.specifiedQueryInfo.sqls->size -1);
230✔
1928
                    sql->delay_list = benchCalloc(
460✔
1929
                            g_queryInfo.specifiedQueryInfo.queryTimes
230✔
1930
                            * g_queryInfo.specifiedQueryInfo.concurrent,
230✔
1931
                            sizeof(int64_t), true);
1932

1933
                    tools_cJSON *sqlStr =
1934
                        tools_cJSON_GetObjectItem(sqlObj, "sql");
230✔
1935
                    if (tools_cJSON_IsString(sqlStr)) {
230✔
1936
                        int strLen = strlen(sqlStr->valuestring) + 1;
230✔
1937
                        sql->command = benchCalloc(1, strLen, true);
230✔
1938
                        tstrncpy(sql->command, sqlStr->valuestring, strLen);
230✔
1939
                        // default value is -1, which mean infinite loop
1940
                        g_queryInfo.specifiedQueryInfo.endAfterConsume[j] = -1;
230✔
1941
                        tools_cJSON *endAfterConsume =
1942
                            tools_cJSON_GetObjectItem(specifiedQuery,
230✔
1943
                                                      "endAfterConsume");
1944
                        if (tools_cJSON_IsNumber(endAfterConsume)) {
230✔
1945
                            g_queryInfo.specifiedQueryInfo.endAfterConsume[j] =
×
1946
                                (int)endAfterConsume->valueint;
×
1947
                        }
1948
                        if (g_queryInfo.specifiedQueryInfo
230✔
1949
                                .endAfterConsume[j] < -1) {
230✔
1950
                            g_queryInfo.specifiedQueryInfo
1951
                                .endAfterConsume[j] = -1;
×
1952
                        }
1953

1954
                        g_queryInfo.specifiedQueryInfo
1955
                                .resubAfterConsume[j] = -1;
230✔
1956
                        tools_cJSON *resubAfterConsume =
1957
                            tools_cJSON_GetObjectItem(
230✔
1958
                                    specifiedQuery, "resubAfterConsume");
1959
                        if (tools_cJSON_IsNumber(resubAfterConsume)) {
230✔
1960
                            g_queryInfo.specifiedQueryInfo.resubAfterConsume[j]
1961
                                = (int)resubAfterConsume->valueint;
×
1962
                        }
1963

1964
                        if (g_queryInfo.specifiedQueryInfo
230✔
1965
                                .resubAfterConsume[j] < -1)
230✔
1966
                            g_queryInfo.specifiedQueryInfo
1967
                                    .resubAfterConsume[j] = -1;
×
1968

1969
                        tools_cJSON *result =
1970
                            tools_cJSON_GetObjectItem(sqlObj, "result");
230✔
1971
                        if (tools_cJSON_IsString(result)) {
230✔
1972
                            tstrncpy(sql->result, result->valuestring,
219✔
1973
                                     MAX_FILE_NAME_LEN);
1974
                        } else {
1975
                            memset(sql->result, 0, MAX_FILE_NAME_LEN);
11✔
1976
                        }
1977
                    } else {
1978
                        errorPrint("%s", "Invalid sql in json\n");
×
NEW
1979
                        return -1;
×
1980
                    }
1981
                }
1982
            }
1983
        }
1984
    }
1985

1986
    // succ
1987
    return 0;
19✔
1988
}
1989

1990
// Super Query
1991
int32_t readSuperQueryJson(tools_cJSON * superQuery) {
12✔
1992
    g_queryInfo.superQueryInfo.threadCnt = 1;
12✔
1993
    if (!superQuery || superQuery->type != tools_cJSON_Object) {
12✔
UNCOV
1994
        g_queryInfo.superQueryInfo.sqlCount = 0;
×
1995
    } else {
1996
        tools_cJSON *subrate =
1997
            tools_cJSON_GetObjectItem(superQuery, "query_interval");
12✔
1998
        if (subrate && subrate->type == tools_cJSON_Number) {
12✔
1999
            g_queryInfo.superQueryInfo.queryInterval = subrate->valueint;
11✔
2000
        } else {
2001
            g_queryInfo.superQueryInfo.queryInterval = 0;
1✔
2002
        }
2003

2004
        tools_cJSON *superQueryTimes =
2005
            tools_cJSON_GetObjectItem(superQuery, "query_times");
12✔
2006
        if (superQueryTimes && superQueryTimes->type == tools_cJSON_Number) {
12✔
2007
            g_queryInfo.superQueryInfo.queryTimes = superQueryTimes->valueint;
×
2008
        } else {
2009
            g_queryInfo.superQueryInfo.queryTimes = g_queryInfo.query_times;
12✔
2010
        }
2011

2012
        tools_cJSON *concurrent =
2013
            tools_cJSON_GetObjectItem(superQuery, "concurrent");
12✔
2014
        if (concurrent && concurrent->type == tools_cJSON_Number) {
12✔
2015
            g_queryInfo.superQueryInfo.threadCnt =
4✔
2016
                (uint32_t)concurrent->valueint;
4✔
2017
        }
2018

2019
        tools_cJSON *threads = tools_cJSON_GetObjectItem(superQuery, "threads");
12✔
2020
        if (threads && threads->type == tools_cJSON_Number) {
12✔
2021
            g_queryInfo.superQueryInfo.threadCnt = (uint32_t)threads->valueint;
7✔
2022
        }
2023

2024
        tools_cJSON *stblname =
2025
            tools_cJSON_GetObjectItem(superQuery, "stblname");
12✔
2026
        if (stblname && stblname->type == tools_cJSON_String
12✔
2027
                && stblname->valuestring != NULL) {
12✔
2028
            tstrncpy(g_queryInfo.superQueryInfo.stbName,
12✔
2029
                     stblname->valuestring,
2030
                     TSDB_TABLE_NAME_LEN);
2031
        }
2032

2033
        tools_cJSON *superAsyncMode =
2034
            tools_cJSON_GetObjectItem(superQuery, "mode");
12✔
2035
        if (superAsyncMode && superAsyncMode->type == tools_cJSON_String
12✔
2036
                && superAsyncMode->valuestring != NULL) {
×
2037
            if (0 == strcmp("async", superAsyncMode->valuestring)) {
×
2038
                g_queryInfo.superQueryInfo.asyncMode = ASYNC_MODE;
×
2039
            } else {
2040
                g_queryInfo.superQueryInfo.asyncMode = SYNC_MODE;
×
2041
            }
2042
        } else {
2043
            g_queryInfo.superQueryInfo.asyncMode = SYNC_MODE;
12✔
2044
        }
2045

2046
        tools_cJSON *superInterval =
2047
            tools_cJSON_GetObjectItem(superQuery, "interval");
12✔
2048
        if (superInterval && superInterval->type == tools_cJSON_Number) {
12✔
2049
            g_queryInfo.superQueryInfo.subscribeInterval =
×
2050
                superInterval->valueint;
×
2051
        } else {
2052
            g_queryInfo.superQueryInfo.subscribeInterval =
12✔
2053
                DEFAULT_QUERY_INTERVAL;
2054
        }
2055

2056
        tools_cJSON *subrestart =
2057
            tools_cJSON_GetObjectItem(superQuery, "restart");
12✔
2058
        if (subrestart && subrestart->type == tools_cJSON_String
12✔
2059
                && subrestart->valuestring != NULL) {
×
2060
            if (0 == strcmp("no", subrestart->valuestring)) {
×
2061
                g_queryInfo.superQueryInfo.subscribeRestart = false;
×
2062
            } else {
2063
                g_queryInfo.superQueryInfo.subscribeRestart = true;
×
2064
            }
2065
        } else {
2066
            g_queryInfo.superQueryInfo.subscribeRestart = true;
12✔
2067
        }
2068

2069
        tools_cJSON *superkeepProgress =
2070
            tools_cJSON_GetObjectItem(superQuery, "keepProgress");
12✔
2071
        if (superkeepProgress && superkeepProgress->type == tools_cJSON_String
12✔
2072
            && superkeepProgress->valuestring != NULL) {
×
2073
            if (0 == strcmp("yes", superkeepProgress->valuestring)) {
×
2074
                g_queryInfo.superQueryInfo.subscribeKeepProgress = 1;
×
2075
            } else {
2076
                g_queryInfo.superQueryInfo.subscribeKeepProgress = 0;
×
2077
            }
2078
        } else {
2079
            g_queryInfo.superQueryInfo.subscribeKeepProgress = 0;
12✔
2080
        }
2081

2082
        // default value is -1, which mean do not resub
2083
        g_queryInfo.superQueryInfo.endAfterConsume = -1;
12✔
2084
        tools_cJSON *superEndAfterConsume =
2085
            tools_cJSON_GetObjectItem(superQuery, "endAfterConsume");
12✔
2086
        if (superEndAfterConsume &&
12✔
2087
            superEndAfterConsume->type == tools_cJSON_Number) {
×
2088
            g_queryInfo.superQueryInfo.endAfterConsume =
×
2089
                (int)superEndAfterConsume->valueint;
×
2090
        }
2091
        if (g_queryInfo.superQueryInfo.endAfterConsume < -1)
12✔
2092
            g_queryInfo.superQueryInfo.endAfterConsume = -1;
×
2093

2094
        // default value is -1, which mean do not resub
2095
        g_queryInfo.superQueryInfo.resubAfterConsume = -1;
12✔
2096
        tools_cJSON *superResubAfterConsume =
2097
            tools_cJSON_GetObjectItem(superQuery, "resubAfterConsume");
12✔
2098
        if ((superResubAfterConsume) &&
12✔
2099
            (superResubAfterConsume->type == tools_cJSON_Number) &&
×
2100
            (superResubAfterConsume->valueint >= 0)) {
×
2101
            g_queryInfo.superQueryInfo.resubAfterConsume =
×
2102
                (int)superResubAfterConsume->valueint;
×
2103
        }
2104
        if (g_queryInfo.superQueryInfo.resubAfterConsume < -1)
12✔
2105
            g_queryInfo.superQueryInfo.resubAfterConsume = -1;
×
2106

2107
        // supert table sqls
2108
        tools_cJSON *superSqls = tools_cJSON_GetObjectItem(superQuery, "sqls");
12✔
2109
        if (!superSqls || superSqls->type != tools_cJSON_Array) {
12✔
2110
            g_queryInfo.superQueryInfo.sqlCount = 0;
×
2111
        } else {
2112
            int superSqlSize = tools_cJSON_GetArraySize(superSqls);
12✔
2113
            if (superSqlSize > MAX_QUERY_SQL_COUNT) {
12✔
2114
                errorPrint(
×
2115
                    "failed to read json, query sql size overflow, max is %d\n",
2116
                    MAX_QUERY_SQL_COUNT);
NEW
2117
                return -1;
×
2118
            }
2119

2120
            g_queryInfo.superQueryInfo.sqlCount = superSqlSize;
12✔
2121
            for (int j = 0; j < superSqlSize; ++j) {
223✔
2122
                tools_cJSON *sql = tools_cJSON_GetArrayItem(superSqls, j);
211✔
2123
                if (sql == NULL) continue;
211✔
2124

2125
                tools_cJSON *sqlStr = tools_cJSON_GetObjectItem(sql, "sql");
211✔
2126
                if (sqlStr && sqlStr->type == tools_cJSON_String) {
211✔
2127
                    tstrncpy(g_queryInfo.superQueryInfo.sql[j],
211✔
2128
                             sqlStr->valuestring, TSDB_MAX_ALLOWED_SQL_LEN);
2129
                }
2130

2131
                tools_cJSON *result = tools_cJSON_GetObjectItem(sql, "result");
211✔
2132
                if (result != NULL && result->type == tools_cJSON_String
211✔
2133
                    && result->valuestring != NULL) {
210✔
2134
                    tstrncpy(g_queryInfo.superQueryInfo.result[j],
210✔
2135
                             result->valuestring, MAX_FILE_NAME_LEN);
2136
                } else {
2137
                    memset(g_queryInfo.superQueryInfo.result[j], 0,
1✔
2138
                           MAX_FILE_NAME_LEN);
2139
                }
2140
            }
2141
        }
2142
    }
2143
    
2144
    // succ
2145
    return 0;
12✔
2146
}
2147

2148
// read query json 
2149
static int getMetaFromQueryJsonFile(tools_cJSON *json) {
31✔
2150
    int32_t code = -1;
31✔
2151

2152
    // read common
2153
    tools_cJSON *telnet_tcp_port =
2154
        tools_cJSON_GetObjectItem(json, "telnet_tcp_port");
31✔
2155
    if (tools_cJSON_IsNumber(telnet_tcp_port)) {
31✔
NEW
2156
        g_arguments->telnet_tcp_port = (uint16_t)telnet_tcp_port->valueint;
×
2157
    }
2158

2159
    tools_cJSON *gQueryTimes = tools_cJSON_GetObjectItem(json, "query_times");
31✔
2160
    if (tools_cJSON_IsNumber(gQueryTimes)) {
31✔
2161
        g_queryInfo.query_times = gQueryTimes->valueint;
29✔
2162
    } else {
2163
        g_queryInfo.query_times = 1;
2✔
2164
    }
2165

2166
    tools_cJSON *gKillSlowQueryThreshold =
2167
        tools_cJSON_GetObjectItem(json, "kill_slow_query_threshold");
31✔
2168
    if (tools_cJSON_IsNumber(gKillSlowQueryThreshold)) {
31✔
NEW
2169
        g_queryInfo.killQueryThreshold = gKillSlowQueryThreshold->valueint;
×
2170
    } else {
2171
        g_queryInfo.killQueryThreshold = 0;
31✔
2172
    }
2173

2174
    tools_cJSON *gKillSlowQueryInterval =
2175
        tools_cJSON_GetObjectItem(json, "kill_slow_query_interval");
31✔
2176
    if (tools_cJSON_IsNumber(gKillSlowQueryInterval)) {
31✔
NEW
2177
        g_queryInfo.killQueryInterval = gKillSlowQueryInterval->valueint;
×
2178
    } else {
2179
        g_queryInfo.killQueryInterval = 1;  /* by default, interval 1s */
31✔
2180
    }
2181

2182
    tools_cJSON *resetCache =
2183
        tools_cJSON_GetObjectItem(json, "reset_query_cache");
31✔
2184
    if (tools_cJSON_IsString(resetCache)) {
31✔
2185
        if (0 == strcasecmp(resetCache->valuestring, "yes")) {
4✔
2186
            g_queryInfo.reset_query_cache = true;
4✔
2187
        }
2188
    } else {
2189
        g_queryInfo.reset_query_cache = false;
27✔
2190
    }
2191

2192
    tools_cJSON *respBuffer =
2193
        tools_cJSON_GetObjectItem(json, "response_buffer");
31✔
2194
    if (tools_cJSON_IsNumber(respBuffer)) {
31✔
2195
        g_queryInfo.response_buffer = respBuffer->valueint;
2✔
2196
    } else {
2197
        g_queryInfo.response_buffer = RESP_BUF_LEN;
29✔
2198
    }
2199

2200
    tools_cJSON *dbs = tools_cJSON_GetObjectItem(json, "databases");
31✔
2201
    if (tools_cJSON_IsString(dbs)) {
31✔
2202
        g_queryInfo.dbName = dbs->valuestring;
31✔
2203
    }
2204

2205
    tools_cJSON *queryMode = tools_cJSON_GetObjectItem(json, "query_mode");
31✔
2206
    if (tools_cJSON_IsString(queryMode)) {
31✔
2207
        if (0 == strcasecmp(queryMode->valuestring, "rest")) {
20✔
2208
            g_queryInfo.iface = REST_IFACE;
9✔
2209
        } else if (0 == strcasecmp(queryMode->valuestring, "taosc")) {
11✔
2210
            g_queryInfo.iface = TAOSC_IFACE;
11✔
2211
        } else {
NEW
2212
            errorPrint("Invalid query_mode value: %s\n",
×
2213
                       queryMode->valuestring);
NEW
2214
            return -1;
×
2215
        }
2216
    }
2217
    // init sqls
2218
    g_queryInfo.specifiedQueryInfo.sqls = benchArrayInit(1, sizeof(SSQL));
31✔
2219

2220
    // specified_table_query
2221
    tools_cJSON *specifiedQuery = tools_cJSON_GetObjectItem(json, "specified_table_query");
31✔
2222
    if (specifiedQuery) {
31✔
2223
        code = readSpecQueryJson(specifiedQuery);
19✔
2224
        if(code) {
19✔
NEW
2225
            errorPrint("failed to readSpecQueryJson code=%d \n", code);
×
NEW
2226
            return code; 
×
2227
        }
2228
    }
2229

2230
    // super_table_query
2231
    tools_cJSON *superQuery = tools_cJSON_GetObjectItem(json, "super_table_query");
31✔
2232
    if (superQuery) {
31✔
2233
        code = readSuperQueryJson(superQuery);
12✔
2234
        if(code) {
12✔
NEW
2235
            errorPrint("failed to readSuperQueryJson code=%d \n", code);
×
NEW
2236
            return code; 
×
2237
        }
2238
    }
2239

2240
    // only have one
2241
    const char* errType = "json config invalid:";
31✔
2242
    if (specifiedQuery && superQuery) {
31✔
2243
        errorPrint("%s only appear one for 'specified_table_query' and 'super_table_query' \n", errType);
1✔
2244
        return -1;
1✔
2245
    }
2246

2247
    // must have one
2248
    if (specifiedQuery == NULL && superQuery == NULL ) {
30✔
2249
        errorPrint("%s must have one for 'specified_table_query' or 'super_table_query' \n", errType);
1✔
2250
        return -1;
1✔
2251
    }
2252

2253
    // succ
2254
    return 0;
29✔
2255
}
2256

2257
#ifdef TD_VER_COMPATIBLE_3_0_0_0
2258
static int getMetaFromTmqJsonFile(tools_cJSON *json) {
4✔
2259
    int32_t code = -1;
4✔
2260

2261
    tools_cJSON *cfgdir = tools_cJSON_GetObjectItem(json, "cfgdir");
4✔
2262
    if (tools_cJSON_IsString(cfgdir)) {
4✔
2263
        tstrncpy(g_configDir, cfgdir->valuestring, MAX_FILE_NAME_LEN);
4✔
2264
    }
2265

2266
#ifdef LINUX
2267
    if (strlen(g_configDir)) {
4✔
2268
        wordexp_t full_path;
2269
    if (wordexp(g_configDir, &full_path, 0) != 0) {
4✔
2270
            errorPrint("Invalid path %s\n", g_configDir);
×
2271
            exit(EXIT_FAILURE);
×
2272
    }
2273
        taos_options(TSDB_OPTION_CONFIGDIR, full_path.we_wordv[0]);
4✔
2274
        wordfree(&full_path);
4✔
2275
    }
2276
#endif
2277

2278
    tools_cJSON *resultfile = tools_cJSON_GetObjectItem(json, "result_file");
4✔
2279
    if (resultfile && resultfile->type == tools_cJSON_String
4✔
2280
            && resultfile->valuestring != NULL) {
4✔
2281
        g_arguments->output_file = resultfile->valuestring;
4✔
2282
    }
2283

2284
    tools_cJSON *answerPrompt =
2285
        tools_cJSON_GetObjectItem(json,
4✔
2286
                                  "confirm_parameter_prompt");  // yes, no,
2287
    if (tools_cJSON_IsString(answerPrompt)) {
4✔
2288
        if (0 == strcasecmp(answerPrompt->valuestring, "no")) {
4✔
2289
            g_arguments->answer_yes = true;
4✔
2290
        }
2291
    }
2292

2293
    // consumer info
2294
    tools_cJSON *tmqInfo = tools_cJSON_GetObjectItem(json, "tmq_info");
4✔
2295
    g_tmqInfo.consumerInfo.concurrent = 1;
4✔
2296

2297
    tools_cJSON *concurrent = tools_cJSON_GetObjectItem(tmqInfo, "concurrent");
4✔
2298
    if (tools_cJSON_IsNumber(concurrent)) {
4✔
2299
        g_tmqInfo.consumerInfo.concurrent = (uint32_t)concurrent->valueint;
4✔
2300
    }
2301

2302
    // sequential,        parallel
2303
    tools_cJSON *createMode = tools_cJSON_GetObjectItem(tmqInfo, "create_mode");
4✔
2304
    if (tools_cJSON_IsString(createMode)) {
4✔
2305
        g_tmqInfo.consumerInfo.createMode = createMode->valuestring;
×
2306
    }
2307

2308
    // share, independent
2309
    tools_cJSON *groupMode = tools_cJSON_GetObjectItem(tmqInfo, "group_mode");
4✔
2310
    if (tools_cJSON_IsString(groupMode)) {
4✔
2311
        g_tmqInfo.consumerInfo.groupMode = groupMode->valuestring;
×
2312
    }
2313

2314

2315
    tools_cJSON *pollDelay = tools_cJSON_GetObjectItem(tmqInfo, "poll_delay");
4✔
2316
    if (tools_cJSON_IsNumber(pollDelay)) {
4✔
2317
        g_tmqInfo.consumerInfo.pollDelay = (uint32_t)pollDelay->valueint;
4✔
2318
    }
2319

2320
    tools_cJSON *autoCommitInterval = tools_cJSON_GetObjectItem(
4✔
2321
            tmqInfo, "auto.commit.interval.ms");
2322
    if (tools_cJSON_IsNumber(autoCommitInterval)) {
4✔
2323
        g_tmqInfo.consumerInfo.autoCommitIntervalMs =
4✔
2324
            (uint32_t)autoCommitInterval->valueint;
4✔
2325
    }
2326

2327
    tools_cJSON *groupId = tools_cJSON_GetObjectItem(tmqInfo, "group.id");
4✔
2328
    if (tools_cJSON_IsString(groupId)) {
4✔
2329
        g_tmqInfo.consumerInfo.groupId = groupId->valuestring;
3✔
2330
    }
2331

2332
    tools_cJSON *clientId = tools_cJSON_GetObjectItem(tmqInfo, "client.id");
4✔
2333
    if (tools_cJSON_IsString(clientId)) {
4✔
2334
        g_tmqInfo.consumerInfo.clientId = clientId->valuestring;
4✔
2335
    }
2336

2337
    tools_cJSON *autoOffsetReset = tools_cJSON_GetObjectItem(
4✔
2338
            tmqInfo, "auto.offset.reset");
2339
    if (tools_cJSON_IsString(autoOffsetReset)) {
4✔
2340
        g_tmqInfo.consumerInfo.autoOffsetReset = autoOffsetReset->valuestring;
4✔
2341
    }
2342

2343
    tools_cJSON *enableAutoCommit = tools_cJSON_GetObjectItem(
4✔
2344
            tmqInfo, "enable.auto.commit");
2345
    if (tools_cJSON_IsString(enableAutoCommit)) {
4✔
2346
        g_tmqInfo.consumerInfo.enableAutoCommit = enableAutoCommit->valuestring;
4✔
2347
    }
2348

2349
    tools_cJSON *enableManualCommit = tools_cJSON_GetObjectItem(
4✔
2350
            tmqInfo, "enable.manual.commit");
2351
    if (tools_cJSON_IsString(enableManualCommit)) {
4✔
2352
        g_tmqInfo.consumerInfo.enableManualCommit =
1✔
2353
            enableManualCommit->valuestring;
1✔
2354
    }
2355

2356
    tools_cJSON *enableHeartbeatBackground = tools_cJSON_GetObjectItem(
4✔
2357
            tmqInfo, "enable.heartbeat.background");
2358
    if (tools_cJSON_IsString(enableHeartbeatBackground)) {
4✔
2359
        g_tmqInfo.consumerInfo.enableHeartbeatBackground =
4✔
2360
            enableHeartbeatBackground->valuestring;
4✔
2361
    }
2362

2363
    tools_cJSON *snapshotEnable = tools_cJSON_GetObjectItem(
4✔
2364
            tmqInfo, "experimental.snapshot.enable");
2365
    if (tools_cJSON_IsString(snapshotEnable)) {
4✔
2366
        g_tmqInfo.consumerInfo.snapshotEnable = snapshotEnable->valuestring;
4✔
2367
    }
2368

2369
    tools_cJSON *msgWithTableName = tools_cJSON_GetObjectItem(
4✔
2370
            tmqInfo, "msg.with.table.name");
2371
    if (tools_cJSON_IsString(msgWithTableName)) {
4✔
2372
        g_tmqInfo.consumerInfo.msgWithTableName = msgWithTableName->valuestring;
4✔
2373
    }
2374

2375
    tools_cJSON *rowsFile = tools_cJSON_GetObjectItem(tmqInfo, "rows_file");
4✔
2376
    if (tools_cJSON_IsString(rowsFile)) {
4✔
2377
        g_tmqInfo.consumerInfo.rowsFile = rowsFile->valuestring;
4✔
2378
    }
2379

2380
    g_tmqInfo.consumerInfo.expectRows = -1;
4✔
2381
    tools_cJSON *expectRows = tools_cJSON_GetObjectItem(tmqInfo, "expect_rows");
4✔
2382
    if (tools_cJSON_IsNumber(expectRows)) {
4✔
2383
        g_tmqInfo.consumerInfo.expectRows = (uint32_t)expectRows->valueint;
4✔
2384
    }
2385

2386
    tools_cJSON *topicList = tools_cJSON_GetObjectItem(tmqInfo, "topic_list");
4✔
2387
    if (tools_cJSON_IsArray(topicList)) {
4✔
2388
        int topicCount = tools_cJSON_GetArraySize(topicList);
4✔
2389
        for (int j = 0; j < topicCount; ++j) {
11✔
2390
            tools_cJSON *topicObj = tools_cJSON_GetArrayItem(topicList, j);
7✔
2391
            if (tools_cJSON_IsObject(topicObj)) {
7✔
2392
                tools_cJSON *topicName = tools_cJSON_GetObjectItem(
7✔
2393
                        topicObj, "name");
2394
                if (tools_cJSON_IsString(topicName)) {
7✔
2395
                    //  int strLen = strlen(topicName->valuestring) + 1;
2396
                    tstrncpy(g_tmqInfo.consumerInfo.topicName[
7✔
2397
                                g_tmqInfo.consumerInfo.topicCount],
2398
                             topicName->valuestring, 255);
2399

2400
                } else {
2401
                    errorPrint("%s", "Invalid topic name in json\n");
×
2402
                    goto TMQ_PARSE_OVER;
×
2403
                }
2404

2405
                tools_cJSON *sqlString = tools_cJSON_GetObjectItem(
7✔
2406
                        topicObj, "sql");
2407
                if (tools_cJSON_IsString(sqlString)) {
7✔
2408
                    //  int strLen = strlen(sqlString->valuestring) + 1;
2409
                    tstrncpy(g_tmqInfo.consumerInfo.topicSql[
7✔
2410
                                g_tmqInfo.consumerInfo.topicCount],
2411
                             sqlString->valuestring, 255);
2412

2413
                } else {
2414
                    errorPrint("%s", "Invalid topic sql in json\n");
×
2415
                    goto TMQ_PARSE_OVER;
×
2416
                }
2417
                g_tmqInfo.consumerInfo.topicCount++;
7✔
2418
            }
2419
        }
2420
    }
2421
    code = 0;
4✔
2422
TMQ_PARSE_OVER:
4✔
2423
    return code;
4✔
2424
}
2425
#endif
2426

2427
int readJsonConfig(char * file) {
119✔
2428
    int32_t code = -1;
119✔
2429
    FILE *  fp = fopen(file, "r");
119✔
2430
    if (!fp) {
119✔
2431
        errorPrint("failed to read %s, reason:%s\n", file,
1✔
2432
                   strerror(errno));
2433
        return code;
1✔
2434
    }
2435

2436
    int   maxLen = MAX_JSON_BUFF;
118✔
2437
    char *content = benchCalloc(1, maxLen + 1, false);
118✔
2438
    int   len = (int)fread(content, 1, maxLen, fp);
118✔
2439
    if (len <= 0) {
118✔
2440
        errorPrint("failed to read %s, content is null", file);
×
2441
        goto PARSE_OVER;
×
2442
    }
2443

2444
    content[len] = 0;
118✔
2445
    root = tools_cJSON_Parse(content);
118✔
2446
    if (root == NULL) {
118✔
2447
        errorPrint("failed to cjson parse %s, invalid json format\n",
1✔
2448
                   file);
2449
        goto PARSE_OVER;
1✔
2450
    }
2451

2452
    char *pstr = tools_cJSON_Print(root);
117✔
2453
    infoPrint("%s\n%s\n", file, pstr);
117✔
2454
    tmfree(pstr);
117✔
2455

2456
    tools_cJSON *filetype = tools_cJSON_GetObjectItem(root, "filetype");
117✔
2457
    if (tools_cJSON_IsString(filetype)) {
117✔
2458
        if (0 == strcasecmp("insert", filetype->valuestring)) {
117✔
2459
            g_arguments->test_mode = INSERT_TEST;
81✔
2460
        } else if (0 == strcasecmp("query", filetype->valuestring)) {
36✔
2461
            g_arguments->test_mode = QUERY_TEST;
31✔
2462
        } else if (0 == strcasecmp("subscribe", filetype->valuestring)) {
5✔
2463
            g_arguments->test_mode = SUBSCRIBE_TEST;
4✔
2464
        } else if (0 == strcasecmp("csvfile", filetype->valuestring)) {
1✔
2465
            g_arguments->test_mode = CSVFILE_TEST;
1✔
2466
        } else {
2467
            errorPrint("%s",
×
2468
                       "failed to read json, filetype not support\n");
2469
            goto PARSE_OVER;
×
2470
        }
2471
    } else {
2472
        g_arguments->test_mode = INSERT_TEST;
×
2473
    }
2474

2475
    // read common item
2476
    code = getMetaFromCommonJsonFile(root);
117✔
2477
    if (INSERT_TEST == g_arguments->test_mode || CSVFILE_TEST == g_arguments->test_mode) {
117✔
2478
        // insert 
2479
        code = getMetaFromInsertJsonFile(root);
82✔
2480
    } else if (QUERY_TEST == g_arguments->test_mode) {
35✔
2481
        // query
2482
        memset(&g_queryInfo, 0, sizeof(SQueryMetaInfo));
31✔
2483
        code = getMetaFromQueryJsonFile(root);
31✔
2484
    } else if (SUBSCRIBE_TEST == g_arguments->test_mode) {
4✔
2485
        // subscribe
2486
        memset(&g_tmqInfo, 0, sizeof(STmqMetaInfo));
4✔
2487
        code = getMetaFromTmqJsonFile(root);
4✔
2488
    }
2489

UNCOV
2490
PARSE_OVER:
×
2491
    free(content);
118✔
2492
    fclose(fp);
118✔
2493
    return code;
118✔
2494
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc