BtRecExample.cpp
Upload User: tsgydb
Upload Date: 2007-04-14
Package Size: 10674k
Code Size: 5k
Category:

MySQL

Development Platform:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1997, 1998, 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  *
  7.  * $Id: BtRecExample.cpp,v 11.6 2000/02/19 20:57:59 bostic Exp $
  8.  */
  9. #include "db_config.h"
  10. #ifndef NO_SYSTEM_INCLUDES
  11. #include <sys/types.h>
  12. #include <errno.h>
  13. #include <iostream.h>
  14. #include <stddef.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <unistd.h>
  19. #endif
  20. #include <iomanip.h>
  21. #include <db_cxx.h>
  22. #define DATABASE "access.db"
  23. #define WORDLIST "../test/wordlist"
  24. void usage();
  25. extern "C" int getopt(int, char * const *, const char *);
  26. char *progname = "BtRecExample"; // Program name.
  27. class BtRecExample
  28. {
  29. public:
  30. BtRecExample(FILE *fp);
  31. ~BtRecExample();
  32. void run();
  33. void stats();
  34. void show(char *msg, Dbt *key, Dbt *data);
  35. private:
  36. Db *dbp;
  37. Dbc *dbcp;
  38. };
  39. BtRecExample::BtRecExample(FILE *fp)
  40. {
  41. char *p, *t, buf[1024], rbuf[1024];
  42. int ret;
  43. // Remove the previous database.
  44. (void)unlink(DATABASE);
  45. dbp = new Db(NULL, 0);
  46. dbp->set_error_stream(&cerr);
  47. dbp->set_errpfx(progname);
  48. dbp->set_pagesize(1024); // 1K page sizes.
  49. dbp->set_flags(DB_RECNUM); // Record numbers.
  50. dbp->open(DATABASE, NULL, DB_BTREE, DB_CREATE, 0664);
  51. //
  52. // Insert records into the database, where the key is the word
  53. // preceded by its record number, and the data is the same, but
  54. // in reverse order.
  55. //
  56. for (int cnt = 1; cnt <= 1000; ++cnt) {
  57. (void)sprintf(buf, "%04d_", cnt);
  58. if (fgets(buf + 4, sizeof(buf) - 4, fp) == NULL)
  59. break;
  60. u_int32_t len = strlen(buf);
  61. buf[len - 1] = '';
  62. for (t = rbuf, p = buf + (len - 2); p >= buf;)
  63. *t++ = *p--;
  64. *t++ = '';
  65. // As a convenience for printing, we include the null terminator
  66. // in the stored data.
  67. //
  68. Dbt key(buf, len);
  69. Dbt data(rbuf, len);
  70. if ((ret = dbp->put(NULL, &key, &data, DB_NOOVERWRITE)) != 0) {
  71. dbp->err(ret, "Db::put");
  72. if (ret != DB_KEYEXIST)
  73. throw DbException(ret);
  74. }
  75. }
  76. }
  77. BtRecExample::~BtRecExample()
  78. {
  79. if (dbcp != 0)
  80. dbcp->close();
  81. dbp->close(0);
  82. delete dbp;
  83. }
  84. //
  85. // Print out the number of records in the database.
  86. //
  87. void BtRecExample::stats()
  88. {
  89. DB_BTREE_STAT *statp;
  90. dbp->stat(&statp, NULL, 0);
  91. cout << progname << ": database contains "
  92.      << (u_long)statp->bt_ndata << " recordsn";
  93. // Note: must use free, not delete.
  94. // This struct is allocated by C.
  95. //
  96. free(statp);
  97. }
  98. void BtRecExample::run()
  99. {
  100. db_recno_t recno;
  101. int ret;
  102. char buf[1024];
  103. // Acquire a cursor for the database.
  104. dbp->cursor(NULL, &dbcp, 0);
  105. //
  106. // Prompt the user for a record number, then retrieve and display
  107. // that record.
  108. //
  109. for (;;) {
  110. // Get a record number.
  111. cout << "recno #> ";
  112. cout.flush();
  113. if (fgets(buf, sizeof(buf), stdin) == NULL)
  114. break;
  115. recno = atoi(buf);
  116. //
  117. // Start with a fresh key each time,
  118. // the dbp->get() routine returns
  119. // the key and data pair, not just the key!
  120. //
  121. Dbt key(&recno, sizeof(recno));
  122. Dbt data;
  123. if ((ret = dbcp->get(&key, &data, DB_SET_RECNO)) != 0) {
  124. dbp->err(ret, "DBcursor->get");
  125. throw DbException(ret);
  126. }
  127. // Display the key and data.
  128. show("k/dt", &key, &data);
  129. // Move the cursor a record forward.
  130. if ((ret = dbcp->get(&key, &data, DB_NEXT)) != 0) {
  131. dbp->err(ret, "DBcursor->get");
  132. throw DbException(ret);
  133. }
  134. // Display the key and data.
  135. show("nextt", &key, &data);
  136. //
  137. // Retrieve the record number for the following record into
  138. // local memory.
  139. //
  140. data.set_data(&recno);
  141. data.set_size(sizeof(recno));
  142. data.set_ulen(sizeof(recno));
  143. data.set_flags(data.get_flags() | DB_DBT_USERMEM);
  144. if ((ret = dbcp->get(&key, &data, DB_GET_RECNO)) != 0) {
  145. if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY) {
  146. dbp->err(ret, "DBcursor->get");
  147. throw DbException(ret);
  148. }
  149. }
  150. else {
  151. cout << "retrieved recno: " << (u_long)recno << "n";
  152. }
  153. }
  154. dbcp->close();
  155. dbcp = NULL;
  156. }
  157. //
  158. // show --
  159. // Display a key/data pair.
  160. //
  161. void BtRecExample::show(char *msg, Dbt *key, Dbt *data)
  162. {
  163. cout << msg << (char *)key->get_data()
  164.      << " : " << (char *)data->get_data() << "n";
  165. }
  166. int
  167. main(int argc, char *argv[])
  168. {
  169. extern char *optarg;
  170. extern int optind;
  171. FILE *fp;
  172. int ch;
  173. while ((ch = getopt(argc, argv, "")) != EOF)
  174. switch (ch) {
  175. case '?':
  176. default:
  177. usage();
  178. }
  179. argc -= optind;
  180. argv += optind;
  181. // Open the word database.
  182. if ((fp = fopen(WORDLIST, "r")) == NULL) {
  183. fprintf(stderr, "%s: open %s: %sn",
  184. progname, WORDLIST, db_strerror(errno));
  185. exit (1);
  186. }
  187. try {
  188. BtRecExample app(fp);
  189. // Close the word database.
  190. (void)fclose(fp);
  191. fp = NULL;
  192. app.stats();
  193. app.run();
  194. }
  195. catch (DbException &dbe) {
  196. cerr << "Exception: " << dbe.what() << "n";
  197. return dbe.get_errno();
  198. }
  199. return (0);
  200. }
  201. void
  202. usage()
  203. {
  204. (void)fprintf(stderr, "usage: %sn", progname);
  205. exit(1);
  206. }