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
  }

351
  // uError("name:%s, cfg not found", name);
S
Shengliang Guan 已提交
352 353
  terrno = TSDB_CODE_CFG_NOT_FOUND;
  return NULL;
S
config  
Shengliang Guan 已提交
354
}
S
Shengliang Guan 已提交
355

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

S
Shengliang Guan 已提交
364 365 366
  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 已提交
367

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

  return 0;
}

S
Shengliang Guan 已提交
380 381
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 已提交
382
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
383 384
}

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

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

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

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

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

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

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

S
Shengliang Guan 已提交
425 426
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 已提交
427
  if (cfgCheckAndSetDir(&item, defaultVal) != 0) {
S
Shengliang Guan 已提交
428 429
    return -1;
  }
S
config  
Shengliang Guan 已提交
430

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

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

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

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

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

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

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

const char *cfgStypeStr(ECfgSrcType type) {
  switch (type) {
S
config  
Shengliang Guan 已提交
463
    case CFG_STYPE_DEFAULT:
S
Shengliang Guan 已提交
464
      return "default";
S
config  
Shengliang Guan 已提交
465
    case CFG_STYPE_CFG_FILE:
S
Shengliang Guan 已提交
466
      return "cfg_file";
S
config  
Shengliang Guan 已提交
467
    case CFG_STYPE_ENV_FILE:
S
Shengliang Guan 已提交
468
      return "env_file";
S
config  
Shengliang Guan 已提交
469
    case CFG_STYPE_ENV_VAR:
S
Shengliang Guan 已提交
470
      return "env_var";
S
config  
Shengliang Guan 已提交
471
    case CFG_STYPE_APOLLO_URL:
S
Shengliang Guan 已提交
472
      return "apollo_url";
S
config  
Shengliang Guan 已提交
473 474
    case CFG_STYPE_ARG_LIST:
      return "arg_list";
S
Shengliang Guan 已提交
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495
    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 已提交
496 497 498 499 500 501
    case CFG_DTYPE_LOCALE:
      return "locale";
    case CFG_DTYPE_CHARSET:
      return "charset";
    case CFG_DTYPE_TIMEZONE:
      return "timezone";
S
Shengliang Guan 已提交
502 503 504 505 506
    default:
      return "invalid";
  }
}

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

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

S
Shengliang Guan 已提交
521 522 523
  int32_t size = taosArrayGetSize(pCfg->array);
  for (int32_t i = 0; i < size; ++i) {
    SConfigItem *pItem = taosArrayGet(pCfg->array, i);
S
Shengliang Guan 已提交
524
    if (tsc && !pItem->tsc) continue;
S
Shengliang Guan 已提交
525 526 527
    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 已提交
528 529
    }

S
Shengliang Guan 已提交
530 531 532 533
    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 已提交
534 535 536

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

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

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

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

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

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

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

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

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

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

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

    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 已提交
645
    if (value2 != NULL && value3 != NULL && value2[0] != 0 && value3[0] != 0 && strcasecmp(name, "dataDir") == 0) {
S
Shengliang Guan 已提交
646 647
      cfgSetTfsItem(pConfig, name, value, value2, value3, CFG_STYPE_CFG_FILE);
    }
S
Shengliang Guan 已提交
648 649
  }

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

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

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