189 lines
4.4 KiB
C
189 lines
4.4 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "db.h"
|
|
|
|
// refer: https://docs.oracle.com/cd/E17076_05/html/gsg/C/BerkeleyDB-Core-C-GSG.pdf
|
|
|
|
// Access Methods:
|
|
// 1. BTree
|
|
// 2. Hash
|
|
// 3. Queue
|
|
// 4. Recno
|
|
|
|
// Use secondary database work as index.
|
|
// Any attemp to write to a secondary database results in a non-zero status return.
|
|
|
|
static int idx_callback(DB *dbp, const DBT *keyp, const DBT *valuep, DBT *resvp);
|
|
|
|
#define USE_ENV 0
|
|
|
|
#define DESCRIPTION_SIZE 128
|
|
float money = 122.45;
|
|
char *description = "Grocery bill.";
|
|
|
|
typedef struct {
|
|
int id;
|
|
char *family_name;
|
|
char *surname;
|
|
} SPersion;
|
|
|
|
static void put_value(DB *dbp) {
|
|
DBT key = {0};
|
|
DBT value = {0};
|
|
int ret;
|
|
|
|
key.data = &money;
|
|
key.size = sizeof(money);
|
|
|
|
value.data = description;
|
|
value.size = strlen(description) + 1;
|
|
|
|
ret = dbp->put(dbp, NULL, &key, &value, DB_NOOVERWRITE);
|
|
if (ret != 0) {
|
|
fprintf(stderr, "Failed to put DB record: %s\n", db_strerror(ret));
|
|
}
|
|
}
|
|
|
|
static void get_value(DB *dbp) {
|
|
char desp[DESCRIPTION_SIZE];
|
|
DBT key = {0};
|
|
DBT value = {0};
|
|
|
|
key.data = &money;
|
|
key.size = sizeof(money);
|
|
|
|
value.data = desp;
|
|
value.ulen = DESCRIPTION_SIZE;
|
|
value.flags = DB_DBT_USERMEM;
|
|
|
|
dbp->get(dbp, NULL, &key, &value, 0);
|
|
printf("The value is \"%s\"\n", desp);
|
|
}
|
|
|
|
int main(int argc, char const *argv[]) {
|
|
DB * dbp = NULL;
|
|
DB * sdbp = NULL;
|
|
u_int32_t db_flags;
|
|
DB_ENV * envp = NULL;
|
|
u_int32_t env_flags;
|
|
int ret;
|
|
DBT key = {0};
|
|
DBT value = {0};
|
|
|
|
#if USE_ENV
|
|
// Initialize an env object and open it for
|
|
ret = db_env_create(&envp, 0);
|
|
if (ret != 0) {
|
|
fprintf(stderr, "Error creating env handle: %s\n", db_strerror(ret));
|
|
return -1;
|
|
}
|
|
|
|
env_flags = DB_CREATE | DB_INIT_MPOOL;
|
|
|
|
ret = envp->open(envp, "./meta", env_flags, 0);
|
|
if (ret != 0) {
|
|
fprintf(stderr, "Error opening env handle: %s\n", db_strerror(ret));
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
// Initialize a DB handle and open the DB
|
|
ret = db_create(&dbp, envp, 0);
|
|
if (ret != 0) {
|
|
exit(1);
|
|
}
|
|
|
|
ret = db_create(&sdbp, envp, 0);
|
|
if (ret != 0) {
|
|
exit(1);
|
|
}
|
|
|
|
ret = sdbp->set_flags(sdbp, DB_DUPSORT);
|
|
if (ret != 0) {
|
|
exit(1);
|
|
}
|
|
|
|
db_flags = DB_CREATE | DB_TRUNCATE;
|
|
ret = dbp->open(dbp, /* DB structure pointer */
|
|
NULL, /* Transaction pointer */
|
|
"meta.db", /* On-disk file that holds the database */
|
|
NULL, /* Optional logical database name */
|
|
DB_BTREE, /* Database access method */
|
|
db_flags, /* Open flags */
|
|
0); /* File mode */
|
|
if (ret != 0) {
|
|
exit(1);
|
|
}
|
|
|
|
ret = sdbp->open(sdbp, /* DB structure pointer */
|
|
NULL, /* Transaction pointer */
|
|
"index.db", /* On-disk file that holds the database */
|
|
NULL, /* Optional logical database name */
|
|
DB_BTREE, /* Database access method */
|
|
db_flags, /* Open flags */
|
|
0); /* File mode */
|
|
if (ret != 0) {
|
|
exit(1);
|
|
}
|
|
|
|
// Associate the secondary database to the primary
|
|
dbp->associate(dbp, /* Primary database */
|
|
NULL, /* TXN id */
|
|
sdbp, /* Secondary database */
|
|
idx_callback, /* Callback used for key creation */
|
|
0); /* Flags */
|
|
|
|
{
|
|
// Insert a key-value record
|
|
put_value(dbp);
|
|
|
|
// Read the key-value record
|
|
get_value(dbp);
|
|
}
|
|
|
|
// Close the database
|
|
if (sdbp != NULL) {
|
|
sdbp->close(sdbp, 0);
|
|
}
|
|
|
|
if (dbp != NULL) {
|
|
dbp->close(dbp, 0);
|
|
}
|
|
|
|
if (envp != NULL) {
|
|
envp->close(envp, 0);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int idx_callback(DB * sdbp, /* secondary db handle */
|
|
const DBT *keyp, /* primary db record's key */
|
|
const DBT *valuep, /* primary db record's value */
|
|
DBT * skeyp /* secondary db record's key*/
|
|
) {
|
|
DBT *tmpdbt;
|
|
|
|
tmpdbt = (DBT *)calloc(2, sizeof(DBT));
|
|
|
|
{ // TODO
|
|
tmpdbt[0].data = NULL;
|
|
tmpdbt[0].size = 0;
|
|
|
|
tmpdbt[1].data = NULL;
|
|
tmpdbt[1].size = 0;
|
|
}
|
|
|
|
/**
|
|
* DB_DBT_MULTIPLE means DBT references an array
|
|
* DB_DBT_APPMALLOC means we dynamically allocated memory for the DBT's data field.
|
|
*/
|
|
skeyp->flags = DB_DBT_MULTIPLE | DB_DBT_APPMALLOC;
|
|
skeyp->size = 2;
|
|
skeyp->data = tmpdbt;
|
|
|
|
return 0;
|
|
}
|