Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

BtRecExample.cpp

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1997-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: BtRecExample.cpp,v 12.1 2005/06/16 20:22:14 bostic Exp $
00008  */
00009 
00010 #include <sys/types.h>
00011 
00012 #include <errno.h>
00013 #include <iostream>
00014 #include <iomanip>
00015 #include <stddef.h>
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include <string.h>
00019 
00020 #include <db_cxx.h>
00021 
00022 using std::cout;
00023 using std::cerr;
00024 
00025 #define DATABASE        "access.db"
00026 #define WORDLIST        "../test/wordlist"
00027 
00028 const char *progname = "BtRecExample";          // Program name.
00029 
00030 class BtRecExample
00031 {
00032 public:
00033         BtRecExample(FILE *fp);
00034         ~BtRecExample();
00035         void run();
00036         void stats();
00037         void show(const char *msg, Dbt *key, Dbt *data);
00038 
00039 private:
00040         Db *dbp;
00041         Dbc *dbcp;
00042 };
00043 
00044 BtRecExample::BtRecExample(FILE *fp)
00045 {
00046         char *p, *t, buf[1024], rbuf[1024];
00047         int ret;
00048 
00049         // Remove the previous database.
00050         (void)remove(DATABASE);
00051 
00052         dbp = new Db(NULL, 0);
00053 
00054         dbp->set_error_stream(&cerr);
00055         dbp->set_errpfx(progname);
00056         dbp->set_pagesize(1024);                        // 1K page sizes.
00057 
00058         dbp->set_flags(DB_RECNUM);                      // Record numbers.
00059         dbp->open(NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664);
00060 
00061         //
00062         // Insert records into the database, where the key is the word
00063         // preceded by its record number, and the data is the same, but
00064         // in reverse order.
00065         //
00066 
00067         for (int cnt = 1; cnt <= 1000; ++cnt) {
00068                 (void)sprintf(buf, "%04d_", cnt);
00069                 if (fgets(buf + 4, sizeof(buf) - 4, fp) == NULL)
00070                         break;
00071                 u_int32_t len = (u_int32_t)strlen(buf);
00072                 buf[len - 1] = '\0';
00073                 for (t = rbuf, p = buf + (len - 2); p >= buf;)
00074                         *t++ = *p--;
00075                 *t++ = '\0';
00076 
00077                 // As a convenience for printing, we include the null terminator
00078                 // in the stored data.
00079                 //
00080                 Dbt key(buf, len);
00081                 Dbt data(rbuf, len);
00082 
00083                 if ((ret = dbp->put(NULL, &key, &data, DB_NOOVERWRITE)) != 0) {
00084                         dbp->err(ret, "Db::put");
00085                         if (ret != DB_KEYEXIST)
00086                                 throw DbException(ret);
00087                 }
00088         }
00089 }
00090 
00091 BtRecExample::~BtRecExample()
00092 {
00093         if (dbcp != 0)
00094                 dbcp->close();
00095         dbp->close(0);
00096         delete dbp;
00097 }
00098 
00099 //
00100 // Print out the number of records in the database.
00101 //
00102 void BtRecExample::stats()
00103 {
00104         DB_BTREE_STAT *statp;
00105 
00106         dbp->stat(NULL, &statp, 0);
00107         cout << progname << ": database contains "
00108              << (u_long)statp->bt_ndata << " records\n";
00109 
00110         // Note: must use free, not delete.
00111         // This struct is allocated by C.
00112         //
00113         free(statp);
00114 }
00115 
00116 void BtRecExample::run()
00117 {
00118         db_recno_t recno;
00119         int ret;
00120         char buf[1024];
00121 
00122         // Acquire a cursor for the database.
00123         dbp->cursor(NULL, &dbcp, 0);
00124 
00125         //
00126         // Prompt the user for a record number, then retrieve and display
00127         // that record.
00128         //
00129         for (;;) {
00130                 // Get a record number.
00131                 cout << "recno #> ";
00132                 cout.flush();
00133                 if (fgets(buf, sizeof(buf), stdin) == NULL)
00134                         break;
00135                 recno = atoi(buf);
00136 
00137                 //
00138                 // Start with a fresh key each time,
00139                 // the dbp->get() routine returns
00140                 // the key and data pair, not just the key!
00141                 //
00142                 Dbt key(&recno, sizeof(recno));
00143                 Dbt data;
00144 
00145                 if ((ret = dbcp->get(&key, &data, DB_SET_RECNO)) != 0) {
00146                         dbp->err(ret, "DBcursor->get");
00147                         throw DbException(ret);
00148                 }
00149 
00150                 // Display the key and data.
00151                 show("k/d\t", &key, &data);
00152 
00153                 // Move the cursor a record forward.
00154                 if ((ret = dbcp->get(&key, &data, DB_NEXT)) != 0) {
00155                         dbp->err(ret, "DBcursor->get");
00156                         throw DbException(ret);
00157                 }
00158 
00159                 // Display the key and data.
00160                 show("next\t", &key, &data);
00161 
00162                 //
00163                 // Retrieve the record number for the following record into
00164                 // local memory.
00165                 //
00166                 data.set_data(&recno);
00167                 data.set_size(sizeof(recno));
00168                 data.set_ulen(sizeof(recno));
00169                 data.set_flags(data.get_flags() | DB_DBT_USERMEM);
00170 
00171                 if ((ret = dbcp->get(&key, &data, DB_GET_RECNO)) != 0) {
00172                         if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY) {
00173                                 dbp->err(ret, "DBcursor->get");
00174                                 throw DbException(ret);
00175                         }
00176                 }
00177                 else {
00178                         cout << "retrieved recno: " << (u_long)recno << "\n";
00179                 }
00180         }
00181 
00182         dbcp->close();
00183         dbcp = NULL;
00184 }
00185 
00186 //
00187 // show --
00188 //      Display a key/data pair.
00189 //
00190 void BtRecExample::show(const char *msg, Dbt *key, Dbt *data)
00191 {
00192         cout << msg << (char *)key->get_data()
00193              << " : " << (char *)data->get_data() << "\n";
00194 }
00195 
00196 int
00197 main()
00198 {
00199         FILE *fp;
00200 
00201         // Open the word database.
00202         if ((fp = fopen(WORDLIST, "r")) == NULL) {
00203                 fprintf(stderr, "%s: open %s: %s\n",
00204                         progname, WORDLIST, db_strerror(errno));
00205                 return (EXIT_FAILURE);
00206         }
00207 
00208         try {
00209                 BtRecExample app(fp);
00210 
00211                 // Close the word database.
00212                 (void)fclose(fp);
00213                 fp = NULL;
00214 
00215                 app.stats();
00216                 app.run();
00217         }
00218         catch (DbException &dbe) {
00219                 cerr << "Exception: " << dbe.what() << "\n";
00220                 return (EXIT_FAILURE);
00221         }
00222 
00223         return (EXIT_SUCCESS);
00224 }

Generated on Sun Dec 25 12:14:25 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2