tconfig.c 17.7 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 19 20 21
#include "tconfig.h"
#include "taoserror.h"
#include "thash.h"
#include "tutil.h"
#include "ulog.h"
S
Shengliang Guan 已提交
22

S
Shengliang Guan 已提交
23
#define CFG_NAME_PRINT_LEN 24
S
Shengliang Guan 已提交
24 25 26 27 28 29 30 31 32 33 34 35
#define CFG_SRC_PRINT_LEN  12

typedef struct SConfig {
  ECfgSrcType stype;
  SHashObj   *hash;
} SConfig;

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 已提交
36

S
Shengliang Guan 已提交
37
SConfig *cfgInit() {
S
Shengliang Guan 已提交
38 39
  SConfig *pCfg = calloc(1, sizeof(SConfig));
  if (pCfg == NULL) {
S
cfgtest  
Shengliang Guan 已提交
40 41 42 43
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

S
Shengliang Guan 已提交
44 45 46
  pCfg->hash = taosHashInit(16, MurmurHash3_32, false, HASH_NO_LOCK);
  if (pCfg->hash == NULL) {
    free(pCfg);
S
cfgtest  
Shengliang Guan 已提交
47 48 49 50
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

S
Shengliang Guan 已提交
51
  return pCfg;
S
Shengliang Guan 已提交
52 53
}

S
Shengliang Guan 已提交
54
int32_t cfgLoad(SConfig *pCfg, ECfgSrcType cfgType, const char *sourceStr) {
S
Shengliang Guan 已提交
55
  switch (cfgType) {
S
config  
Shengliang Guan 已提交
56
    case CFG_STYPE_CFG_FILE:
S
Shengliang Guan 已提交
57
      return cfgLoadFromCfgFile(pCfg, sourceStr);
S
config  
Shengliang Guan 已提交
58
    case CFG_STYPE_ENV_FILE:
S
Shengliang Guan 已提交
59
      return cfgLoadFromEnvFile(pCfg, sourceStr);
S
config  
Shengliang Guan 已提交
60
    case CFG_STYPE_ENV_VAR:
S
Shengliang Guan 已提交
61
      return cfgLoadFromEnvVar(pCfg);
S
config  
Shengliang Guan 已提交
62
    case CFG_STYPE_APOLLO_URL:
S
Shengliang Guan 已提交
63
      return cfgLoadFromApollUrl(pCfg, sourceStr);
S
Shengliang Guan 已提交
64 65 66 67 68
    default:
      return -1;
  }
}

S
Shengliang Guan 已提交
69 70 71 72 73
void cfgCleanup(SConfig *pCfg) {
  if (pCfg != NULL) {
    if (pCfg->hash != NULL) {
      taosHashCleanup(pCfg->hash);
      pCfg->hash == NULL;
S
Shengliang Guan 已提交
74
    }
S
Shengliang Guan 已提交
75
    free(pCfg);
S
Shengliang Guan 已提交
76 77 78
  }
}

S
Shengliang Guan 已提交
79
int32_t cfgGetSize(SConfig *pCfg) { return taosHashGetSize(pCfg->hash); }
S
Shengliang Guan 已提交
80

S
Shengliang Guan 已提交
81
SConfigItem *cfgIterate(SConfig *pCfg, SConfigItem *pIter) { return taosHashIterate(pCfg->hash, pIter); }
S
Shengliang Guan 已提交
82

S
Shengliang Guan 已提交
83
void cfgCancelIterate(SConfig *pCfg, SConfigItem *pIter) { return taosHashCancelIterate(pCfg->hash, pIter); }
S
Shengliang Guan 已提交
84

S
Shengliang Guan 已提交
85 86 87 88 89 90
static int32_t cfgCheckAndSetTimezone(SConfigItem *pItem, const char *timezone) {
  tfree(pItem->str);
  pItem->str = strdup(timezone);
  if (pItem->str == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
S
config  
Shengliang Guan 已提交
91
  }
S
Shengliang Guan 已提交
92 93 94 95 96 97 98 99 100 101

  return 0;
}

static int32_t cfgCheckAndSetCharset(SConfigItem *pItem, const char *charset) {
  tfree(pItem->str);
  pItem->str = strdup(charset);
  if (pItem->str == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
S
config  
Shengliang Guan 已提交
102
  }
S
config  
Shengliang Guan 已提交
103

S
config  
Shengliang Guan 已提交
104 105 106
  return 0;
}

S
Shengliang Guan 已提交
107 108 109 110 111
static int32_t cfgCheckAndSetLocale(SConfigItem *pItem, const char *locale) {
  tfree(pItem->str);
  pItem->str = strdup(locale);
  if (pItem->str == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
S
config  
Shengliang Guan 已提交
112 113
    return -1;
  }
S
config  
Shengliang Guan 已提交
114

S
config  
Shengliang Guan 已提交
115 116 117
  return 0;
}

S
Shengliang Guan 已提交
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
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;
  }

  if (taosMkDir(fullDir) != 0) {
    uError("failed to create dir:%s realpath:%s since %s", inputDir, fullDir, terrstr());
    return -1;
  }

  tfree(pItem->str);
  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 已提交
157 158 159 160
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
161
static int32_t cfgSetInt32(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
config  
Shengliang Guan 已提交
162
  int32_t ival = (int32_t)atoi(value);
S
Shengliang Guan 已提交
163
  if (ival < pItem->imin || ival > pItem->imax) {
S
config  
Shengliang Guan 已提交
164
    uError("cfg:%s, type:%s src:%s value:%d out of range[%" PRId64 ", %" PRId64 "], use last src:%s value:%d",
S
Shengliang Guan 已提交
165 166
           pItem->name, cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), ival, pItem->imin, pItem->imax,
           cfgStypeStr(pItem->stype), pItem->i32);
S
config  
Shengliang Guan 已提交
167 168 169
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
config  
Shengliang Guan 已提交
170

S
Shengliang Guan 已提交
171
  pItem->i32 = ival;
S
config  
Shengliang Guan 已提交
172 173 174 175
  pItem->stype = stype;
  return 0;
}

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

S
Shengliang Guan 已提交
187
  pItem->i64 = ival;
S
config  
Shengliang Guan 已提交
188 189 190 191
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
192
static int32_t cfgSetFloat(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
config  
Shengliang Guan 已提交
193
  float fval = (float)atof(value);
S
Shengliang Guan 已提交
194
  if (fval < pItem->fmin || fval > pItem->fmax) {
S
config  
Shengliang Guan 已提交
195
    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 已提交
196 197
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), fval, pItem->fmin, pItem->fmax, cfgStypeStr(pItem->stype),
           pItem->fval);
S
config  
Shengliang Guan 已提交
198 199 200
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
config  
Shengliang Guan 已提交
201

S
Shengliang Guan 已提交
202
  pItem->fval = fval;
S
config  
Shengliang Guan 已提交
203 204 205 206
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
207
static int32_t cfgSetString(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
config  
Shengliang Guan 已提交
208 209 210 211
  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 已提交
212
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), value, terrstr(), cfgStypeStr(pItem->stype), pItem->str);
S
config  
Shengliang Guan 已提交
213 214
    return -1;
  }
