#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#define DATABASE "access.db"
#define WORDLIST "../test/wordlist"
int main __P((void));
int ex_btrec __P((void));
void show __P((const char *, DBT *, DBT *));
int
main()
{
return (ex_btrec() == 1 ? EXIT_FAILURE : EXIT_SUCCESS);
}
int
ex_btrec()
{
DB *dbp;
DBC *dbcp;
DBT key, data;
DB_BTREE_STAT *statp;
FILE *fp;
db_recno_t recno;
u_int32_t len;
int cnt, ret;
char *p, *t, buf[1024], rbuf[1024];
const char *progname = "ex_btrec";
if ((fp = fopen(WORDLIST, "r")) == NULL) {
fprintf(stderr, "%s: open %s: %s\n",
progname, WORDLIST, db_strerror(errno));
return (1);
}
(void)remove(DATABASE);
if ((ret = db_create(&dbp, NULL, 0)) != 0) {
fprintf(stderr,
"%s: db_create: %s\n", progname, db_strerror(ret));
return (1);
}
dbp->set_errfile(dbp, stderr);
dbp->set_errpfx(dbp, progname);
if ((ret = dbp->set_pagesize(dbp, 1024)) != 0) {
dbp->err(dbp, ret, "set_pagesize");
return (1);
}
if ((ret = dbp->set_flags(dbp, DB_RECNUM)) != 0) {
dbp->err(dbp, ret, "set_flags: DB_RECNUM");
return (1);
}
if ((ret = dbp->open(dbp,
NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
dbp->err(dbp, ret, "open: %s", DATABASE);
return (1);
}
memset(&key, 0, sizeof(DBT));
memset(&data, 0, sizeof(DBT));
for (cnt = 1; cnt <= 1000; ++cnt) {
(void)sprintf(buf, "%04d_", cnt);
if (fgets(buf + 4, sizeof(buf) - 4, fp) == NULL)
break;
len = strlen(buf);
for (t = rbuf, p = buf + (len - 2); p >= buf;)
*t++ = *p--;
*t++ = '\0';
key.data = buf;
data.data = rbuf;
data.size = key.size = len - 1;
if ((ret =
dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE)) != 0) {
dbp->err(dbp, ret, "DB->put");
if (ret != DB_KEYEXIST)
goto err1;
}
}
(void)fclose(fp);
if ((ret = dbp->stat(dbp, &statp, 0)) != 0) {
dbp->err(dbp, ret, "DB->stat");
goto err1;
}
printf("%s: database contains %lu records\n",
progname, (u_long)statp->bt_ndata);
free(statp);
if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) {
dbp->err(dbp, ret, "DB->cursor");
goto err1;
}
for (;;) {
printf("recno #> ");
fflush(stdout);
if (fgets(buf, sizeof(buf), stdin) == NULL)
break;
recno = atoi(buf);
key.data = &recno;
key.size = sizeof(recno);
if ((ret = dbcp->c_get(dbcp, &key, &data, DB_SET_RECNO)) != 0)
goto get_err;
show("k/d\t", &key, &data);
if ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) != 0)
goto get_err;
show("next\t", &key, &data);
data.data = &recno;
data.size = sizeof(recno);
data.ulen = sizeof(recno);
data.flags |= DB_DBT_USERMEM;
if ((ret = dbcp->c_get(dbcp, &key, &data, DB_GET_RECNO)) != 0) {
get_err: dbp->err(dbp, ret, "DBcursor->get");
if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY)
goto err2;
} else
printf("retrieved recno: %lu\n", (u_long)recno);
memset(&data, 0, sizeof(data));
}
if ((ret = dbcp->c_close(dbcp)) != 0) {
dbp->err(dbp, ret, "DBcursor->close");
goto err1;
}
if ((ret = dbp->close(dbp, 0)) != 0) {
fprintf(stderr,
"%s: DB->close: %s\n", progname, db_strerror(ret));
return (1);
}
return (0);
err2: (void)dbcp->c_close(dbcp);
err1: (void)dbp->close(dbp, 0);
return (ret);
}
void
show(msg, key, data)
const char *msg;
DBT *key, *data;
{
printf("%s%.*s : %.*s\n", msg,
(int)key->size, (char *)key->data,
(int)data->size, (char *)data->data);
}