Examples

Creating and populating a database

#include <string.h>
#include <yax/osutil.h>
#include <sys/fcntl.h>
#include "mdbm.h"

int main(int argc, char **argv)
{
    MDBM* db;
    char fn[MAXPATHLEN];
    char buf[2048];
    int ndups;

    snprintf(fn,sizeof(fn),"%s%s",yax_getroot(),"/tmp/example.mdbm");
    db = mdbm_open(fn,MDBM_O_RDWR|MDBM_O_CREAT,0666,0,0);
    if (!db) {
        perror("Unable to create database");
        exit(2);
    }
    ndups = 0;
    while (fgets(buf,sizeof(buf),stdin)) {
        int len = strlen(buf);
        char* s;
        if (buf[len-1] == '\n') {
            buf[--len] = 0;
        }
        s = strchr(buf,':');
        if (s) {
            datum key, val;
            int ret;
            key.dptr = buf;
            key.dsize = s-buf;
            val.dptr = s+1;
            val.dsize = len-key.dsize-1;
            mdbm_lock(db);
            ret = mdbm_store(db,key,val,MDBM_INSERT);
            mdbm_unlock(db);
            if (ret == 1) {
                ndups++;
            } else if (ret == -1) {
                perror("Database store failed");
            }
        }
    }
    mdbm_sync(db);      /* optional flush to disk */
    mdbm_close(db);
    return 0;
}

Fetching and updating records in-place

#include <assert.h>
#include <string.h>
#include <yax/osutil.h>
#include <sys/fcntl.h>
#include "mdbm.h"

struct user_rec {
    int u_count;
};

int main(int argc, char **argv)
{
    MDBM* db;
    char fn[MAXPATHLEN];
    char buf[2048];
    int notfound;

    snprintf(fn,sizeof(fn),"%s%s",yax_getroot(),"/tmp/example.mdbm");
    db = mdbm_open(fn,MDBM_O_RDWR,0666,0,0);
    if (!db) {
        perror("Unable to open database");
        exit(2);
    }
    notfound = 0;
    while (fgets(buf,sizeof(buf),stdin)) {
        datum key, val;
        int len = strlen(buf);
        if (buf[len-1] == '\n') {
            buf[--len] = 0;
        }
        key.dptr = buf;
        key.dsize = len;
        mdbm_lock(db);
        val = mdbm_fetch(db,key);
        if (val.dptr) {
            struct user_rec* recp;
            assert(val.dsize == sizeof(*recp));
            recp = (struct user_rec*)val.dptr;
            if (--recp->u_count == 0) {
                mdbm_delete(db,key);
            }
        } else {
            notfound++;
        }
        mdbm_unlock(db);
    }
    mdbm_close(db);
    return 0;
}

Adding/replacing records

#include <assert.h>
#include <string.h>
#include <yax/osutil.h>
#include <sys/fcntl.h>
#include "mdbm.h"

int main(int argc, char **argv)
{
    char buf[2048];
    MDBM* db;
    char fn[MAXPATHLEN];
    int notfound;

    snprintf(fn,sizeof(fn),"%s%s",yax_getroot(),"/tmp/example.mdbm");
    db = mdbm_open(fn,MDBM_O_RDWR,0666,0,0);
    if (!db) {
        perror("Unable to open database");
        exit(2);
    }
    notfound = 0;
    while (fgets(buf,sizeof(buf),stdin)) {
        datum key, val;
        static char DELETED[] = "deleted";
        int len = strlen(buf);
        int ret;

        if (buf[len-1] == '\n') {
            buf[--len] = 0;
        }
        key.dptr = buf;
        key.dsize = len;
        val.dptr = DELETED;
        val.dsize = sizeof(DELETED)-1;
        mdbm_lock(db);
        ret = mdbm_store(db,key,val,MDBM_REPLACE);
        mdbm_unlock(db);
        if (ret) {
            perror("Database store failed");
        }
    }
    mdbm_close(db);
    return 0;
}

Iterating over all records

#include <assert.h>
#include <string.h>
#include <yax/osutil.h>
#include <sys/fcntl.h>
#include "mdbm.h"

int main(int argc, char **argv)
{
    MDBM* db;
    char fn[MAXPATHLEN];
    kvpair kv;

    snprintf(fn,sizeof(fn),"%s%s",yax_getroot(),"/tmp/example.mdbm");
    db = mdbm_open(fn,MDBM_O_RDONLY,0666,0,0);
        if (!db) {
            perror("Unable to open database");
            exit(2);
        }

    mdbm_lock(db);
    kv = mdbm_first(db);
    while (kv.key.dptr) {
        printf("%.*s %.*s\n",
               kv.key.dsize,(char*)kv.key.dptr,
               kv.val.dsize,(char*)kv.val.dptr);
        kv = mdbm_next(db);
    }
    mdbm_unlock(db);
    mdbm_close(db);
    return 0;
}

Iterating over all records with custom iterator

/* Use iterators to walk through MDBM.
 */

#include <assert.h>
#include <strings.h>
#include <yax/osutil.h>
#include <sys/fcntl.h>
#include "mdbm.h"

