tconfig.c 18.8 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() {
S
Shengliang Guan 已提交
32 33
  SConfig *pCfg = calloc(1, sizeof(SConfig));
  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) {
S
Shengliang Guan 已提交
40
    free(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;
  }
}

X
Xiaoyu Wang 已提交
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 78 79 80 81 82 83 84 85
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) {
    tfree(pItem->str);
  }
  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 92
    int32_t size = taosArrayGetSize(pCfg->array);
    for (int32_t i = 0; i < size; ++i) {
      SConfigItem *pItem = taosArrayGet(pCfg->array, i);
      cfgFreeItem(pItem);
      tfree(pItem->name);
S
Shengliang Guan 已提交
93
    }
S
Shengliang Guan 已提交
94
    taosArrayDestroy(pCfg->array);
S
Shengliang Guan 已提交
95
    free(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;
  }

X
Xiaoyu Wang 已提交
148
#if 0
S
Shengliang Guan 已提交
149 150 151 152
  if (taosMkDir(fullDir) != 0) {
    uError("failed to create dir:%s realpath:%s since %s", inputDir, fullDir, terrstr());
    return -1;
  }
X
Xiaoyu Wang 已提交
153
#endif
S
Shengliang Guan 已提交
154

S
tfs cfg  
Shengliang Guan 已提交
155
  cfgFreeItem(pItem);
S
Shengliang Guan 已提交
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
  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 已提交
175 176 177 178
  pItem->stype = stype;
  return 0;
}

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

S
Shengliang Guan 已提交
189
  pItem->i32 = ival;
S
config  
Shengliang Guan 已提交
190 191 192 193
  pItem->stype = stype;
  return 0;
}

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

S
Shengliang Guan 已提交
205
  pItem->i64 = ival;
S
config  
Shengliang Guan 已提交
206 207 208 209
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
210
static int32_t cfgSetFloat(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
config  
Shengliang Guan 已提交
211
  float fval = (float)atof(value);
S
Shengliang Guan 已提交
212
  if (fval < pItem->fmin || fval > pItem->fmax) {
S
config  
Shengliang Guan 已提交
213
    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 已提交
214 215
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), fval, pItem->fmin, pItem->fmax, cfgStypeStr(pItem->stype),
           pItem->fval);
S
config  
Shengliang Guan 已提交
216 217 218
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
config  
Shengliang Guan 已提交
219

S
Shengliang Guan 已提交
220
  pItem->fval = fval;
S
config  
Shengliang Guan 已提交
221 222 223 224
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
225
static int32_t cfgSetString(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
config  
Shengliang Guan 已提交
226 227 228 229
  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 已提交
230
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), value, terrstr(), cfgStypeStr(pItem->stype), pItem->str);
S
config  
Shengliang Guan 已提交
231 232
    return -1;
  }
S
config  
Shengliang Guan 已提交
233

S
Shengliang Guan 已提交
234 235
  free(pItem->str);
  pItem->str = tmp;
S
config  
Shengliang Guan 已提交
236 237 238 239
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
240
static int32_t cfgSetDir(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
Shengliang Guan 已提交
241
  if (cfgCheckAndSetDir(pItem, value) != 0) {
S
Shengliang Guan 已提交
242 243 244 245 246 247 248 249 250 251 252
    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 已提交
253
  if (cfgCheckAndSetLocale(pItem, value) != 0) {
S
Shengliang Guan 已提交
254 255 256 257 258 259 260 261 262 263 264
    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 已提交
265
  if (cfgCheckAndSetCharset(pItem, value) != 0) {
S
Shengliang Guan 已提交
266 267 268 269 270 271 272 273 274 275 276
    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 已提交
277
  if (cfgCheckAndSetTimezone(pItem, value) != 0) {
S
config  
Shengliang Guan 已提交
278 279
    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 已提交
280
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), value, terrstr(), cfgStypeStr(pItem->stype), pItem->str);
S
config  
Shengliang Guan 已提交
281 282
    return -1;
  }
S
config  
Shengliang Guan 已提交
283

S
config  
Shengliang Guan 已提交
284 285 286 287
  pItem->stype = stype;
  return 0;
}

S
tfs cfg  
Shengliang Guan 已提交
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
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 已提交
315 316
int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype) {
  SConfigItem *pItem = cfgGetItem(pCfg, name);
S
config  
Shengliang Guan 已提交
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
  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 已提交
333
      return cfgSetDir(pItem, value, stype);
S
Shengliang Guan 已提交
334 335 336 337 338 339
    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 已提交
340 341 342 343 344 345 346 347 348
    case CFG_DTYPE_NONE:
    default:
      break;
  }

  terrno = TSDB_CODE_INVALID_CFG;
  return -1;
}

