diff options
Diffstat (limited to 'src/db.c')
-rw-r--r-- | src/db.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/db.c b/src/db.c new file mode 100644 index 0000000..a0443c9 --- /dev/null +++ b/src/db.c @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright © 2020 rsiddharth <s@ricketyspace.net> + */ + +#include <db.h> + +static const char *DB_FILE = "nserver.db"; + +datum *mk_datum(char *data) +{ + datum *d = NULL; + + check(data != NULL, "data invalid"); + + d = calloc(1, sizeof(datum)); + check(d != NULL, "datum mem alloc failed"); + + d->dptr = data; + d->dsize = strlen(data); + + return d; + error: + if (d) { + free(d); + } + return NULL; +} + +GDBM_FILE db_open(int flags) +{ + return gdbm_open(DB_FILE, 0,flags, S_IRUSR|S_IWUSR, NULL); +} + +int db_init() +{ + // Create DB if it's not already created. + GDBM_FILE gf = db_open(GDBM_WRCREAT); + check(gf != NULL, "unable to init db"); + + // Close the DB. + int rc = gdbm_close(gf); + check(rc == 0, "error closing db after init"); + + return 0; + error: + return -1; +} + +int db_store(char *key, char *value) +{ + datum *k_datum = NULL, *v_datum = NULL; + GDBM_FILE gf = NULL; + + check(key != NULL && strlen(key) > 0, "key invalid"); + check(value != NULL && strlen(value) > 0, "data invalid"); + + // make key value datum + k_datum = mk_datum(key); + check(k_datum != NULL, "key datum init failed"); + + v_datum = mk_datum(value); + check(v_datum != NULL, "value datum init failed"); + + // init db. + int rc = db_init(); + check(rc == 0, "db init failed"); + + // open the gdbm data in write mode + gf = db_open(GDBM_WRITER|GDBM_SYNC); + check(gf != NULL, "unable to open db in write mode"); + + // write key -> data to db. + rc = gdbm_store(gf, *k_datum, *v_datum, GDBM_REPLACE); + check(rc == 0, "gdbm store failed"); + + // close db + rc = gdbm_close(gf); + check(rc == 0, "gdbm close failed"); + + // cleanup. + free(k_datum); + free(v_datum); + + return 0; + error: + if (k_datum) { + free(k_datum); + } + if (v_datum) { + free(v_datum); + } + if (gf) { + gdbm_close(gf); + } + return -1; +} + +char *db_load(char *key) +{ + datum *k_datum = NULL; + GDBM_FILE gf = NULL; + + check(key != NULL && strlen(key) > 0, "key invalid"); + + // make key datum + k_datum = mk_datum(key); + check(k_datum != NULL, "key datum init failed"); + + // init db. + int rc = db_init(); + check(rc == 0, "db init failed"); + + // open the gdbm data in read mode + gf = db_open(GDBM_READER|GDBM_SYNC); + check(gf != NULL, "unable to open db in read mode"); + + // try to fetch value for key. + datum v_datum = gdbm_fetch(gf, *k_datum); + check(v_datum.dptr != NULL, "key not found"); + + // close db + rc = gdbm_close(gf); + check(rc == 0, "gdbm close failed"); + + // clean up. + free(k_datum); + + return v_datum.dptr; + error: + if (k_datum) { + free(k_datum); + } + if (gf) { + gdbm_close(gf); + } + return NULL; +} |