tconfig.c 19.2 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
Shengliang Guan 已提交
19
#include "tcfg.h"
S
Shengliang Guan 已提交
20 21
#include "thash.h"
#include "tutil.h"
S
log  
Shengliang Guan 已提交
22
#include "tlog.h"
S
Shengliang Guan 已提交
23

S
Shengliang Guan 已提交
24
#define CFG_NAME_PRINT_LEN 24
S
Shengliang Guan 已提交
25 26 27 28 29 30 31 32 33 34 35 36
#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 已提交
37

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

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

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

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

S
Shengliang Guan 已提交
70 71 72 73
int32_t cfgLoadArray(SConfig *pCfg, SArray *pArgs) {
  int32_t size = taosArrayGetSize(pArgs);
  for (int32_t i = 0; i < size; ++i) {
    SConfigPair *pPair = taosArrayGet(pArgs, i);
S
Shengliang Guan 已提交
74 75 76
    if (cfgSetItem(pCfg, pPair->name, pPair->value, CFG_STYPE_ARG_LIST) != 0) {
      return -1;
    }
S
Shengliang Guan 已提交
77
  }
S
Shengliang Guan 已提交
78 79

  return 0;
S
Shengliang Guan 已提交
80 81
}

S
tfs cfg  
Shengliang Guan 已提交
82 83 84 85 86 87 88 89 90 91 92
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 已提交
93 94 95
void cfgCleanup(SConfig *pCfg) {
  if (pCfg != NULL) {
    if (pCfg->hash != NULL) {
S
tfs cfg  
Shengliang Guan 已提交
96 97 98
      SConfigItem *pItem = taosHashIterate(pCfg->hash, NULL);
      while (pItem != NULL) {
        cfgFreeItem(pItem);
wafwerar's avatar
wafwerar 已提交
99
        tfree(pItem->name);
S
tfs cfg  
Shengliang Guan 已提交
100 101
        pItem = taosHashIterate(pCfg->hash, pItem);
      }
S
Shengliang Guan 已提交
102 103
      taosHashCleanup(pCfg->hash);
      pCfg->hash == NULL;
S
Shengliang Guan 已提交
104
    }
S
Shengliang Guan 已提交
105
    free(pCfg);
S
Shengliang Guan 已提交
106 107 108
  }
}

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

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

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

S
Shengliang Guan 已提交
115
static int32_t cfgCheckAndSetTimezone(SConfigItem *pItem, const char *timezone) {
S
tfs cfg  
Shengliang Guan 已提交
116
  cfgFreeItem(pItem);
S
Shengliang Guan 已提交
117 118 119 120
  pItem->str = strdup(timezone);
  if (pItem->str == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
S
config  
Shengliang Guan 已提交
121
  }
S
Shengliang Guan 已提交
122 123 124 125 126

  return 0;
}

static int32_t cfgCheckAndSetCharset(SConfigItem *pItem, const char *charset) {
S
tfs cfg  
Shengliang Guan 已提交
127
  cfgFreeItem(pItem);
S
Shengliang Guan 已提交
128 129 130 131
  pItem->str = strdup(charset);
  if (pItem->str == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
S
config  
Shengliang Guan 已提交
132
  }
S
config  
Shengliang Guan 已提交
133

S
config  
Shengliang Guan 已提交
134 135 136
  return 0;
}

S
Shengliang Guan 已提交
137
static int32_t cfgCheckAndSetLocale(SConfigItem *pItem, const char *locale) {
S
tfs cfg  
Shengliang Guan 已提交
138
  cfgFreeItem(pItem);
S
Shengliang Guan 已提交
139 140 141
  pItem->str = strdup(locale);
  if (pItem->str == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
S
config  
Shengliang Guan 已提交
142 143
    return -1;
  }
S
config  
Shengliang Guan 已提交
144

S
config  
Shengliang Guan 已提交
145 146 147
  return 0;
}