S
config  
Shengliang Guan 已提交
215

S
Shengliang Guan 已提交
216 217
  free(pItem->str);
  pItem->str = tmp;
S
config  
Shengliang Guan 已提交
218 219 220 221
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
222
static int32_t cfgSetDir(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
config  
Shengliang Guan 已提交
223
  char *tmp = strdup(value);
S
Shengliang Guan 已提交
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
  if (tmp == NULL || cfgCheckAndSetDir(pItem, value) != 0) {
    free(tmp);
    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) {
  char *tmp = strdup(value);
  if (tmp == NULL || cfgCheckAndSetLocale(pItem, value) != 0) {
    free(tmp);
    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) {
  char *tmp = strdup(value);
  if (tmp == NULL || cfgCheckAndSetCharset(pItem, value) != 0) {
    free(tmp);
    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) {
  char *tmp = strdup(value);
  if (tmp == NULL || cfgCheckAndSetTimezone(pItem, value) != 0) {
    free(tmp);
S
config  
Shengliang Guan 已提交
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,
S
Shengliang Guan 已提交
270
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), value, terrstr(), cfgStypeStr(pItem->stype), pItem->str);
S
config  
Shengliang Guan 已提交
271 272
    return -1;
  }
S
config  
Shengliang Guan 已提交
273

S
config  
Shengliang Guan 已提交
274 275 276 277
  pItem->stype = stype;
  return 0;
}

S
Shengliang Guan 已提交
278 279
int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype) {
  SConfigItem *pItem = cfgGetItem(pCfg, name);
S
config  
Shengliang Guan 已提交
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
  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 已提交
296
      return cfgSetDir(pItem, value, stype);
S
Shengliang Guan 已提交
297 298 299 300 301 302
    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 已提交
303 304 305 306 307 308 309 310 311
    case CFG_DTYPE_NONE:
    default:
      break;
  }

  terrno = TSDB_CODE_INVALID_CFG;
  return -1;
}

