How to Use Berkeley DB

Download and Build

  1. Download the source code tarball from http://www.oracle.com/technetwork/database/berkeleydb/downloads/index.html
  2. Unpack the tarball and change directory into db-5.1.19/build_unix.
  3. configure –prefix=… –enable-cxx –enable-stl && make && make install

References

  1. Getting Started with Berkeley DB (C++ Edition)

    http://download.oracle.com/docs/cd/E17076_02/html/gsg/CXX/index.html

    This is a must-read one with code snippets for newcomers.

  2. Berkeley DB Programmer’s Reference Guide

    http://download.oracle.com/docs/cd/E17076_02/html/programmer_reference/index.html

    This comes with more details. Particularly, Chapter 7 introduces DBSTL with examples.

  3. Berkeley DB C++ API Reference

    http://download.oracle.com/docs/cd/E17076_02/html/api_reference/CXX/frame_main.html

  4. Berkeley DB C++ Standard Template Library API Reference

    http://download.oracle.com/docs/cd/E17076_02/html/api_reference/STL/frame_main.html

Code Snippets

Utilities

You can use db_dump provided by Berkeley DB to dump the database file generated by the following examples.

Example in C

#include <stdlib.h>
#include <string.h>

#include <iostream>
#include <iomanip>
#include <string>

#define HAVE_CXX_STDHEADERS
#include <db_cxx.h>

using namespace std;

const char* kDatabaseName = "access.db";

int main() {
  DB *dbp;
  DBT key, data;
  int ret, t_ret;

  if ((ret = db_create(&dbp, NULL, 0)) != 0) {
    cerr << "db_create:" << db_strerror(ret) << endl;
    exit (1);
  }

  if ((ret = dbp->open(dbp, NULL, kDatabaseName, "",
                       DB_BTREE, DB_CREATE, 0664)) != 0) {
    dbp->err(dbp, ret, "%s", kDatabaseName);
    goto err;
  }

  memset(&key, 0, sizeof(key));
  memset(&data, 0, sizeof(data));
  key.data = (char*)"fruit";
  key.size = sizeof("fruit");
  data.data = (char*)"apple";
  data.size = sizeof("apple");

  if ((ret = dbp->put(dbp, NULL, &key, &data, 0)) == 0)
    cout << "db: " << (char*)key.data << ": key stored.\n";
  else {
    dbp->err(dbp, ret, "DB->put");
    goto err;
  }

  if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) == 0)
    cout << "db: " << (char*)key.data
         << ": key retrieved: data was " << (char *)data.data << endl;
  else {
    dbp->err(dbp, ret, "DB->get");
    goto err;
  }

  if ((ret = dbp->del(dbp, NULL, &key, 0)) == 0)
    cout << "db: " << (char*)key.data << " key was deleted.\n";
  else {
    dbp->err(dbp, ret, "DB->del");
    goto err;
  }

  if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) == 0)
    cout << "db: " << (char*)key.data << ": key retrieved: data was "
         << (char *)data.data << endl;
  else
    dbp->err(dbp, ret, "DB->get");

err:
  if ((t_ret = dbp->close(dbp, 0)) != 0 && ret == 0)
    ret = t_ret;

  return ret;
}

Examples in C++

#include <stdlib.h>
#include <string.h>

#include <iostream>
#include <iomanip>
#include <string>

#include <db_cxx.h>

using namespace std;

const char* kDatabaseName = "access.db";

int main() {

  string fruit("fruit");
  string apple("apple");
  string orange("orange");

  DbEnv env(0);
  Db* pdb;

  try {
    env.set_error_stream(&cerr);
    env.open("/Users/wangyi/db", DB_CREATE | DB_INIT_MPOOL, 0);

    pdb = new Db(&env, 0);
    // If you want to support duplicated records and make duplicated
    // records sorted by data, you need to call:
    //   pdb->set_flags(DB_DUPSORT);
    // Note that only Btree-typed database supports sorted duplicated
    // records

    // If the database does not exist, create it.  If it exists, clear
    // its content after openning.
    pdb->open(NULL, "access.db", NULL, DB_BTREE, DB_CREATE | DB_TRUNCATE, 0);

    Dbt key(const_cast<char*>(fruit.data()), fruit.size());
    Dbt value(const_cast<char*>(apple.data()), apple.size()+1);
    pdb->put(NULL, &key, &value, 0);

    Dbt value_orange(const_cast<char*>(orange.data()), orange.size()+1);
    pdb->put(NULL, &key, &value_orange, 0);

    // You need to set ulen and flags=DB_DBT_USERMEM to prevent Dbt
    // from allocate its own memory but use the memory provided by you.
    char buffer[1024];
    Dbt data;
    data.set_data(buffer);
    data.set_ulen(1024);
    data.set_flags(DB_DBT_USERMEM);
    if (pdb->get(NULL, &key, &data, 0) == DB_NOTFOUND) {
      cerr << "Not found" << endl;
    } else {
      cout << "Found: " << buffer << endl;
    }

    if (pdb != NULL) {
      pdb->close(0);
      delete pdb;
      // You have to close and delete an exisiting handle, then create
      // a new one before you can use it to remove a database (file).
      pdb = new Db(NULL, 0);
      pdb->remove("/Users/wangyi/db/access.db", NULL, 0);
      delete pdb;
    }
    env.close(0);
  } catch (DbException& e) {
    cerr << "DbException: " << e.what() << endl;
    return -1;
  } catch (std::exception& e) {
    cerr << e.what() << endl;
    return -1;
  }

  return 0;
}

Examples in DBSTL

#include <iostream>
#include <iomanip>
#include <string>

#include <db_cxx.h>
#include <dbstl_map.h>

using namespace std;

const char* kDatabaseName = "access.db";

int main() {

  string fruit("fruit");
  string apple("apple");
  string orange("orange");

  DbEnv env(DB_CXX_NO_EXCEPTIONS);
  Db* pdb;

  try {
    env.set_error_stream(&cerr);
    env.open("/Users/wangyi/db", DB_CREATE | DB_INIT_MPOOL, 0);

    pdb = new Db(&env, DB_CXX_NO_EXCEPTIONS);
    pdb->open(NULL, "access.db", NULL, DB_BTREE, DB_CREATE, 0);

    // In order to use db_map with an explicitly specified database,
    // - the database and its environment must be constructed with
    //   DB_CXX_NO_EXCEPTIONS flag set.
    // - do not specify DB_TRUNCATE flag in Db::open.
    typedef dbstl::db_map<string, string> HugeMap;
    HugeMap huge_map(pdb, &env);

    for (char c = 0; c < 26; ++c) {
      string key, value;
      key += (static_cast<char>(c + 'a'));
      value += (static_cast<char>('z' - c));
      huge_map[key] = value;
    }

    for (HugeMap::iterator i = huge_map.begin(); i != huge_map.end(); ++i) {
      cout << i->first << " : " << i->second << "\n";
    }

    if (pdb != NULL) {
      pdb->close(0);
      delete pdb;
    }
    env.close(0);

  } catch (DbException& e) {
    cerr << "DbException: " << e.what() << endl;
    return -1;
  } catch (std::exception& e) {
    cerr << e.what() << endl;
    return -1;
  }

  return 0;
}

Build Programs

If your program uses only the C API (like the first example program), link against libdb. If it uses the C++ API, link against libdb_cxx. If it uses the DBSTL API, link against libdb_stl.

About these ads

One Response to How to Use Berkeley DB

  1. PD says:

    Thanks, this was useful.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 28 other followers

%d bloggers like this: