173 lines
3.7 KiB
C
173 lines
3.7 KiB
C
/*
|
|
* 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 ALLOW_FORBID_FUNC
|
|
#include "db.h"
|
|
|
|
#include "taoserror.h"
|
|
#include "tcoding.h"
|
|
#include "thash.h"
|
|
#include "tsdbDBDef.h"
|
|
#include "tsdbLog.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;
|
|
}
|
|
tfree(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 = calloc(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;
|
|
} |