Download and Build
- Download the source code tarball from http://www.oracle.com/technetwork/database/berkeleydb/downloads/index.html
- Unpack the tarball and change directory into db-5.1.19/build_unix.
- configure –prefix=… –enable-cxx –enable-stl && make && make install
References
- 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.
- 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.
- Berkeley DB C++ API Reference
http://download.oracle.com/docs/cd/E17076_02/html/api_reference/CXX/frame_main.html
- 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.