tconfig.c 18.9 KB
Newer Older
S
Shengliang Guan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#define _DEFAULT_SOURCE
S
Shengliang Guan 已提交
17 18
#include "tconfig.h"
#include "taoserror.h"
S
log  
Shengliang Guan 已提交
19
#include "tlog.h"
S
Shengliang Guan 已提交
20
#include "tutil.h"
S
Shengliang Guan 已提交
21

S
Shengliang Guan 已提交
22
#define CFG_NAME_PRINT_LEN 24
S
Shengliang Guan 已提交
23 24 25 26 27 28 29
#define CFG_SRC_PRINT_LEN  12

int32_t cfgLoadFromCfgFile(SConfig *pConfig, const char *filepath);
int32_t cfgLoadFromEnvFile(SConfig *pConfig, const char *filepath);
int32_t cfgLoadFromEnvVar(SConfig *pConfig);
int32_t cfgLoadFromApollUrl(SConfig *pConfig, const char *url);
int32_t cfgSetItem(SConfig *pConfig, const char *name, const char *value, ECfgSrcType stype);
S
Shengliang Guan 已提交
30

S
Shengliang Guan 已提交
31
SConfig *cfgInit() {
wafwerar's avatar
wafwerar 已提交
32
  SConfig *pCfg = taosMemoryCalloc(1, sizeof(SConfig));
S
Shengliang Guan 已提交
33
  if (pCfg == NULL) {
S
cfgtest  
Shengliang Guan 已提交
34 35 36 37
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

S
Shengliang Guan 已提交
38 39
  pCfg->array = taosArrayInit(32, sizeof(SConfigItem));
  if (pCfg->array == NULL) {
wafwerar's avatar
wafwerar 已提交
40
    taosMemoryFree(pCfg);
S
cfgtest  
Shengliang Guan 已提交
41 42 43 44
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

S
Shengliang Guan 已提交
45
  return pCfg;
S
Shengliang Guan 已提交
46 47
}

S
Shengliang Guan 已提交
48
int32_t cfgLoad(SConfig *pCfg, ECfgSrcType cfgType, const char *sourceStr) {
S
Shengliang Guan 已提交
49
  switch (cfgType) {
S
config  
Shengliang Guan 已提交
50
    case CFG_STYPE_CFG_FILE:
S
Shengliang Guan 已提交
51
      return cfgLoadFromCfgFile(pCfg, sourceStr);
S
config  
Shengliang Guan 已提交
52
    case CFG_STYPE_ENV_FILE:
S
Shengliang Guan 已提交
53
      return cfgLoadFromEnvFile(pCfg, sourceStr);
S
config  
Shengliang Guan 已提交
54
    case CFG_STYPE_ENV_VAR:
S
Shengliang Guan 已提交
55
      return cfgLoadFromEnvVar(pCfg);
S
config  
Shengliang Guan 已提交
56
    case CFG_STYPE_APOLLO_URL:
S
Shengliang Guan 已提交
57
      return cfgLoadFromApollUrl(pCfg, sourceStr);
S
Shengliang Guan 已提交
58 59 60 61 62
    default:
      return -1;
  }
}

63
int32_t cfgLoadFromArray(SConfig *pCfg, SArray *pArgs) {
S
Shengliang Guan 已提交
64 65 66
  int32_t size = taosArrayGetSize(pArgs);
  for (int32_t i = 0; i < size; ++i) {
    SConfigPair *pPair = taosArrayGet(pArgs, i);
S
Shengliang Guan 已提交
67 68 69
    if (cfgSetItem(pCfg, pPair->name, pPair->value, CFG_STYPE_ARG_LIST) != 0) {
      return -1;
    }
S
Shengliang Guan 已提交
70
  }
S
Shengliang Guan 已提交
71 72

  return 0;
S
Shengliang Guan 已提交
73 74
}

S
tfs cfg  
Shengliang Guan 已提交
75 76 77
static void cfgFreeItem(SConfigItem *pItem) {
  if (pItem->dtype == CFG_DTYPE_STRING || pItem->dtype == CFG_DTYPE_DIR || pItem->dtype == CFG_DTYPE_LOCALE ||
      pItem->dtype == CFG_DTYPE_CHARSET || pItem->dtype == CFG_DTYPE_TIMEZONE) {
wafwerar's avatar
wafwerar 已提交
78
    taosMemoryFreeClear(pItem->str);
S
tfs cfg  
Shengliang Guan 已提交
79 80 81 82 83 84 85
  }
  if (pItem->array) {
    taosArrayDestroy(pItem->array);
    pItem->array = NULL;
  }
}

S
Shengliang Guan 已提交
86 87
void cfgCleanup(SConfig *pCfg) {
  if (pCfg != NULL) {
S
Shengliang Guan 已提交
88 89 90 91
    int32_t size = taosArrayGetSize(pCfg->array);
    for (int32_t i = 0; i < size; ++i) {
      SConfigItem *pItem = taosArrayGet(pCfg->array, i);
      cfgFreeItem(pItem);
wafwerar's avatar
wafwerar 已提交
92
      taosMemoryFreeClear(pItem->name);
S
Shengliang Guan 已提交
93
    }
S
Shengliang Guan 已提交
94
    taosArrayDestroy(pCfg->array);
wafwerar's avatar
wafwerar 已提交
95
    taosMemoryFree(pCfg);
S
Shengliang Guan 已提交
96 97 98
  }
}

S
Shengliang Guan 已提交
99
int32_t cfgGetSize(SConfig *pCfg) { return taosArrayGetSize(pCfg->array); }
S
Shengliang Guan 已提交
100

S
Shengliang Guan 已提交
101
static int32_t cfgCheckAndSetTimezone(SConfigItem *pItem, const char *timezone) {
S
tfs cfg  
Shengliang Guan 已提交
102
  cfgFreeItem(pItem);
S
Shengliang Guan 已提交
103 104 105 106
  pItem->str = strdup(timezone);
  if (pItem->str == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
S
config  
Shengliang Guan 已提交
107
  }
S
Shengliang Guan 已提交
108 109 110 111 112

  return 0;
}

static int32_t cfgCheckAndSetCharset(SConfigItem *pItem, const char *charset) {
S
tfs cfg  
Shengliang Guan 已提交
113
  cfgFreeItem(pItem);
S
Shengliang Guan 已提交
114 115 116 117
  pItem->str = strdup(charset);
  if (pItem->str == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
S
config  
Shengliang Guan 已提交
118
  }
S
config  
Shengliang Guan 已提交
119

S
config  
Shengliang Guan 已提交
120 121 122
  return 0;
}

S
Shengliang Guan 已提交
123
static int32_t cfgCheckAndSetLocale(SConfigItem *pItem, const char *locale) {
S
tfs cfg  
Shengliang Guan 已提交
124
  cfgFreeItem(pItem);
S
Shengliang Guan 已提交
125 126 127
  pItem->str = strdup(locale);
  if (pItem->str == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
S
config  
Shengliang Guan 已提交
128 129
    return -1;
  }
S
config  
Shengliang Guan 已提交
130

S
config  
Shengliang Guan 已提交
131 132 133
  return 0;
}

S
Shengliang Guan 已提交
134 135 136 137 138 139 140 141 142 143 144 145 146 147
static int32_t cfgCheckAndSetDir(SConfigItem *pItem, const char *inputDir) {
  char fullDir[PATH_MAX] = {0};
  if (taosExpandDir(inputDir, fullDir, PATH_MAX) != 0) {
    terrno = TAOS_SYSTEM_ERROR(errno);
    uError("failed to expand dir:%s since %s", inputDir, terrstr());
    return -1;
  }

  if (taosRealPath(fullDir, PATH_MAX) != 0) {
    terrno = TAOS_SYSTEM_ERROR(errno);
    uError("failed to get realpath of dir:%s since %s", inputDir, terrstr());
    return -1;
  }

wafwerar's avatar
wafwerar 已提交
148
  taosMemoryFreeClear(pItem->str);
S
Shengliang Guan 已提交
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
  pItem->str = strdup(fullDir);
  if (pItem->str == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

  return 0;
}

static int32_t cfgSetBool(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
  bool tmp = false;
  if (strcasecmp(value, "true") == 0) {
    tmp = true;
  }
  if (atoi(value) > 0) {
    tmp = true;
  }

  pItem->bval = tmp;
S
config  
Shengliang Guan 已提交
168 169 170 171
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
172
static int32_t cfgSetInt32(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
config  
Shengliang Guan 已提交
173
  int32_t ival = (int32_t)atoi(value);
S
Shengliang Guan 已提交
174
  if (ival < pItem->imin || ival > pItem->imax) {
S
config  
Shengliang Guan 已提交
175
    uError("cfg:%s, type:%s src:%s value:%d out of range[%" PRId64 ", %" PRId64 "], use last src:%s value:%d",
S
Shengliang Guan 已提交
176 177
           pItem->name, cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), ival, pItem->imin, pItem->imax,
           cfgStypeStr(pItem->stype), pItem->i32);
S
config  
Shengliang Guan 已提交
178 179 180
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
config  
Shengliang Guan 已提交
181

S
Shengliang Guan 已提交
182
  pItem->i32 = ival;
S
config  
Shengliang Guan 已提交
183 184 185 186
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
187
static int32_t cfgSetInt64(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
config  
Shengliang Guan 已提交
188
  int64_t ival = (int64_t)atoi(value);
S
Shengliang Guan 已提交
189
  if (ival < pItem->imin || ival > pItem->imax) {
S
config  
Shengliang Guan 已提交
190 191
    uError("cfg:%s, type:%s src:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64
           "], use last src:%s value:%" PRId64,
S
Shengliang Guan 已提交
192 193
           pItem->name, cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), ival, pItem->imin, pItem->imax,
           cfgStypeStr(pItem->stype), pItem->i64);
S
config  
Shengliang Guan 已提交
194 195 196
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
config  
Shengliang Guan 已提交
197

S
Shengliang Guan 已提交
198
  pItem->i64 = ival;
S
config  
Shengliang Guan 已提交
199 200 201 202
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
203
static int32_t cfgSetFloat(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
config  
Shengliang Guan 已提交
204
  float fval = (float)atof(value);
S
Shengliang Guan 已提交
205
  if (fval < pItem->fmin || fval > pItem->fmax) {
S
config  
Shengliang Guan 已提交
206
    uError("cfg:%s, type:%s src:%s value:%f out of range[%f, %f], use last src:%s value:%f", pItem->name,
S
Shengliang Guan 已提交
207 208
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), fval, pItem->fmin, pItem->fmax, cfgStypeStr(pItem->stype),
           pItem->fval);
S
config  
Shengliang Guan 已提交
209 210 211
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
config  
Shengliang Guan 已提交
212

S
Shengliang Guan 已提交
213
  pItem->fval = fval;
S
config  
Shengliang Guan 已提交
214 215 216 217
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
218
static int32_t cfgSetString(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
config  
Shengliang Guan 已提交
219 220 221 222
  char *tmp = strdup(value);
  if (tmp == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s, use last src:%s value:%s", pItem->name,
S
Shengliang Guan 已提交
223
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), value, terrstr(), cfgStypeStr(pItem->stype), pItem->str);
S
config  
Shengliang Guan 已提交
224 225
    return -1;
  }
S
config  
Shengliang Guan 已提交
226

wafwerar's avatar
wafwerar 已提交
227
  taosMemoryFree(pItem->str);
S
Shengliang Guan 已提交
228
  pItem->str = tmp;
S
config  
Shengliang Guan 已提交
229 230 231 232
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
233
static int32_t cfgSetDir(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
Shengliang Guan 已提交
234
  if (cfgCheckAndSetDir(pItem, value) != 0) {
S
Shengliang Guan 已提交
235 236 237 238 239 240 241 242 243 244 245
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s, use last src:%s value:%s", pItem->name,
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), value, terrstr(), cfgStypeStr(pItem->stype), pItem->str);
    return -1;
  }

  pItem->stype = stype;
  return 0;
}

static int32_t cfgSetLocale(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
Shengliang Guan 已提交
246
  if (cfgCheckAndSetLocale(pItem, value) != 0) {
S
Shengliang Guan 已提交
247 248 249 250 251 252 253 254 255 256 257
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s, use last src:%s value:%s", pItem->name,
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), value, terrstr(), cfgStypeStr(pItem->stype), pItem->str);
    return -1;
  }

  pItem->stype = stype;
  return 0;
}

static int32_t cfgSetCharset(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
Shengliang Guan 已提交
258
  if (cfgCheckAndSetCharset(pItem, value) != 0) {
S
Shengliang Guan 已提交
259 260 261 262 263 264 265 266 267 268 269
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s, use last src:%s value:%s", pItem->name,
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), value, terrstr(), cfgStypeStr(pItem->stype), pItem->str);
    return -1;
  }

  pItem->stype = stype;
  return 0;
}

