1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1997,2008 Oracle. All rights reserved. 5 * 6 * $Id: AccessExample.cpp,v 12.6 2008/01/08 20:58:26 bostic Exp $ 7 */ 8 9#include <sys/types.h> 10 11#include <iostream> 12#include <iomanip> 13#include <errno.h> 14#include <stdlib.h> 15#include <string.h> 16 17#ifdef _WIN32 18extern "C" { 19 extern int getopt(int, char * const *, const char *); 20 extern int optind; 21} 22#else 23#include <unistd.h> 24#endif 25 26#include <db_cxx.h> 27 28#define DATABASE "access.db" 29 30using std::cin; 31using std::cout; 32using std::cerr; 33 34class AccessExample 35{ 36public: 37 AccessExample(); 38 void run(bool removeExistingDatabase, const char *fileName); 39 40private: 41 // no need for copy and assignment 42 AccessExample(const AccessExample &); 43 void operator = (const AccessExample &); 44}; 45 46int 47usage() 48{ 49 (void)fprintf(stderr, "usage: AccessExample [-r] [database]\n"); 50 return (EXIT_FAILURE); 51} 52 53int 54main(int argc, char *argv[]) 55{ 56 int ch, rflag; 57 const char *database; 58 59 rflag = 0; 60 while ((ch = getopt(argc, argv, "r")) != EOF) 61 switch (ch) { 62 case 'r': 63 rflag = 1; 64 break; 65 case '?': 66 default: 67 return (usage()); 68 } 69 argc -= optind; 70 argv += optind; 71 72 /* Accept optional database name. */ 73 database = *argv == NULL ? DATABASE : argv[0]; 74 75 // Use a try block just to report any errors. 76 // An alternate approach to using exceptions is to 77 // use error models (see DbEnv::set_error_model()) so 78 // that error codes are returned for all Berkeley DB methods. 79 // 80 try { 81 AccessExample app; 82 app.run((bool)(rflag == 1 ? true : false), database); 83 return (EXIT_SUCCESS); 84 } 85 catch (DbException &dbe) { 86 cerr << "AccessExample: " << dbe.what() << "\n"; 87 return (EXIT_FAILURE); 88 } 89} 90 91AccessExample::AccessExample() 92{ 93} 94 95void AccessExample::run(bool removeExistingDatabase, const char *fileName) 96{ 97 // Remove the previous database. 98 if (removeExistingDatabase) 99 (void)remove(fileName); 100 101 // Create the database object. 102 // There is no environment for this simple example. 103 Db db(0, 0); 104 105 db.set_error_stream(&cerr); 106 db.set_errpfx("AccessExample"); 107 db.set_pagesize(1024); /* Page size: 1K. */ 108 db.set_cachesize(0, 32 * 1024, 0); 109 db.open(NULL, fileName, NULL, DB_BTREE, DB_CREATE, 0664); 110 111 // 112 // Insert records into the database, where the key is the user 113 // input and the data is the user input in reverse order. 114 // 115 char buf[1024], rbuf[1024]; 116 char *p, *t; 117 int ret; 118 u_int32_t len; 119 120 for (;;) { 121 cout << "input> "; 122 cout.flush(); 123 124 cin.getline(buf, sizeof(buf)); 125 if (cin.eof()) 126 break; 127 128 if ((len = (u_int32_t)strlen(buf)) <= 0) 129 continue; 130 for (t = rbuf, p = buf + (len - 1); p >= buf;) 131 *t++ = *p--; 132 *t++ = '\0'; 133 134 Dbt key(buf, len + 1); 135 Dbt data(rbuf, len + 1); 136 137 ret = db.put(0, &key, &data, DB_NOOVERWRITE); 138 if (ret == DB_KEYEXIST) { 139 cout << "Key " << buf << " already exists.\n"; 140 } 141 } 142 cout << "\n"; 143 144 // We put a try block around this section of code 145 // to ensure that our database is properly closed 146 // in the event of an error. 147 // 148 try { 149 // Acquire a cursor for the table. 150 Dbc *dbcp; 151 db.cursor(NULL, &dbcp, 0); 152 153 // Walk through the table, printing the key/data pairs. 154 Dbt key; 155 Dbt data; 156 while (dbcp->get(&key, &data, DB_NEXT) == 0) { 157 char *key_string = (char *)key.get_data(); 158 char *data_string = (char *)data.get_data(); 159 cout << key_string << " : " << data_string << "\n"; 160 } 161 dbcp->close(); 162 } 163 catch (DbException &dbe) { 164 cerr << "AccessExample: " << dbe.what() << "\n"; 165 } 166 167 db.close(0); 168} 169