1m4_ignore([dnl 2#include <sys/types.h> 3 4#include <errno.h> 5#include <stdlib.h> 6#include <string.h> 7 8#include <db.h> 9 10#define DATABASE "access.db" 11#define WORDLIST "../test/wordlist" 12 13int rec_display __P((DB *)); 14 15int 16main() 17{ 18 DB *dbp; 19 DBT key, data; 20 FILE *fp; 21 u_int32_t len; 22 int cnt, ret; 23 char *p, *t, buf[1024], rbuf[1024]; 24 const char *progname = "ex_access"; /* Program name. */ 25 26 /* Open the word database. */ 27 if ((fp = fopen(WORDLIST, "r")) == NULL) { 28 fprintf(stderr, "%s: open %s: %s\n", 29 progname, WORDLIST, db_strerror(errno)); 30 return (1); 31 } 32 33 /* Remove the previous database. */ 34 (void)remove(DATABASE); 35 36 /* Create and initialize database object, open the database. */ 37 if ((ret = db_create(&dbp, NULL, 0)) != 0) { 38 fprintf(stderr, 39 "%s: db_create: %s\n", progname, db_strerror(ret)); 40 return (1); 41 } 42 dbp->set_errfile(dbp, stderr); 43 dbp->set_errpfx(dbp, progname); 44 if ((ret = dbp->set_pagesize(dbp, 1024)) != 0) { 45 dbp->err(dbp, ret, "set_pagesize"); 46 return (1); 47 } 48 if ((ret = dbp->set_cachesize(dbp, 0, 32 * 1024, 0)) != 0) { 49 dbp->err(dbp, ret, "set_cachesize"); 50 return (1); 51 } 52 if ((ret = dbp->open(dbp, 53 NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) { 54 dbp->err(dbp, ret, "%s: open", DATABASE); 55 return (1); 56 } 57 58 /* 59 * Insert records into the database, where the key is the word 60 * preceded by its record number, and the data is the same, but 61 * in reverse order. 62 */ 63 memset(&key, 0, sizeof(DBT)); 64 memset(&data, 0, sizeof(DBT)); 65 for (cnt = 1; cnt <= 1000; ++cnt) { 66 (void)sprintf(buf, "%04d_", cnt); 67 if (fgets(buf + 4, sizeof(buf) - 4, fp) == NULL) 68 break; 69 len = strlen(buf); 70 for (t = rbuf, p = buf + (len - 2); p >= buf;) 71 *t++ = *p--; 72 *t++ = '\0'; 73 74 key.data = buf; 75 data.data = rbuf; 76 data.size = key.size = len - 1; 77 78 if ((ret = 79 dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE)) != 0) { 80 dbp->err(dbp, ret, "DB->put"); 81 if (ret != DB_KEYEXIST) 82 return (1); 83 } 84 } 85 86 /* Close the word database. */ 87 (void)fclose(fp); 88 89 rec_display(dbp); 90 91 return (0); 92}]) 93m4_indent([dnl 94int 95rec_display(dbp) 96 DB *dbp; 97{ 98 DBC *dbcp; 99 DBT key, data; 100 size_t retklen, retdlen; 101 char *retkey, *retdata; 102 int ret, t_ret; 103 void *p; 104m4_blank 105 memset(&key, 0, sizeof(key)); 106 memset(&data, 0, sizeof(data)); 107m4_blank 108 /* Review the database in 5MB chunks. */ 109#define BUFFER_LENGTH (5 * 1024 * 1024) 110 if ((data.data = malloc(BUFFER_LENGTH)) == NULL) 111 return (errno); 112 data.ulen = BUFFER_LENGTH; 113 data.flags = DB_DBT_USERMEM; 114m4_blank 115 /* Acquire a cursor for the database. */ 116 if ((ret = dbp-__GT__cursor(dbp, NULL, &dbcp, 0)) != 0) { 117 dbp-__GT__err(dbp, ret, "DB-__GT__cursor"); 118 free(data.data); 119 return (ret); 120 } 121m4_blank 122 for (;;) { 123 /* 124 * Acquire the next set of key/data pairs. This code does 125 * not handle single key/data pairs that won't fit in a 126 * BUFFER_LENGTH size buffer, instead returning DB_BUFFER_SMALL 127 * to our caller. 128 */ 129 if ((ret = dbcp-__GT__c_get(dbcp, 130 &key, &data, DB_MULTIPLE_KEY | DB_NEXT)) != 0) { 131 if (ret != DB_NOTFOUND) 132 dbp-__GT__err(dbp, ret, "DBcursor-__GT__c_get"); 133 break; 134 } 135m4_blank 136 for (DB_MULTIPLE_INIT(p, &data);;) { 137 DB_MULTIPLE_KEY_NEXT(p, 138 &data, retkey, retklen, retdata, retdlen); 139 if (p == NULL) 140 break; 141 printf("key: %.*s, data: %.*s\n", 142 (int)retklen, retkey, (int)retdlen, retdata); 143 } 144 } 145m4_blank 146 if ((t_ret = dbcp-__GT__c_close(dbcp)) != 0) { 147 dbp-__GT__err(dbp, ret, "DBcursor-__GT__close"); 148 if (ret == 0) 149 ret = t_ret; 150 } 151m4_blank 152 free(data.data); 153m4_blank 154 return (ret); 155}]) 156