S
Shengliang Guan 已提交
349
SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) {
S
Shengliang Guan 已提交
350 351 352 353 354 355
  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 已提交
356 357
  }

S
Shengliang Guan 已提交
358 359
  terrno = TSDB_CODE_CFG_NOT_FOUND;
  return NULL;
S
config  
Shengliang Guan 已提交
360
}
S
Shengliang Guan 已提交
361

S
Shengliang Guan 已提交
362
static int32_t cfgAddItem(SConfig *pCfg, SConfigItem *pItem, const char *name) {
S
config  
Shengliang Guan 已提交
363
  pItem->stype = CFG_STYPE_DEFAULT;
S
Shengliang Guan 已提交
364
  pItem->name = strdup(name);
S
Shengliang Guan 已提交
365
  if (pItem->name == NULL) {
S
Shengliang Guan 已提交
366 367 368 369
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

S
Shengliang Guan 已提交
370 371 372
  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 已提交
373

S
Shengliang Guan 已提交
374
  if (taosArrayPush(pCfg->array, pItem) == NULL) {
S
cfgtest  
Shengliang Guan 已提交
375
    if (pItem->dtype == CFG_DTYPE_STRING) {
S
Shengliang Guan 已提交
376
      free(pItem->str);
S
cfgtest  
Shengliang Guan 已提交
377 378
    }
    free(pItem->name);
S
Shengliang Guan 已提交
379 380 381 382 383 384 385
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

  return 0;
}

S
Shengliang Guan 已提交
386 387
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 已提交
388
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
389 390
}

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

S
Shengliang Guan 已提交
397
  SConfigItem item = {.dtype = CFG_DTYPE_INT32, .i32 = defaultVal, .imin = minval, .imax = maxval, .tsc = tsc};
S
Shengliang Guan 已提交
398
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
399 400
}