static int32_t cfgSetTimezone(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
Shengliang Guan 已提交
270
  if (cfgCheckAndSetTimezone(pItem, value) != 0) {
S
config  
Shengliang Guan 已提交
271 272
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s, use last src:%s value:%s", pItem->name,
S
Shengliang Guan 已提交
273
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), value, terrstr(), cfgStypeStr(pItem->stype), pItem->str);
S
config  
Shengliang Guan 已提交
274 275
    return -1;
  }
S
config  
Shengliang Guan 已提交
276

S
config  
Shengliang Guan 已提交
277 278 279 280
  pItem->stype = stype;
  return 0;
}

S
tfs cfg  
Shengliang Guan 已提交
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
static int32_t cfgSetTfsItem(SConfig *pCfg, const char *name, const char *value, const char *level, const char *primary,
                             ECfgSrcType stype) {
  SConfigItem *pItem = cfgGetItem(pCfg, name);
  if (pItem == NULL) return -1;

  if (pItem->array == NULL) {
    pItem->array = taosArrayInit(16, sizeof(SDiskCfg));
    if (pItem->array == NULL) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      return -1;
    }
  }

  SDiskCfg cfg = {0};
  tstrncpy(cfg.dir, value, sizeof(cfg.dir));
  cfg.level = atoi(level);
  cfg.primary = atoi(primary);
  void *ret = taosArrayPush(pItem->array, &cfg);
  if (ret == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

  pItem->stype = stype;
  return 0;
}

