diff options
Diffstat (limited to 'bdb/examples_cxx/BtRecExample.cpp')
-rw-r--r-- | bdb/examples_cxx/BtRecExample.cpp | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/bdb/examples_cxx/BtRecExample.cpp b/bdb/examples_cxx/BtRecExample.cpp new file mode 100644 index 00000000000..98d9626b969 --- /dev/null +++ b/bdb/examples_cxx/BtRecExample.cpp @@ -0,0 +1,247 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997, 1998, 1999, 2000 + * Sleepycat Software. All rights reserved. + * + * $Id: BtRecExample.cpp,v 11.6 2000/02/19 20:57:59 bostic Exp $ + */ + +#include "db_config.h" + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> +#include <errno.h> +#include <iostream.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#endif + +#include <iomanip.h> +#include <db_cxx.h> + +#define DATABASE "access.db" +#define WORDLIST "../test/wordlist" + +void usage(); +extern "C" int getopt(int, char * const *, const char *); + +char *progname = "BtRecExample"; // Program name. + +class BtRecExample +{ +public: + BtRecExample(FILE *fp); + ~BtRecExample(); + void run(); + void stats(); + void show(char *msg, Dbt *key, Dbt *data); + +private: + Db *dbp; + Dbc *dbcp; +}; + +BtRecExample::BtRecExample(FILE *fp) +{ + char *p, *t, buf[1024], rbuf[1024]; + int ret; + + // Remove the previous database. + (void)unlink(DATABASE); + + dbp = new Db(NULL, 0); + + dbp->set_error_stream(&cerr); + dbp->set_errpfx(progname); + dbp->set_pagesize(1024); // 1K page sizes. + + dbp->set_flags(DB_RECNUM); // Record numbers. + dbp->open(DATABASE, NULL, DB_BTREE, DB_CREATE, 0664); + + // + // Insert records into the database, where the key is the word + // preceded by its record number, and the data is the same, but + // in reverse order. + // + + for (int cnt = 1; cnt <= 1000; ++cnt) { + (void)sprintf(buf, "%04d_", cnt); + if (fgets(buf + 4, sizeof(buf) - 4, fp) == NULL) + break; + u_int32_t len = strlen(buf); + buf[len - 1] = '\0'; + for (t = rbuf, p = buf + (len - 2); p >= buf;) + *t++ = *p--; + *t++ = '\0'; + + // As a convenience for printing, we include the null terminator + // in the stored data. + // + Dbt key(buf, len); + Dbt data(rbuf, len); + + if ((ret = dbp->put(NULL, &key, &data, DB_NOOVERWRITE)) != 0) { + dbp->err(ret, "Db::put"); + if (ret != DB_KEYEXIST) + throw DbException(ret); + } + } +} + +BtRecExample::~BtRecExample() +{ + if (dbcp != 0) + dbcp->close(); + dbp->close(0); + delete dbp; +} + +// +// Print out the number of records in the database. +// +void BtRecExample::stats() +{ + DB_BTREE_STAT *statp; + + dbp->stat(&statp, NULL, 0); + cout << progname << ": database contains " + << (u_long)statp->bt_ndata << " records\n"; + + // Note: must use free, not delete. + // This struct is allocated by C. + // + free(statp); +} + +void BtRecExample::run() +{ + db_recno_t recno; + int ret; + char buf[1024]; + + // Acquire a cursor for the database. + dbp->cursor(NULL, &dbcp, 0); + + // + // Prompt the user for a record number, then retrieve and display + // that record. + // + for (;;) { + // Get a record number. + cout << "recno #> "; + cout.flush(); + if (fgets(buf, sizeof(buf), stdin) == NULL) + break; + recno = atoi(buf); + + // + // Start with a fresh key each time, + // the dbp->get() routine returns + // the key and data pair, not just the key! + // + Dbt key(&recno, sizeof(recno)); + Dbt data; + + if ((ret = dbcp->get(&key, &data, DB_SET_RECNO)) != 0) { + dbp->err(ret, "DBcursor->get"); + throw DbException(ret); + } + + // Display the key and data. + show("k/d\t", &key, &data); + + // Move the cursor a record forward. + if ((ret = dbcp->get(&key, &data, DB_NEXT)) != 0) { + dbp->err(ret, "DBcursor->get"); + throw DbException(ret); + } + + // Display the key and data. + show("next\t", &key, &data); + + // + // Retrieve the record number for the following record into + // local memory. + // + data.set_data(&recno); + data.set_size(sizeof(recno)); + data.set_ulen(sizeof(recno)); + data.set_flags(data.get_flags() | DB_DBT_USERMEM); + + if ((ret = dbcp->get(&key, &data, DB_GET_RECNO)) != 0) { + if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY) { + dbp->err(ret, "DBcursor->get"); + throw DbException(ret); + } + } + else { + cout << "retrieved recno: " << (u_long)recno << "\n"; + } + } + + dbcp->close(); + dbcp = NULL; +} + +// +// show -- +// Display a key/data pair. +// +void BtRecExample::show(char *msg, Dbt *key, Dbt *data) +{ + cout << msg << (char *)key->get_data() + << " : " << (char *)data->get_data() << "\n"; +} + +int +main(int argc, char *argv[]) +{ + extern char *optarg; + extern int optind; + FILE *fp; + int ch; + + while ((ch = getopt(argc, argv, "")) != EOF) + switch (ch) { + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + // Open the word database. + if ((fp = fopen(WORDLIST, "r")) == NULL) { + fprintf(stderr, "%s: open %s: %s\n", + progname, WORDLIST, db_strerror(errno)); + exit (1); + } + + try { + BtRecExample app(fp); + + // Close the word database. + (void)fclose(fp); + fp = NULL; + + app.stats(); + app.run(); + } + catch (DbException &dbe) { + cerr << "Exception: " << dbe.what() << "\n"; + return dbe.get_errno(); + } + + return (0); +} + +void +usage() +{ + (void)fprintf(stderr, "usage: %s\n", progname); + exit(1); +} |