int main(int argc, char **argv)
{
    MDBM* db;
    char fn[MAXPATHLEN];

    MDBM_ITER iter;
    kvpair kv;

    snprintf(fn,sizeof(fn),"%s%s",yax_getroot(),"/tmp/example.mdbm");
    db = mdbm_open(fn,MDBM_O_RDWR,0666,0,0);
    if (!db) {
        perror("Unable to open database");
        exit(2);
    }

    /* Start at the beginning */
    kv = mdbm_first_r( db, &iter );
    if ((kv.key.dsize == 0) && (kv.val.dsize == 0)) {
          printf("Database was empty!\n");
          mdbm_close(db);
          exit(3);
    }

    while (! ((kv.key.dsize == 0) && (kv.val.dsize == 0))) {
        printf("Key [%.*s] Val [%.*s]\n",
               kv.key.dsize, kv.key.dptr,
               kv.val.dsize, kv.val.dptr);

        kv = mdbm_next_r( db, &iter );
    }
    printf("End of db reached.\n");
    mdbm_close(db);
    exit(1);
}

Iterating over all keys with custom iterator

/* Use iterators to walk through MDBM.
 */

#include <assert.h>
#include <strings.h>
#include <yax/osutil.h>
#include <sys/fcntl.h>
#include "mdbm.h"

int main(int argc, char **argv)
{
    MDBM* db;
    char fn[MAXPATHLEN];

    MDBM_ITER iter;
    datum key;

    strlcpy(fn,yax_getroot(),sizeof(fn));
    strlcat(fn,"/tmp/example.mdbm",sizeof(fn));
    db = mdbm_open(fn,MDBM_O_RDWR,0666,0,0);
    if (!db) {
        perror("Unable to open database");
        exit(2);
    }

    /* Start at the beginning */
    key = mdbm_firstkey_r( db, &iter );
    if (key.dsize == 0) {
        printf("Database was empty!\n");
        mdbm_close(db);
        exit(3);
    }

    while (! (key.dsize == 0)) {
        printf("Key [%.*s]\n", key.dsize, key.dptr);

        key = mdbm_nextkey_r( db, &iter );
    }
    printf("End of db reached.\n");
    mdbm_close(db);
    exit(1);
}

Iterating over all values for a given key

Generation

/*
 * Generate a db with a bunch of different entires, all sharing the
 * same key.
 */

#include <strings.h>
#include <yax/osutil.h>
#include <sys/fcntl.h>
#include "mdbm.h"

int main(int argc, char **argv)
{
    MDBM* db;
    char fn[MAXPATHLEN];
    char buf[2048];
    int num;
    datum key, val;
    int ret;

    strlcpy(fn,yax_getroot(),sizeof(fn));
    strlcat(fn,"/tmp/example.mdbm",sizeof(fn));
    db = mdbm_open(fn,MDBM_O_RDWR|MDBM_O_CREAT,0666,0,0);
    if (!db) {
        perror("Unable to create database");
        exit(2);
    }
    
#define COMMON_KEY_ONE "mykey\0"
#define COMMON_KEY_TWO "fooba\0"

    /* Insert a bunch of different values */
    for (num=0; num<16; num++) {
        if (num%2) {
            key.dptr = COMMON_KEY_ONE;
        } else {
            key.dptr = COMMON_KEY_TWO;
        }
        key.dsize = strlen( key.dptr );

        sprintf(buf, "Value #%d", num);
        val.dptr = buf;
        val.dsize = strlen(buf);

        mdbm_lock(db);
        printf("Storing [%.*s] value [%.*s]\n",
               key.dsize, key.dptr, val.dsize, val.dptr);
        ret = mdbm_store(db, key, val, MDBM_INSERT_DUP);
        mdbm_unlock(db);
        if (ret == -1) {
            perror("Database store failed");
        }
    }
    mdbm_close(db);
}

Iteration

/* Fetch all values for a given key.  Assumes more than on value was
 * inserted for a given key, via mbm_store() and the MDBM_INSERT_DUP.
 */

#include <assert.h>
#include <strings.h>
#include <yax/osutil.h>
#include <sys/fcntl.h>
#include "mdbm.h"

int main(int argc, char **argv)
{
    MDBM* db;
    char fn[MAXPATHLEN];

    MDBM_ITER iter;
    datum key, val;

    strlcpy(fn,yax_getroot(),sizeof(fn));
    strlcat(fn,"/tmp/example.mdbm",sizeof(fn));
    db = mdbm_open(fn,MDBM_O_RDWR,0666,0,0);
    if (!db) {
        perror("Unable to open database");
        exit(2);
    }

#define COMMON_KEY "mykey\0"
    key.dptr = COMMON_KEY;
    key.dsize = strlen(COMMON_KEY);

    MDBM_ITER_INIT( &iter );

    /* Loop through DB, looking at records with the same key.
     */
    while (mdbm_fetch_dup_r( db, &key, &val, &iter ) == 0) {
        printf("Found another: %.*s\n", val.dsize, val.dptr);
    }
    printf("End of db reached.\n");
    mdbm_close(db);
    exit(1);
}