fz/db_bdb.c

241 lines
4.6 KiB
C
Raw Permalink Normal View History

2021-11-03 04:29:33 +01:00
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <db.h>
#include "node.h"
#include "vector.h"
static DB *dbp;
void bdb_init()
{
int ret = db_create(&dbp, 0, 0);;
if (ret) {
fprintf(stderr, "db_create: %s\n", db_strerror(ret));
exit(EXIT_FAILURE);
}
ret = dbp->open(dbp, 0, "calc.bdb", 0, DB_BTREE, DB_CREATE, 0664);
if (ret) {
dbp->err(dbp, ret, "calc.bdb");
exit(EXIT_FAILURE);
}
}
static void bdb_put(char *key, char *val)
{
assert(key);
assert(val);
DBT field = { 0 };
field.data = key;
field.size = strlen(key) + 1;
DBT data = { 0 };
data.data = val;
data.size = strlen(val) + 1;
int ret = dbp->put(dbp, 0, &field, &data, 0);
if (ret) {
dbp->err(dbp, ret, "[BDB] DB->put");
assert(!ret);
}
int cret = dbp->close(dbp, 0);
assert(!cret);
bdb_init();
}
static void bdb_del(char *key)
{
assert(key);
DBT field = { 0 };
field.data = key;
field.size = strlen(key) + 1;
int ret = dbp->del(dbp, 0, &field, 0);
if (ret) {
if (ret == DB_NOTFOUND)
return;
dbp->err(dbp, ret, "[BDB] DB->del");
assert(!ret);
}
int cret = dbp->close(dbp, 0);
assert(!cret);
bdb_init();
}
char *bdballoc(char *key)
{
DBT field = { 0 };
field.data = key;
field.size = strlen(key) + 1;
DBT data = { 0 };
int ret = dbp->get(dbp, 0, &field, &data, 0);
if (ret) {
if (ret == DB_NOTFOUND)
return 0;
dbp->err(dbp, ret, "✝ DB->get");
assert(0);
}
char *s = strdup(data.data);
return s;
}
static void store_node(char *name, struct vector *v, char *sub)
{
char *inhalt = vector_pick_string(v, sub);
if (!inhalt)
return;
char key[strlen(name) + sizeof("/") + strlen(sub)];
char *p = key, *n = name;
while (*n)
*p++ = tolower(*n++);
*p++ = '/';
n = sub;
while (*n)
*p++ = tolower(*n++);
*p = 0;
bdb_put(key, inhalt);
}
static void remove_node(char *name, char *sub)
{
char key[strlen(name) + sizeof("/") + strlen(sub)];
char *p = key, *n = name;
while (*n)
*p++ = tolower(*n++);
*p++ = '/';
n = sub;
while (*n)
*p++ = tolower(*n++);
*p = 0;
bdb_del(key);
}
static void build_node(char *name, struct vector *v, char *sub)
{
if (!sub) {
struct node *node = node_create(name, BF_TYPE_STRING);
vector_put(v, "eintrag", node);
return;
}
char key[strlen(name) + strlen("/") + strlen(sub) + 1];
char *p = key, *n = name;
while (*n)
*p++ = tolower(*n++);
*p = 0;
strcat(key, "/");
strcat(key, sub);
char *val = bdballoc(key);
if (val) {
struct node *node;
if (!strcmp(sub, "auth") ||
(!strcmp(sub, "type") && !*val)) {
char *nil = malloc(sizeof("0"));
assert(nil);
strcpy(nil, "0");
node = node_create(nil, BF_TYPE_STRING);
} else
node = node_create(val, BF_TYPE_STRING);
vector_put(v, sub, node);
}
}
int bdb_exists(char *name)
{
char key[strlen(name) + strlen("/") + strlen("bot") + 1];
char *p = key, *n = name;
while (*n)
*p++ = tolower(*n++);
*p = 0;
strcat(key, "/");
strcat(key, "bot");
DBT field = { 0 };
field.data = key;
field.size = strlen(key) + 1;
DBT data = { 0 };
int ret = dbp->get(dbp, 0, &field, &data, 0);
if (ret) {
if (ret == DB_NOTFOUND)
return 0;
dbp->err(dbp, ret, "✝ DB->get");
assert(0);
}
return 1;
}
struct vector *bdb_load(char *name)
{
int exists = bdb_exists(name);
if (!exists)
return 0;
struct vector *vb = vector_create();
build_node(name, vb, "auth");
build_node(name, vb, "name");
build_node(name, vb, 0); // „eintrag“
build_node(name, vb, "inhalt");
build_node(name, vb, "zeit");
build_node(name, vb, "bot");
build_node(name, vb, "protected");
build_node(name, vb, "channel");
build_node(name, vb, "network");
build_node(name, vb, "count");
build_node(name, vb, "type");
build_node(name, vb, "tag");
build_node(name, vb, "lastcall");
return vb;
}
void bdb_store(char *name, struct vector *v)
{
store_node(name, v, "auth");
store_node(name, v, "name");
store_node(name, v, "inhalt");
store_node(name, v, "zeit");
store_node(name, v, "protected");
store_node(name, v, "channel");
store_node(name, v, "network");
store_node(name, v, "count");
store_node(name, v, "type");
store_node(name, v, "tag");
store_node(name, v, "lastcall");
store_node(name, v, "eintrag");
store_node(name, v, "bot");
}
void bdb_delete(char *name)
{
remove_node(name, "eintrag");
remove_node(name, "inhalt");
remove_node(name, "name");
remove_node(name, "zeit");
remove_node(name, "protected");
remove_node(name, "channel");
remove_node(name, "network");
remove_node(name, "count");
remove_node(name, "type");
remove_node(name, "tag");
remove_node(name, "lastcall");
remove_node(name, "bot");
remove_node(name, "auth");
}