S
Shengliang Guan 已提交
312
SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) {
S
config  
Shengliang Guan 已提交
313 314 315
  char lowcaseName[CFG_NAME_MAX_LEN + 1] = {0};
  memcpy(lowcaseName, name, CFG_NAME_MAX_LEN);
  strntolower(lowcaseName, name, CFG_NAME_MAX_LEN);
S
config  
Shengliang Guan 已提交
316

S
Shengliang Guan 已提交
317
  SConfigItem *pItem = taosHashGet(pCfg->hash, lowcaseName, strlen(lowcaseName) + 1);
S
config  
Shengliang Guan 已提交
318 319 320 321 322 323
  if (pItem == NULL) {
    terrno = TSDB_CODE_CFG_NOT_FOUND;
  }

  return pItem;
}
S
Shengliang Guan 已提交
324

S
Shengliang Guan 已提交
325
static int32_t cfgAddItem(SConfig *pCfg, SConfigItem *pItem, const char *name) {
S
config  
Shengliang Guan 已提交
326
  pItem->stype = CFG_STYPE_DEFAULT;
S
Shengliang Guan 已提交
327
  pItem->name = strdup(name);
S
Shengliang Guan 已提交
328
  if (pItem->name == NULL) {
S
Shengliang Guan 已提交
329 330 331 332
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

S
config  
Shengliang Guan 已提交
333 334 335 336
  char lowcaseName[CFG_NAME_MAX_LEN + 1] = {0};
  memcpy(lowcaseName, name, CFG_NAME_MAX_LEN);
  strntolower(lowcaseName, name, CFG_NAME_MAX_LEN);

S
Shengliang Guan 已提交
337
  if (taosHashPut(pCfg->hash, lowcaseName, strlen(lowcaseName) + 1, pItem, sizeof(SConfigItem)) != 0) {
S
cfgtest  
Shengliang Guan 已提交
338
    if (pItem->dtype == CFG_DTYPE_STRING) {
S
Shengliang Guan 已提交
339
      free(pItem->str);
S
cfgtest  
Shengliang Guan 已提交
340 341
    }
    free(pItem->name);
S
Shengliang Guan 已提交
342 343 344 345 346 347 348
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

  return 0;
}

S
Shengliang Guan 已提交
349 350
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 已提交
351
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
352 353
}

S
Shengliang Guan 已提交
354
int32_t cfgAddInt32(SConfig *pCfg, const char *name, int32_t defaultVal, int64_t minval, int64_t maxval, bool tsc) {
S
config  
Shengliang Guan 已提交
355 356 357 358
  if (defaultVal < minval || defaultVal > maxval) {
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
Shengliang Guan 已提交
359

S
Shengliang Guan 已提交
360
  SConfigItem item = {.dtype = CFG_DTYPE_INT32, .i32 = defaultVal, .imin = minval, .imax = maxval, .tsc = tsc};
S
Shengliang Guan 已提交
361
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
362 363
}

S
Shengliang Guan 已提交
364
int32_t cfgAddInt64(SConfig *pCfg, const char *name, int64_t defaultVal, int64_t minval, int64_t maxval, bool tsc) {
S
config  
Shengliang Guan 已提交
365 366 367 368
  if (defaultVal < minval || defaultVal > maxval) {
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
Shengliang Guan 已提交
369

S
Shengliang Guan 已提交
370
  SConfigItem item = {.dtype = CFG_DTYPE_INT64, .i64 = defaultVal, .imin = minval, .imax = maxval, .tsc = tsc};
S
Shengliang Guan 已提交
371
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
372 373
}

S
Shengliang Guan 已提交
374
int32_t cfgAddFloat(SConfig *pCfg, const char *name, float defaultVal, double minval, double maxval, bool tsc) {
S
config  
Shengliang Guan 已提交
375 376 377 378
  if (defaultVal < minval || defaultVal > maxval) {
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
Shengliang Guan 已提交
379

S
Shengliang Guan 已提交
380
  SConfigItem item = {.dtype = CFG_DTYPE_FLOAT, .fval = defaultVal, .fmin = minval, .fmax = maxval, .tsc = tsc};
S
Shengliang Guan 已提交
381
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
382 383
}

S
Shengliang Guan 已提交
384 385
int32_t cfgAddString(SConfig *pCfg, const char *name, const char *defaultVal, bool tsc) {
  SConfigItem item = {.dtype = CFG_DTYPE_STRING, .tsc = tsc};
S
Shengliang Guan 已提交
386 387
  item.str = strdup(defaultVal);
  if (item.str == NULL) {
S
Shengliang Guan 已提交
388 389 390
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
391
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
392 393
}

S
Shengliang Guan 已提交
394 395
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 已提交
396
  if (cfgCheckAndSetDir(&item, defaultVal) != 0) {
S
Shengliang Guan 已提交
397 398
    return -1;
  }
S
config  
Shengliang Guan 已提交
399

S
Shengliang Guan 已提交
400
  return cfgAddItem(pCfg, &item, name);
S
config  
Shengliang Guan 已提交
401 402
}

S
Shengliang Guan 已提交
403
int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal) {
S
Shengliang Guan 已提交
404
  SConfigItem item = {.dtype = CFG_DTYPE_LOCALE, .tsc = 1};
S
config  
Shengliang Guan 已提交
405 406 407 408
  if (cfgCheckAndSetLocale(&item, defaultVal) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
409
  return cfgAddItem(pCfg, &item, name);
S
config  
Shengliang Guan 已提交
410 411
}

S
Shengliang Guan 已提交
412
int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal) {
S
Shengliang Guan 已提交
413
  SConfigItem item = {.dtype = CFG_DTYPE_CHARSET, .tsc = 1};
S
config  
Shengliang Guan 已提交
414 415 416 417
  if (cfgCheckAndSetCharset(&item, defaultVal) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
418
  return cfgAddItem(pCfg, &item, name);
S
config  
Shengliang Guan 已提交
419 420
}

S
Shengliang Guan 已提交
421
int32_t cfgAddTimezone(SConfig *pCfg, const char *name, const char *defaultVal) {
S
Shengliang Guan 已提交
422
  SConfigItem item = {.dtype = CFG_DTYPE_TIMEZONE, .tsc = 1};
S
config  
Shengliang Guan 已提交
423 424 425 426
  if (cfgCheckAndSetTimezone(&item, defaultVal) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
427
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
428
}
S
Shengliang Guan 已提交
429 430 431

const char *cfgStypeStr(ECfgSrcType type) {
  switch (type) {
S
config  
Shengliang Guan 已提交
432
    case CFG_STYPE_DEFAULT:
S
Shengliang Guan 已提交
433
      return "default";
S
config  
Shengliang Guan 已提交
434
    case CFG_STYPE_CFG_FILE:
S
Shengliang Guan 已提交
435
      return "cfg_file";
S
config  
Shengliang Guan 已提交
436
    case CFG_STYPE_ENV_FILE:
S
Shengliang Guan 已提交
437
      return "env_file";
S
config  
Shengliang Guan 已提交
438
    case CFG_STYPE_ENV_VAR:
S
Shengliang Guan 已提交
439
      return "env_var";
S
config  
Shengliang Guan 已提交
440
    case CFG_STYPE_APOLLO_URL:
S
Shengliang Guan 已提交
441
      return "apollo_url";
S
config  
Shengliang Guan 已提交
442 443 444 445
    case CFG_STYPE_ARG_LIST:
      return "arg_list";
    case CFG_STYPE_API_OPTION:
      return "api_option";
S
Shengliang Guan 已提交
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
    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 已提交
467 468 469 470 471 472
    case CFG_DTYPE_LOCALE:
      return "locale";
    case CFG_DTYPE_CHARSET:
      return "charset";
    case CFG_DTYPE_TIMEZONE:
      return "timezone";
S
Shengliang Guan 已提交
473 474 475 476 477
    default:
      return "invalid";
  }
}

S
Shengliang Guan 已提交
478 479 480 481 482 483 484 485 486 487
void cfgDumpCfg(SConfig *pCfg, bool tsc, bool dump) {
  if (dump) {
    printf("   global config");
    printf("\n");
    printf("=================================================================");
    printf("\n");
  } else {
    uInfo("   global config");
    uInfo("=================================================================");
  }
S
Shengliang Guan 已提交
488 489 490

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

  SConfigItem *pItem = cfgIterate(pCfg, NULL);
  while (pItem != NULL) {
S
Shengliang Guan 已提交
494
    if (tsc && !pItem->tsc) continue;
S
Shengliang Guan 已提交
495 496 497
    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 已提交
498 499
    }

S
Shengliang Guan 已提交
500 501 502 503
    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 已提交
504 505 506

    switch (pItem->dtype) {
      case CFG_DTYPE_BOOL:
S
Shengliang Guan 已提交
507 508 509 510 511 512 513
        if (dump) {
          printf("%s %s %u", src, name, pItem->bval);
          printf("\n");
        } else {
          uInfo("%s %s %u", src, name, pItem->bval);
        }

S
Shengliang Guan 已提交
514 515
        break;
      case CFG_DTYPE_INT32:
S
Shengliang Guan 已提交
516 517 518 519 520 521
        if (dump) {
          printf("%s %s %d", src, name, pItem->i32);
          printf("\n");
        } else {
          uInfo("%s %s %d", src, name, pItem->i32);
        }
S
Shengliang Guan 已提交
522 523
        break;
      case CFG_DTYPE_INT64:
S
Shengliang Guan 已提交
524 525 526 527 528 529
        if (dump) {
          printf("%s %s %" PRId64, src, name, pItem->i64);
          printf("\n");
        } else {
          uInfo("%s %s %" PRId64, src, name, pItem->i64);
        }
S
Shengliang Guan 已提交
530 531
        break;
      case CFG_DTYPE_FLOAT:
S
Shengliang Guan 已提交
532 533 534 535 536 537
        if (dump) {
          printf("%s %s %f", src, name, pItem->fval);
          printf("\n");
        } else {
          uInfo("%s %s %f", src, name, pItem->fval);
        }
S
Shengliang Guan 已提交
538 539 540 541 542 543
        break;
      case CFG_DTYPE_STRING:
      case CFG_DTYPE_DIR:
      case CFG_DTYPE_LOCALE:
      case CFG_DTYPE_CHARSET:
      case CFG_DTYPE_TIMEZONE:
S
Shengliang Guan 已提交
544 545 546 547 548 549
        if (dump) {
          printf("%s %s %s", src, name, pItem->str);
          printf("\n");
        } else {
          uInfo("%s %s %s", src, name, pItem->str);
        }
S
Shengliang Guan 已提交
550 551 552 553 554
        break;
    }
    pItem = cfgIterate(pCfg, pItem);
  }

S
Shengliang Guan 已提交
555 556 557 558 559 560
  if (dump) {
    printf("=================================================================");
    printf("\n");
  } else {
    uInfo("=================================================================");
  }
S
Shengliang Guan 已提交
561
}
S
Shengliang Guan 已提交
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629

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) {
  char   *line, *name, *value, *value2, *value3;
  int     olen, vlen, vlen2, vlen3;
  ssize_t _bytes = 0;
  size_t  len = 1024;

  FILE *fp = fopen(filepath, "r");
  if (fp == NULL) {
    terrno = TAOS_SYSTEM_ERROR(errno);
    return -1;
  }

  line = malloc(len);

  while (!feof(fp)) {
    memset(line, 0, len);

    name = value = value2 = value3 = NULL;
    olen = vlen = vlen2 = vlen3 = 0;

    _bytes = tgetline(&line, &len, fp);
    if (_bytes < 0) {
      break;
    }

    line[len - 1] = 0;

    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);
    // taosReadConfigOption(name, value, value2, value3);
  }

  fclose(fp);
  tfree(line);

  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;
}