S
Shengliang Guan 已提交
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
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;
  }

S
tfs cfg  
Shengliang Guan 已提交
167
  cfgFreeItem(pItem);
S
Shengliang Guan 已提交
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
  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 已提交
187 188 189 190
  pItem->stype = stype;
  return 0;
}

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

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

S
config  
Shengliang Guan 已提交
206
static int32_t cfgSetInt64(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
config  
Shengliang Guan 已提交
207
  int64_t ival = (int64_t)atoi(value);
S
Shengliang Guan 已提交
208
  if (ival < pItem->imin || ival > pItem->imax) {
S
config  
Shengliang Guan 已提交
209 210
    uError("cfg:%s, type:%s src:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64
           "], use last src:%s value:%" PRId64,
S
Shengliang Guan 已提交
211 212
           pItem->name, cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), ival, pItem->imin, pItem->imax,
           cfgStypeStr(pItem->stype), pItem->i64);
S
config  
Shengliang Guan 已提交
213 214 215
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
config  
Shengliang Guan 已提交
216

S
Shengliang Guan 已提交
217
  pItem->i64 = ival;
S
config  
Shengliang Guan 已提交
218 219 220 221
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
222
static int32_t cfgSetFloat(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
config  
Shengliang Guan 已提交
223
  float fval = (float)atof(value);
S
Shengliang Guan 已提交
224
  if (fval < pItem->fmin || fval > pItem->fmax) {
S
config  
Shengliang Guan 已提交
225
    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 已提交
226 227
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), fval, pItem->fmin, pItem->fmax, cfgStypeStr(pItem->stype),
           pItem->fval);
S
config  
Shengliang Guan 已提交
228 229 230
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
config  
Shengliang Guan 已提交
231

S
Shengliang Guan 已提交
232
  pItem->fval = fval;
S
config  
Shengliang Guan 已提交
233 234 235 236
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
237
static int32_t cfgSetString(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
S
config  
Shengliang Guan 已提交
238 239 240 241
  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 已提交
242
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), value, terrstr(), cfgStypeStr(pItem->stype), pItem->str);
S
config  
Shengliang Guan 已提交
243 244
    return -1;
  }
S
config  
Shengliang Guan 已提交
245

S
Shengliang Guan 已提交
246 247
  free(pItem->str);
  pItem->str = tmp;
S
config  
Shengliang Guan 已提交
248 249 250 251
  pItem->stype = stype;
  return 0;
}