S
Shengliang Guan 已提交
308 309
int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype) {
  SConfigItem *pItem = cfgGetItem(pCfg, name);
S
config  
Shengliang Guan 已提交
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
  if (pItem == NULL) {
    return -1;
  }

  switch (pItem->dtype) {
    case CFG_DTYPE_BOOL:
      return cfgSetBool(pItem, value, stype);
    case CFG_DTYPE_INT32:
      return cfgSetInt32(pItem, value, stype);
    case CFG_DTYPE_INT64:
      return cfgSetInt64(pItem, value, stype);
    case CFG_DTYPE_FLOAT:
      return cfgSetFloat(pItem, value, stype);
    case CFG_DTYPE_STRING:
      return cfgSetString(pItem, value, stype);
    case CFG_DTYPE_DIR:
S
config  
Shengliang Guan 已提交
326
      return cfgSetDir(pItem, value, stype);
S
Shengliang Guan 已提交
327 328 329 330 331 332
    case CFG_DTYPE_TIMEZONE:
      return cfgSetTimezone(pItem, value, stype);
    case CFG_DTYPE_CHARSET:
      return cfgSetCharset(pItem, value, stype);
    case CFG_DTYPE_LOCALE:
      return cfgSetLocale(pItem, value, stype);
S
config  
Shengliang Guan 已提交
333 334 335 336 337 338 339 340 341
    case CFG_DTYPE_NONE:
    default:
      break;
  }

  terrno = TSDB_CODE_INVALID_CFG;
  return -1;
}

