summaryrefslogblamecommitdiffstats
path: root/src/db.c
blob: a0443c9ffd267dff20bf1c5a99b6fcc0e7fb5a58 (plain) (tree)
1
2
3
4
5
6
7
8
9




                                                    

               

                                          









                                               
                            








                




                                                             


                                             
                                          









                                                   
 















































                                                              























                                                         



                                        












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