/*
* $Id: t-bdb-secondary-0.c,v 1.1 2005/07/29 22:05:44 ca Exp $
*/
/*
** Just an example program how to use a secondary index;
** taken from the BDB docs.
*/
#include "sm/generic.h"
SM_RCSID("@(#)$Id: t-bdb-secondary-0.c,v 1.1 2005/07/29 22:05:44 ca Exp $")
#include <stdio.h>
#include "sm/bdb.h"
struct student_record
{
char student_id[4];
char last_name[15];
char first_name[15];
};
typedef struct student_record student_record_T;
void
handle_error(int ret)
{
fprintf(stderr, "fail: %d\n", ret);
exit(ret);
}
/*
* getname -- extracts a secondary key (the last name) from a primary key/data
* pair
*/
static int
getname(DB * dbp, const DBT * pkey, const DBT * pdata, DBT * skey)
{
/*
* Since the secondary key is a simple structure member of the record,
* we don't have to do anything fancy to return it. If we have
* composite keys that need to be constructed from the record, rather
* than simply pointing into it, then the user's function might need to
* allocate space and copy data. In this case, the DB_DBT_APPMALLOC
* flag should be set in the secondary key DBT.
*/
memset(skey, 0, sizeof(DBT));
skey->data = ((struct student_record *) pdata->data)->last_name;
skey->size = sizeof((struct student_record *) pdata->data)->last_name;
return (0);
}
static DB *dbp, *sdbp;
void
second(void)
{
int ret;
#define dbenv NULL
/* Open/create primary */
if ((ret = db_create(&dbp, dbenv, 0)) != 0)
handle_error(ret);
if ((ret = dbp->open(dbp, NULL,
"students.db", NULL, DB_BTREE, DB_CREATE, 0600)) != 0)
handle_error(ret);
/*
* Open/create secondary. Note that it supports duplicate data * items,
* since last names might not be unique.
*/
if ((ret = db_create(&sdbp, dbenv, 0)) != 0)
handle_error(ret);
if ((ret = sdbp->set_flags(sdbp, DB_DUP | DB_DUPSORT)) != 0)
handle_error(ret);
if ((ret = sdbp->open(sdbp, NULL, "lastname.db", NULL, DB_BTREE,
DB_CREATE, 0600)) != 0)
handle_error(ret);
/* Associate the secondary with the primary. */
if ((ret = dbp->associate(dbp, NULL, sdbp, getname, 0)) != 0)
handle_error(ret);
}
#define new_student(st, id, last, first) \
do { \
strlcpy((st).student_id, (id), sizeof((st).student_id)); \
strlcpy((st).last_name, (last), sizeof((st).last_name)); \
strlcpy((st).first_name, (first), sizeof((st).first_name)); \
} while (0)
static void
closedb(void)
{
int ret;
if ((ret = dbp->close(dbp, 0)) != 0)
handle_error(ret);
}
static void
putst(student_record_T * s0)
{
int ret;
DBT data, key;
#define txn NULL
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = s0->student_id;
key.size = sizeof(s0->student_id);
data.data = s0;
data.size = sizeof(*s0);
if ((ret = dbp->put(dbp, txn, &key, &data, 0)) != 0)
handle_error(ret);
}
static void
bdb0(void)
{
int ret;
DBT data, key;
DBC *dbcp;
student_record_T s0, s1, s2;
new_student(s0, "id0", "last0", "first0");
new_student(s1, "id1", "last1", "first1");
new_student(s2, "id2", "last2", "first2");
second();
putst(&s0);
putst(&s2);
putst(&s1);
/* Acquire a cursor for the database. */
if ((ret = dbp->cursor(sdbp, NULL, &dbcp, 0)) != 0)
{
sdbp->err(sdbp, ret, "DB->cursor");
goto err;
}
/* Initialize the key/data return pair. */
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
#if 0
while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0)
printf("%.*s : %.*s\n",
(int)key.size, (char *)key.data,
(int)data.size, (char *)data.data);
if (ret != DB_NOTFOUND)
{
sdbp->err(sdbp, ret, "DBcursor->get");
goto err;
}
#else
if ((ret = dbcp->c_get(dbcp, &key, &data, DB_LAST)) == 0)
printf("%.*s : %.*s\n",
(int)key.size, (char *)key.data,
(int)data.size, (char *)data.data);
if ((ret = dbcp->c_del(dbcp, 0)) != 0)
sdbp->err(sdbp, ret, "DBcursor->c_del");
if ((ret = dbcp->c_get(dbcp, &key, &data, DB_LAST)) == 0)
printf("%.*s : %.*s\n",
(int)key.size, (char *)key.data,
(int)data.size, (char *)data.data);
#endif
err:
if ((ret = dbcp->c_close(dbcp)) != 0)
{
sdbp->err(sdbp, ret, "DBcursor->close");
}
closedb();
}
static void
usage(const char *prg)
{
exit(-1);
}
int
main(int argc, char **argv)
{
int ch;
while ((ch = getopt(argc, argv, "V")) != -1)
{
switch (ch)
{
default:
usage(argv[0]);
return -1;
}
}
bdb0();
return (0);
}
syntax highlighted by Code2HTML, v. 0.9.1