/* * Copyright (c) 2019 TAOS Data, Inc. * * 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 . */ #define ALLOW_FORBID_FUNC #include "db.h" #include "taoserror.h" #include "tcoding.h" #include "thash.h" #define IMPL_WITH_LOCK 1 static int tsdbOpenBDBDb(DB **ppDB, DB_ENV *pEnv, const char *pFName, bool isDup); static void tsdbCloseBDBDb(DB *pDB); #define BDB_PERR(info, code) fprintf(stderr, "%s:%d " info " reason: %s\n", __FILE__, __LINE__, db_strerror(code)) int32_t tsdbOpenDBF(TDBEnv pEnv, SDBFile *pDBF) { // TDBEnv is shared by a group of SDBFile if (!pEnv) { terrno = TSDB_CODE_INVALID_PTR; return -1; } // Open DBF if (tsdbOpenBDBDb(&(pDBF->pDB), pEnv, pDBF->path, false) < 0) { terrno = TSDB_CODE_TDB_INIT_FAILED; tsdbCloseBDBDb(pDBF->pDB); return -1; } return 0; } void tsdbCloseDBF(SDBFile *pDBF) { if (pDBF->pDB) { tsdbCloseBDBDb(pDBF->pDB); pDBF->pDB = NULL; } taosMemoryFreeClear(pDBF->path); } int32_t tsdbOpenBDBEnv(DB_ENV **ppEnv, const char *path) { int ret = 0; DB_ENV *pEnv = NULL; if (path == NULL) return 0; ret = db_env_create(&pEnv, 0); if (ret != 0) { BDB_PERR("Failed to create tsdb env", ret); return -1; } ret = pEnv->open(pEnv, path, DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL, 0); if (ret != 0) { terrno = TSDB_CODE_TDB_TDB_ENV_OPEN_ERROR; tsdbWarn("Failed to open tsdb env for path %s since ret %d != 0", path ? path : "NULL", ret); return -1; } *ppEnv = pEnv; return 0; } void tsdbCloseBDBEnv(DB_ENV *pEnv) { if (pEnv) { pEnv->close(pEnv, 0); } } static int tsdbOpenBDBDb(DB **ppDB, DB_ENV *pEnv, const char *pFName, bool isDup) { int ret; DB *pDB; ret = db_create(&(pDB), pEnv, 0); if (ret != 0) { BDB_PERR("Failed to create DBP", ret); return -1; } if (isDup) { ret = pDB->set_flags(pDB, DB_DUPSORT); if (ret != 0) { BDB_PERR("Failed to set DB flags", ret); return -1; } } ret = pDB->open(pDB, NULL, pFName, NULL, DB_BTREE, DB_CREATE, 0); if (ret) { BDB_PERR("Failed to open DBF", ret); return -1; } *ppDB = pDB; return 0; } static void tsdbCloseBDBDb(DB *pDB) { if (pDB) { pDB->close(pDB, 0); } } int32_t tsdbSaveSmaToDB(SDBFile *pDBF, void *key, uint32_t keySize, void *data, uint32_t dataSize) { int ret; DBT key1 = {0}, value1 = {0}; key1.data = key; key1.size = keySize; value1.data = data; value1.size = dataSize; // TODO: lock ret = pDBF->pDB->put(pDBF->pDB, NULL, &key1, &value1, 0); if (ret) { BDB_PERR("Failed to put data to DBF", ret); // TODO: unlock return -1; } // TODO: unlock return 0; } void *tsdbGetSmaDataByKey(SDBFile *pDBF, void* key, uint32_t keySize, uint32_t *valueSize) { void *result = NULL; DBT key1 = {0}; DBT value1 = {0}; int ret; // Set key/value key1.data = key; key1.size = keySize; // Query // TODO: lock ret = pDBF->pDB->get(pDBF->pDB, NULL, &key1, &value1, 0); // TODO: unlock if (ret != 0) { return NULL; } result = taosMemoryCalloc(1, value1.size); if (result == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return NULL; } *valueSize = value1.size; memcpy(result, value1.data, value1.size); return result; }