S
Shengliang Guan 已提交
342
SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) {
S
Shengliang Guan 已提交
343 344 345 346 347 348
  int32_t size = taosArrayGetSize(pCfg->array);
  for (int32_t i = 0; i < size; ++i) {
    SConfigItem *pItem = taosArrayGet(pCfg->array, i);
    if (strcasecmp(pItem->name, name) == 0) {
      return pItem;
    }
S
config  
Shengliang Guan 已提交
349 350
  }

S
Shengliang Guan 已提交
351 352
  terrno = TSDB_CODE_CFG_NOT_FOUND;
  return NULL;
S
config  
Shengliang Guan 已提交
353
}
S
Shengliang Guan 已提交
354

S
Shengliang Guan 已提交
355
static int32_t cfgAddItem(SConfig *pCfg, SConfigItem *pItem, const char *name) {
S
config  
Shengliang Guan 已提交
356
  pItem->stype = CFG_STYPE_DEFAULT;
S
Shengliang Guan 已提交
357
  pItem->name = strdup(name);
S
Shengliang Guan 已提交
358
  if (pItem->name == NULL) {
S
Shengliang Guan 已提交
359 360 361 362
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

S
Shengliang Guan 已提交
363 364 365
  int32_t len = strlen(name);
  char    lowcaseName[CFG_NAME_MAX_LEN + 1] = {0};
  strntolower(lowcaseName, name, TMIN(CFG_NAME_MAX_LEN, len));
S
config  
Shengliang Guan 已提交
366

S
Shengliang Guan 已提交
367
  if (taosArrayPush(pCfg->array, pItem) == NULL) {
S
cfgtest  
Shengliang Guan 已提交
368
    if (pItem->dtype == CFG_DTYPE_STRING) {
wafwerar's avatar
wafwerar 已提交
369
      taosMemoryFree(pItem->str);
S
cfgtest  
Shengliang Guan 已提交
370
    }
wafwerar's avatar
wafwerar 已提交
371
    taosMemoryFree(pItem->name);
S
Shengliang Guan 已提交
372 373 374 375 376 377 378
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

  return 0;
}

S
Shengliang Guan 已提交
379 380
int32_t cfgAddBool(SConfig *pCfg, const char *name, bool defaultVal, bool tsc) {
  SConfigItem item = {.dtype = CFG_DTYPE_BOOL, .bval = defaultVal, .tsc = tsc};
S
Shengliang Guan 已提交
381
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
382 383
}

S
Shengliang Guan 已提交
384
int32_t cfgAddInt32(SConfig *pCfg, const char *name, int32_t defaultVal, int64_t minval, int64_t maxval, bool tsc) {
S
config  
Shengliang Guan 已提交
385 386 387 388
  if (defaultVal < minval || defaultVal > maxval) {
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
Shengliang Guan 已提交
389

S
Shengliang Guan 已提交
390
  SConfigItem item = {.dtype = CFG_DTYPE_INT32, .i32 = defaultVal, .imin = minval, .imax = maxval, .tsc = tsc};
S
Shengliang Guan 已提交
391
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
392 393
}

S
Shengliang Guan 已提交
394
int32_t cfgAddInt64(SConfig *pCfg, const char *name, int64_t defaultVal, int64_t minval, int64_t maxval, bool tsc) {
S
config  
Shengliang Guan 已提交
395 396 397 398
  if (defaultVal < minval || defaultVal > maxval) {
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
Shengliang Guan 已提交
399

S
Shengliang Guan 已提交
400
  SConfigItem item = {.dtype = CFG_DTYPE_INT64, .i64 = defaultVal, .imin = minval, .imax = maxval, .tsc = tsc};
S
Shengliang Guan 已提交
401
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
402 403
}

S
Shengliang Guan 已提交
404
int32_t cfgAddFloat(SConfig *pCfg, const char *name, float defaultVal, double minval, double maxval, bool tsc) {
S
config  
Shengliang Guan 已提交
405 406 407 408
  if (defaultVal < minval || defaultVal > maxval) {
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
Shengliang Guan 已提交
409

S
Shengliang Guan 已提交
410
  SConfigItem item = {.dtype = CFG_DTYPE_FLOAT, .fval = defaultVal, .fmin = minval, .fmax = maxval, .tsc = tsc};
S
Shengliang Guan 已提交
411
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
412 413
}

S
Shengliang Guan 已提交
414 415
int32_t cfgAddString(SConfig *pCfg, const char *name, const char *defaultVal, bool tsc) {
  SConfigItem item = {.dtype = CFG_DTYPE_STRING, .tsc = tsc};
S
Shengliang Guan 已提交
416 417
  item.str = strdup(defaultVal);
  if (item.str == NULL) {
S
Shengliang Guan 已提交
418 419 420
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
421
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
422 423
}

S
Shengliang Guan 已提交
424 425
int32_t cfgAddDir(SConfig *pCfg, const char *name, const char *defaultVal, bool tsc) {
  SConfigItem item = {.dtype = CFG_DTYPE_DIR, .tsc = tsc};
S
config  
Shengliang Guan 已提交
426
  if (cfgCheckAndSetDir(&item, defaultVal) != 0) {
S
Shengliang Guan 已提交
427 428
    return -1;
  }
S
config  
Shengliang Guan 已提交
429

S
Shengliang Guan 已提交
430
  return cfgAddItem(pCfg, &item, name);
S
config  
Shengliang Guan 已提交
431 432
}

S
Shengliang Guan 已提交
433
int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal) {
S
Shengliang Guan 已提交
434
  SConfigItem item = {.dtype = CFG_DTYPE_LOCALE, .tsc = 1};
S
config  
Shengliang Guan 已提交
435 436 437 438
  if (cfgCheckAndSetLocale(&item, defaultVal) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
439
  return cfgAddItem(pCfg, &item, name);
S
config  
Shengliang Guan 已提交
440 441
}

S
Shengliang Guan 已提交
442
int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal) {
S
Shengliang Guan 已提交
443
  SConfigItem item = {.dtype = CFG_DTYPE_CHARSET, .tsc = 1};
S
config  
Shengliang Guan 已提交
444 445 446 447
  if (cfgCheckAndSetCharset(&item, defaultVal) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
448
  return cfgAddItem(pCfg, &item, name);
S
config  
Shengliang Guan 已提交
449 450
}

S
Shengliang Guan 已提交
451
int32_t cfgAddTimezone(SConfig *pCfg, const char *name, const char *defaultVal) {
S
Shengliang Guan 已提交
452
  SConfigItem item = {.dtype = CFG_DTYPE_TIMEZONE, .tsc = 1};
S
config  
Shengliang Guan 已提交
453 454 455 456
  if (cfgCheckAndSetTimezone(&item, defaultVal) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
457
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
458
}
S
Shengliang Guan 已提交
459 460 461

const char *cfgStypeStr(ECfgSrcType type) {
  switch (type) {
S
config  
Shengliang Guan 已提交
462
    case CFG_STYPE_DEFAULT:
S
Shengliang Guan 已提交
463
      return "default";
S
config  
Shengliang Guan 已提交
464
    case CFG_STYPE_CFG_FILE:
S
Shengliang Guan 已提交
465
      return "cfg_file";
S
config  
Shengliang Guan 已提交
466
    case CFG_STYPE_ENV_FILE:
S
Shengliang Guan 已提交
467
      return "env_file";
S
config  
Shengliang Guan 已提交
468
    case CFG_STYPE_ENV_VAR:
S
Shengliang Guan 已提交
469
      return "env_var";
S
config  
Shengliang Guan 已提交
470
    case CFG_STYPE_APOLLO_URL:
S
Shengliang Guan 已提交
471
      return "apollo_url";
S
config  
Shengliang Guan 已提交
472 473
    case CFG_STYPE_ARG_LIST:
      return "arg_list";
S
Shengliang Guan 已提交
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
    default:
      return "invalid";
  }
}

const char *cfgDtypeStr(ECfgDataType type) {
  switch (type) {
    case CFG_DTYPE_NONE:
      return "none";
    case CFG_DTYPE_BOOL:
      return "bool";
    case CFG_DTYPE_INT32:
      return "int32";
    case CFG_DTYPE_INT64:
      return "int64";
    case CFG_DTYPE_FLOAT:
      return "float";
    case CFG_DTYPE_STRING:
      return "string";
    case CFG_DTYPE_DIR:
      return "dir";
S
config  
Shengliang Guan 已提交
495 496 497 498 499 500
    case CFG_DTYPE_LOCALE:
      return "locale";
    case CFG_DTYPE_CHARSET:
      return "charset";
    case CFG_DTYPE_TIMEZONE:
      return "timezone";
S
Shengliang Guan 已提交
501 502 503 504 505
    default:
      return "invalid";
  }
}

S
Shengliang Guan 已提交
506 507
void cfgDumpCfg(SConfig *pCfg, bool tsc, bool dump) {
  if (dump) {
S
Shengliang Guan 已提交
508
    printf("                     global config");
S
Shengliang Guan 已提交
509 510 511 512
    printf("\n");
    printf("=================================================================");
    printf("\n");
  } else {
S
Shengliang Guan 已提交
513
    uInfo("                     global config");
S
Shengliang Guan 已提交
514 515
    uInfo("=================================================================");
  }
S
Shengliang Guan 已提交
516 517 518

  char src[CFG_SRC_PRINT_LEN + 1] = {0};
  char name[CFG_NAME_PRINT_LEN + 1] = {0};
S
Shengliang Guan 已提交
519

S
Shengliang Guan 已提交
520 521 522
  int32_t size = taosArrayGetSize(pCfg->array);
  for (int32_t i = 0; i < size; ++i) {
    SConfigItem *pItem = taosArrayGet(pCfg->array, i);
S
Shengliang Guan 已提交
523
    if (tsc && !pItem->tsc) continue;
S
Shengliang Guan 已提交
524 525 526
    tstrncpy(src, cfgStypeStr(pItem->stype), CFG_SRC_PRINT_LEN);
    for (int32_t i = 0; i < CFG_SRC_PRINT_LEN; ++i) {
      if (src[i] == 0) src[i] = ' ';
S
Shengliang Guan 已提交
527 528
    }

S
Shengliang Guan 已提交
529 530 531 532
    tstrncpy(name, pItem->name, CFG_NAME_PRINT_LEN);
    for (int32_t i = 0; i < CFG_NAME_PRINT_LEN; ++i) {
      if (name[i] == 0) name[i] = ' ';
    }
S
Shengliang Guan 已提交
533 534 535

    switch (pItem->dtype) {
      case CFG_DTYPE_BOOL:
S
Shengliang Guan 已提交
536 537 538 539 540 541 542
        if (dump) {
          printf("%s %s %u", src, name, pItem->bval);
          printf("\n");
        } else {
          uInfo("%s %s %u", src, name, pItem->bval);
        }

S
Shengliang Guan 已提交
543 544
        break;
      case CFG_DTYPE_INT32:
S
Shengliang Guan 已提交
545 546 547 548 549 550
        if (dump) {
          printf("%s %s %d", src, name, pItem->i32);
          printf("\n");
        } else {
          uInfo("%s %s %d", src, name, pItem->i32);
        }
S
Shengliang Guan 已提交
551 552
        break;
      case CFG_DTYPE_INT64:
S
Shengliang Guan 已提交
553 554 555 556 557 558
        if (dump) {
          printf("%s %s %" PRId64, src, name, pItem->i64);
          printf("\n");
        } else {
          uInfo("%s %s %" PRId64, src, name, pItem->i64);
        }
S
Shengliang Guan 已提交
559 560
        break;
      case CFG_DTYPE_FLOAT:
S
Shengliang Guan 已提交
561 562 563 564 565 566
        if (dump) {
          printf("%s %s %f", src, name, pItem->fval);
          printf("\n");
        } else {
          uInfo("%s %s %f", src, name, pItem->fval);
        }
S
Shengliang Guan 已提交
567 568 569 570 571 572
        break;
      case CFG_DTYPE_STRING:
      case CFG_DTYPE_DIR:
      case CFG_DTYPE_LOCALE:
      case CFG_DTYPE_CHARSET:
      case CFG_DTYPE_TIMEZONE:
573
      case CFG_DTYPE_NONE:
S
Shengliang Guan 已提交
574 575 576 577 578 579
        if (dump) {
          printf("%s %s %s", src, name, pItem->str);
          printf("\n");
        } else {
          uInfo("%s %s %s", src, name, pItem->str);
        }
S
Shengliang Guan 已提交
580 581 582 583
        break;
    }
  }

S
Shengliang Guan 已提交
584 585 586 587 588 589
  if (dump) {
    printf("=================================================================");
    printf("\n");
  } else {
    uInfo("=================================================================");
  }
S
Shengliang Guan 已提交
590
}
S
Shengliang Guan 已提交
591 592

int32_t cfgLoadFromEnvVar(SConfig *pConfig) {
S
Shengliang Guan 已提交
593
  uInfo("load from global env variables not implemented yet");
S
Shengliang Guan 已提交
594 595 596 597
  return 0;
}

int32_t cfgLoadFromEnvFile(SConfig *pConfig, const char *filepath) {
S
Shengliang Guan 已提交
598
  uInfo("load from env file not implemented yet");
S
Shengliang Guan 已提交
599 600 601 602
  return 0;
}

int32_t cfgLoadFromCfgFile(SConfig *pConfig, const char *filepath) {
603
  char   *line = NULL, *name, *value, *value2, *value3;
S
Shengliang Guan 已提交
604
  int32_t olen, vlen, vlen2, vlen3;
S
Shengliang Guan 已提交
605 606
  ssize_t _bytes = 0;

607 608 609 610
  if (taosIsDir(filepath)) {
    return -1;
  }

611
  TdFilePtr pFile = taosOpenFile(filepath, TD_FILE_READ | TD_FILE_STREAM);
612
  if (pFile == NULL) {
S
Shengliang Guan 已提交
613 614 615 616
    terrno = TAOS_SYSTEM_ERROR(errno);
    return -1;
  }

617
  while (!taosEOFFile(pFile)) {
S
Shengliang Guan 已提交
618 619 620
    name = value = value2 = value3 = NULL;
    olen = vlen = vlen2 = vlen3 = 0;

621
    _bytes = taosGetLineFile(pFile, &line);
S
Shengliang Guan 已提交
622 623 624 625
    if (_bytes < 0) {
      break;
    }

626
    line[_bytes - 1] = 0;
S
Shengliang Guan 已提交
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643

    paGetToken(line, &name, &olen);
    if (olen == 0) continue;
    name[olen] = 0;

    paGetToken(name + olen + 1, &value, &vlen);
    if (vlen == 0) continue;
    value[vlen] = 0;

    paGetToken(value + vlen + 1, &value2, &vlen2);
    if (vlen2 != 0) {
      value2[vlen2] = 0;
      paGetToken(value2 + vlen2 + 1, &value3, &vlen3);
      if (vlen3 != 0) value3[vlen3] = 0;
    }

    cfgSetItem(pConfig, name, value, CFG_STYPE_CFG_FILE);
S
Shengliang Guan 已提交
644
    if (value2 != NULL && value3 != NULL && value2[0] != 0 && value3[0] != 0 && strcasecmp(name, "dataDir") == 0) {
S
Shengliang Guan 已提交
645 646
      cfgSetTfsItem(pConfig, name, value, value2, value3, CFG_STYPE_CFG_FILE);
    }
S
Shengliang Guan 已提交
647 648
  }

649
  taosCloseFile(&pFile);
wafwerar's avatar
wafwerar 已提交
650
  if (line != NULL) taosMemoryFreeClear(line);
S
Shengliang Guan 已提交
651

S
Shengliang Guan 已提交
652
  uInfo("load from cfg file %s success", filepath);
S
Shengliang Guan 已提交
653 654 655 656
  return 0;
}

int32_t cfgLoadFromApollUrl(SConfig *pConfig, const char *url) {
S
Shengliang Guan 已提交
657
  uInfo("load from apoll url not implemented yet");
S
Shengliang Guan 已提交
658
  return 0;
659
}