S
Shengliang Guan 已提交
401
int32_t cfgAddInt64(SConfig *pCfg, const char *name, int64_t defaultVal, int64_t minval, int64_t maxval, bool tsc) {
S
config  
Shengliang Guan 已提交
402 403 404 405
  if (defaultVal < minval || defaultVal > maxval) {
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
Shengliang Guan 已提交
406

S
Shengliang Guan 已提交
407
  SConfigItem item = {.dtype = CFG_DTYPE_INT64, .i64 = defaultVal, .imin = minval, .imax = maxval, .tsc = tsc};
S
Shengliang Guan 已提交
408
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
409 410
}

S
Shengliang Guan 已提交
411
int32_t cfgAddFloat(SConfig *pCfg, const char *name, float defaultVal, double minval, double maxval, bool tsc) {
S
config  
Shengliang Guan 已提交
412 413 414 415
  if (defaultVal < minval || defaultVal > maxval) {
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
Shengliang Guan 已提交
416

S
Shengliang Guan 已提交
417
  SConfigItem item = {.dtype = CFG_DTYPE_FLOAT, .fval = defaultVal, .fmin = minval, .fmax = maxval, .tsc = tsc};
S
Shengliang Guan 已提交
418
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
419 420
}

S
Shengliang Guan 已提交
421 422
int32_t cfgAddString(SConfig *pCfg, const char *name, const char *defaultVal, bool tsc) {
  SConfigItem item = {.dtype = CFG_DTYPE_STRING, .tsc = tsc};
S
Shengliang Guan 已提交
423 424
  item.str = strdup(defaultVal);
  if (item.str == NULL) {
S
Shengliang Guan 已提交
425 426 427
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
428
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
429 430
}

S
Shengliang Guan 已提交
431 432
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 已提交
433
  if (cfgCheckAndSetDir(&item, defaultVal) != 0) {
S
Shengliang Guan 已提交
434 435
    return -1;
  }
S
config  
Shengliang Guan 已提交
436

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

S
Shengliang Guan 已提交
440
int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal) {
S
Shengliang Guan 已提交
441
  SConfigItem item = {.dtype = CFG_DTYPE_LOCALE, .tsc = 1};
S
config  
Shengliang Guan 已提交
442 443 444 445
  if (cfgCheckAndSetLocale(&item, defaultVal) != 0) {
    return -1;
  }

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

S
Shengliang Guan 已提交
449
int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal) {
S
Shengliang Guan 已提交
450
  SConfigItem item = {.dtype = CFG_DTYPE_CHARSET, .tsc = 1};
S
config  
Shengliang Guan 已提交
451 452 453 454
  if (cfgCheckAndSetCharset(&item, defaultVal) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
455
  return cfgAddItem(pCfg, &item, name);
S
config  
Shengliang Guan 已提交
456 457
}

S
Shengliang Guan 已提交
458
int32_t cfgAddTimezone(SConfig *pCfg, const char *name, const char *defaultVal) {
S
Shengliang Guan 已提交
459
  SConfigItem item = {.dtype = CFG_DTYPE_TIMEZONE, .tsc = 1};
S
config  
Shengliang Guan 已提交
460 461 462 463
  if (cfgCheckAndSetTimezone(&item, defaultVal) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
464
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
465
}
S
Shengliang Guan 已提交
466 467 468

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

S
Shengliang Guan 已提交
513 514
void cfgDumpCfg(SConfig *pCfg, bool tsc, bool dump) {
  if (dump) {
S
Shengliang Guan 已提交
515
    printf("                     global config");
S
Shengliang Guan 已提交
516 517 518 519
    printf("\n");
    printf("=================================================================");
    printf("\n");
  } else {
S
Shengliang Guan 已提交
520
    uInfo("                     global config");
S
Shengliang Guan 已提交
521 522
    uInfo("=================================================================");
  }
S
Shengliang Guan 已提交
523 524 525

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

S
Shengliang Guan 已提交
527 528 529
  int32_t size = taosArrayGetSize(pCfg->array);
  for (int32_t i = 0; i < size; ++i) {
    SConfigItem *pItem = taosArrayGet(pCfg->array, i);
S
Shengliang Guan 已提交
530
    if (tsc && !pItem->tsc) continue;
S
Shengliang Guan 已提交
531 532 533
    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 已提交
534 535
    }

S
Shengliang Guan 已提交
536 537 538 539
    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 已提交
540 541 542

    switch (pItem->dtype) {
      case CFG_DTYPE_BOOL:
S
Shengliang Guan 已提交
543 544 545 546 547 548 549
        if (dump) {
          printf("%s %s %u", src, name, pItem->bval);
          printf("\n");
        } else {
          uInfo("%s %s %u", src, name, pItem->bval);
        }

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

S
Shengliang Guan 已提交
590 591 592 593 594 595
  if (dump) {
    printf("=================================================================");
    printf("\n");
  } else {
    uInfo("=================================================================");
  }
S
Shengliang Guan 已提交
596
}
S
Shengliang Guan 已提交
597 598 599 600 601 602 603 604 605 606 607 608

int32_t cfgLoadFromEnvVar(SConfig *pConfig) {
  uInfo("load from global env variables");
  return 0;
}

int32_t cfgLoadFromEnvFile(SConfig *pConfig, const char *filepath) {
  uInfo("load from env file %s", filepath);
  return 0;
}

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

X
Xiaoyu Wang 已提交
613 614 615 616
  if (taosIsDir(filepath)) {
    return -1;
  }

617
  TdFilePtr pFile = taosOpenFile(filepath, TD_FILE_READ | TD_FILE_STREAM);
618
  if (pFile == NULL) {
S
Shengliang Guan 已提交
619 620 621 622
    terrno = TAOS_SYSTEM_ERROR(errno);
    return -1;
  }

623
  while (!taosEOFFile(pFile)) {
S
Shengliang Guan 已提交
624 625 626
    name = value = value2 = value3 = NULL;
    olen = vlen = vlen2 = vlen3 = 0;

627
    _bytes = taosGetLineFile(pFile, &line);
S
Shengliang Guan 已提交
628 629 630 631
    if (_bytes < 0) {
      break;
    }

632
    line[_bytes - 1] = 0;
S
Shengliang Guan 已提交
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649

    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 已提交
650 651 652
    if (value2 != NULL && value3 != NULL && value2[0] != 0 && value3[0] != 0) {
      cfgSetTfsItem(pConfig, name, value, value2, value3, CFG_STYPE_CFG_FILE);
    }
S
Shengliang Guan 已提交
653 654
  }

655
  taosCloseFile(&pFile);
S
tfs cfg  
Shengliang Guan 已提交
656
  if (line != NULL) tfree(line);
S
Shengliang Guan 已提交
657 658 659 660 661 662 663 664 665

  uInfo("load from cfg file %s success", filepath);
  return 0;
}

int32_t cfgLoadFromApollUrl(SConfig *pConfig, const char *url) {
  uInfo("load from apoll url %s", url);
  return 0;
}