S
config  
Shengliang Guan 已提交
252
static int32_t cfgSetDir(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
wafwerar's avatar
wafwerar 已提交
253
  if (cfgCheckAndSetDir(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 cfgSetLocale(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
wafwerar's avatar
wafwerar 已提交
265
  if (cfgCheckAndSetLocale(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 cfgSetCharset(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
wafwerar's avatar
wafwerar 已提交
277
  if (cfgCheckAndSetCharset(pItem, value) != 0) {
S
Shengliang Guan 已提交
278 279 280 281 282 283 284 285 286 287 288
    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) {
wafwerar's avatar
wafwerar 已提交
289
  if (cfgCheckAndSetTimezone(pItem, value) != 0) {
S
config  
Shengliang Guan 已提交
290 291
    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 已提交
292
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), value, terrstr(), cfgStypeStr(pItem->stype), pItem->str);
S
config  
Shengliang Guan 已提交
293 294
    return -1;
  }
S
config  
Shengliang Guan 已提交
295

S
config  
Shengliang Guan 已提交
296 297 298 299
  pItem->stype = stype;
  return 0;
}

S
tfs cfg  
Shengliang Guan 已提交
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
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 已提交
327 328
int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype) {
  SConfigItem *pItem = cfgGetItem(pCfg, name);
S
config  
Shengliang Guan 已提交
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
  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 已提交
345
      return cfgSetDir(pItem, value, stype);
S
Shengliang Guan 已提交
346 347 348 349 350 351
    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 已提交
352 353 354 355 356 357 358 359 360
    case CFG_DTYPE_NONE:
    default:
      break;
  }

  terrno = TSDB_CODE_INVALID_CFG;
  return -1;
}

S
Shengliang Guan 已提交
361
SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) {
wafwerar's avatar
wafwerar 已提交
362 363 364
  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 已提交
365

wafwerar's avatar
wafwerar 已提交
366
  SConfigItem *pItem = taosHashGet(pCfg->hash, lowcaseName, len + 1);
S
config  
Shengliang Guan 已提交
367 368 369 370 371 372
  if (pItem == NULL) {
    terrno = TSDB_CODE_CFG_NOT_FOUND;
  }

  return pItem;
}
S
Shengliang Guan 已提交
373

S
Shengliang Guan 已提交
374
static int32_t cfgAddItem(SConfig *pCfg, SConfigItem *pItem, const char *name) {
S
config  
Shengliang Guan 已提交
375
  pItem->stype = CFG_STYPE_DEFAULT;
S
Shengliang Guan 已提交
376
  pItem->name = strdup(name);
S
Shengliang Guan 已提交
377
  if (pItem->name == NULL) {
S
Shengliang Guan 已提交
378 379 380 381
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

wafwerar's avatar
wafwerar 已提交
382 383 384
  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 已提交
385

wafwerar's avatar
wafwerar 已提交
386
  if (taosHashPut(pCfg->hash, lowcaseName, len + 1, pItem, sizeof(SConfigItem)) != 0) {
S
cfgtest  
Shengliang Guan 已提交
387
    if (pItem->dtype == CFG_DTYPE_STRING) {
S
Shengliang Guan 已提交
388
      free(pItem->str);
S
cfgtest  
Shengliang Guan 已提交
389 390
    }
    free(pItem->name);
S
Shengliang Guan 已提交
391 392 393 394 395 396 397
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

  return 0;
}

S
Shengliang Guan 已提交
398 399
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 已提交
400
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
401 402
}

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

S
Shengliang Guan 已提交
409
  SConfigItem item = {.dtype = CFG_DTYPE_INT32, .i32 = defaultVal, .imin = minval, .imax = maxval, .tsc = tsc};
S
Shengliang Guan 已提交
410
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
411 412
}

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

S
Shengliang Guan 已提交
419
  SConfigItem item = {.dtype = CFG_DTYPE_INT64, .i64 = defaultVal, .imin = minval, .imax = maxval, .tsc = tsc};
S
Shengliang Guan 已提交
420
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
421 422
}

S
Shengliang Guan 已提交
423
int32_t cfgAddFloat(SConfig *pCfg, const char *name, float defaultVal, double minval, double maxval, bool tsc) {
S
config  
Shengliang Guan 已提交
424 425 426 427
  if (defaultVal < minval || defaultVal > maxval) {
    terrno = TSDB_CODE_OUT_OF_RANGE;
    return -1;
  }
S
Shengliang Guan 已提交
428

S
Shengliang Guan 已提交
429
  SConfigItem item = {.dtype = CFG_DTYPE_FLOAT, .fval = defaultVal, .fmin = minval, .fmax = maxval, .tsc = tsc};
S
Shengliang Guan 已提交
430
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
431 432
}

S
Shengliang Guan 已提交
433 434
int32_t cfgAddString(SConfig *pCfg, const char *name, const char *defaultVal, bool tsc) {
  SConfigItem item = {.dtype = CFG_DTYPE_STRING, .tsc = tsc};
S
Shengliang Guan 已提交
435 436
  item.str = strdup(defaultVal);
  if (item.str == NULL) {
S
Shengliang Guan 已提交
437 438 439
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }
S
Shengliang Guan 已提交
440
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
441 442
}

S
Shengliang Guan 已提交
443 444
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 已提交
445
  if (cfgCheckAndSetDir(&item, defaultVal) != 0) {
S
Shengliang Guan 已提交
446 447
    return -1;
  }
S
config  
Shengliang Guan 已提交
448

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

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

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

S
Shengliang Guan 已提交
461
int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal) {
S
Shengliang Guan 已提交
462
  SConfigItem item = {.dtype = CFG_DTYPE_CHARSET, .tsc = 1};
S
config  
Shengliang Guan 已提交
463 464 465 466
  if (cfgCheckAndSetCharset(&item, defaultVal) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
467
  return cfgAddItem(pCfg, &item, name);
S
config  
Shengliang Guan 已提交
468 469
}

S
Shengliang Guan 已提交
470
int32_t cfgAddTimezone(SConfig *pCfg, const char *name, const char *defaultVal) {
S
Shengliang Guan 已提交
471
  SConfigItem item = {.dtype = CFG_DTYPE_TIMEZONE, .tsc = 1};
S
config  
Shengliang Guan 已提交
472 473 474 475
  if (cfgCheckAndSetTimezone(&item, defaultVal) != 0) {
    return -1;
  }

S
Shengliang Guan 已提交
476
  return cfgAddItem(pCfg, &item, name);
S
Shengliang Guan 已提交
477
}
S
Shengliang Guan 已提交
478 479 480

const char *cfgStypeStr(ECfgSrcType type) {
  switch (type) {
S
config  
Shengliang Guan 已提交
481
    case CFG_STYPE_DEFAULT:
S
Shengliang Guan 已提交
482
      return "default";
S
config  
Shengliang Guan 已提交
483
    case CFG_STYPE_CFG_FILE:
S
Shengliang Guan 已提交
484
      return "cfg_file";
S
config  
Shengliang Guan 已提交
485
    case CFG_STYPE_ENV_FILE:
S
Shengliang Guan 已提交
486
      return "env_file";
S
config  
Shengliang Guan 已提交
487
    case CFG_STYPE_ENV_VAR:
S
Shengliang Guan 已提交
488
      return "env_var";
S
config  
Shengliang Guan 已提交
489
    case CFG_STYPE_APOLLO_URL:
S
Shengliang Guan 已提交
490
      return "apollo_url";
S
config  
Shengliang Guan 已提交
491 492
    case CFG_STYPE_ARG_LIST:
      return "arg_list";
S
Shengliang Guan 已提交
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
    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 已提交
514 515 516 517 518 519
    case CFG_DTYPE_LOCALE:
      return "locale";
    case CFG_DTYPE_CHARSET:
      return "charset";
    case CFG_DTYPE_TIMEZONE:
      return "timezone";
S
Shengliang Guan 已提交
520 521 522 523 524
    default:
      return "invalid";
  }
}

S
Shengliang Guan 已提交
525 526
void cfgDumpCfg(SConfig *pCfg, bool tsc, bool dump) {
  if (dump) {
S
Shengliang Guan 已提交
527
    printf("                     global config");
S
Shengliang Guan 已提交
528 529 530 531
    printf("\n");
    printf("=================================================================");
    printf("\n");
  } else {
S
Shengliang Guan 已提交
532
    uInfo("                     global config");
S
Shengliang Guan 已提交
533 534
    uInfo("=================================================================");
  }
S
Shengliang Guan 已提交
535 536 537

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

  SConfigItem *pItem = cfgIterate(pCfg, NULL);
  while (pItem != NULL) {
S
Shengliang Guan 已提交
541
    if (tsc && !pItem->tsc) continue;
S
Shengliang Guan 已提交
542 543 544
    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 已提交
545 546
    }

S
Shengliang Guan 已提交
547 548 549 550
    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 已提交
551 552 553

    switch (pItem->dtype) {
      case CFG_DTYPE_BOOL:
S
Shengliang Guan 已提交
554 555 556 557 558 559 560
        if (dump) {
          printf("%s %s %u", src, name, pItem->bval);
          printf("\n");
        } else {
          uInfo("%s %s %u", src, name, pItem->bval);
        }

S
Shengliang Guan 已提交
561 562
        break;
      case CFG_DTYPE_INT32:
S
Shengliang Guan 已提交
563 564 565 566 567 568
        if (dump) {
          printf("%s %s %d", src, name, pItem->i32);
          printf("\n");
        } else {
          uInfo("%s %s %d", src, name, pItem->i32);
        }
S
Shengliang Guan 已提交
569 570
        break;
      case CFG_DTYPE_INT64:
S
Shengliang Guan 已提交
571 572 573 574 575 576
        if (dump) {
          printf("%s %s %" PRId64, src, name, pItem->i64);
          printf("\n");
        } else {
          uInfo("%s %s %" PRId64, src, name, pItem->i64);
        }
S
Shengliang Guan 已提交
577 578
        break;
      case CFG_DTYPE_FLOAT:
S
Shengliang Guan 已提交
579 580 581 582 583 584
        if (dump) {
          printf("%s %s %f", src, name, pItem->fval);
          printf("\n");
        } else {
          uInfo("%s %s %f", src, name, pItem->fval);
        }
S
Shengliang Guan 已提交
585 586 587 588 589 590
        break;
      case CFG_DTYPE_STRING:
      case CFG_DTYPE_DIR:
      case CFG_DTYPE_LOCALE:
      case CFG_DTYPE_CHARSET:
      case CFG_DTYPE_TIMEZONE:
S
Shengliang Guan 已提交
591 592 593 594 595 596
        if (dump) {
          printf("%s %s %s", src, name, pItem->str);
          printf("\n");
        } else {
          uInfo("%s %s %s", src, name, pItem->str);
        }
S
Shengliang Guan 已提交
597 598 599 600 601
        break;
    }
    pItem = cfgIterate(pCfg, pItem);
  }

S
Shengliang Guan 已提交
602 603 604 605 606 607
  if (dump) {
    printf("=================================================================");
    printf("\n");
  } else {
    uInfo("=================================================================");
  }
S
Shengliang Guan 已提交
608
}
S
Shengliang Guan 已提交
609 610 611 612 613 614 615 616 617 618 619 620

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) {
621
  char   *line = NULL, *name, *value, *value2, *value3;
S
Shengliang Guan 已提交
622 623 624
  int     olen, vlen, vlen2, vlen3;
  ssize_t _bytes = 0;

625 626 627
  // FILE *fp = fopen(filepath, "r");
  TdFilePtr pFile = taosOpenFile(filepath, TD_FILE_READ);
  if (pFile == NULL) {
S
Shengliang Guan 已提交
628 629 630 631
    terrno = TAOS_SYSTEM_ERROR(errno);
    return -1;
  }

632
  while (!taosEOFFile(pFile)) {
S
Shengliang Guan 已提交
633 634 635
    name = value = value2 = value3 = NULL;
    olen = vlen = vlen2 = vlen3 = 0;

636
    _bytes = taosGetLineFile(pFile, &line);
S
Shengliang Guan 已提交
637 638 639 640
    if (_bytes < 0) {
      break;
    }

641
    line[_bytes - 1] = 0;
S
Shengliang Guan 已提交
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658

    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 已提交
659 660 661
    if (value2 != NULL && value3 != NULL && value2[0] != 0 && value3[0] != 0) {
      cfgSetTfsItem(pConfig, name, value, value2, value3, CFG_STYPE_CFG_FILE);
    }
S
Shengliang Guan 已提交
662 663
  }

664
  taosCloseFile(&pFile);
S
tfs cfg  
Shengliang Guan 已提交
665
  if (line != NULL) tfree(line);
S
Shengliang Guan 已提交
666 667 668 669 670 671 672 673 674

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