1m4_ignore([
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 *, db_recno_t));
14int recno_display __P((DB *, char *));
15
16int
17main()
18{
19	DB *dbp;
20	DBT key, data;
21	DB_BTREE_STAT *statp;
22	FILE *fp;
23	db_recno_t recno;
24	u_int32_t len;
25	int cnt, ret;
26	char *p, *t, buf[1024], rbuf[1024];
27	const char *progname = "ex_btrec";		/* Program name. */
28
29	/* Open the word database. */
30	if ((fp = fopen(WORDLIST, "r")) == NULL) {
31		fprintf(stderr, "%s: open %s: %s\n",
32		    progname, WORDLIST, db_strerror(errno));
33		return (1);
34	}
35
36	/* Remove the previous database. */
37	(void)remove(DATABASE);
38
39	/* Create and initialize database object, open the database. */
40	if ((ret = db_create(&dbp, NULL, 0)) != 0) {
41		fprintf(stderr,
42		    "%s: db_create: %s\n", progname, db_strerror(ret));
43		return (1);
44	}
45	dbp->set_errfile(dbp, stderr);
46	dbp->set_errpfx(dbp, progname);			/* 1K page sizes. */
47	if ((ret = dbp->set_pagesize(dbp, 1024)) != 0) {
48		dbp->err(dbp, ret, "set_pagesize");
49		return (1);
50	}						/* Record numbers. */
51	if ((ret = dbp->set_flags(dbp, DB_RECNUM)) != 0) {
52		dbp->err(dbp, ret, "set_flags: DB_RECNUM");
53		return (1);
54	}
55	if ((ret = dbp->open(dbp,
56	    NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
57		dbp->err(dbp, ret, "open: %s", DATABASE);
58		return (1);
59	}
60
61	/*
62	 * Insert records into the database, where the key is the word
63	 * preceded by its record number, and the data is the same, but
64	 * in reverse order.
65	 */
66	memset(&key, 0, sizeof(DBT));
67	memset(&data, 0, sizeof(DBT));
68	for (cnt = 1; cnt <= 1000; ++cnt) {
69		(void)sprintf(buf, "%04d_", cnt);
70		if (fgets(buf + 4, sizeof(buf) - 4, fp) == NULL)
71			break;
72		len = strlen(buf);
73		for (t = rbuf, p = buf + (len - 2); p >= buf;)
74			*t++ = *p--;
75		*t++ = '\0';
76
77		key.data = buf;
78		data.data = rbuf;
79		data.size = key.size = len - 1;
80
81		if ((ret =
82		    dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE)) != 0) {
83			dbp->err(dbp, ret, "DB->put");
84			if (ret != DB_KEYEXIST)
85				goto err1;
86		}
87	}
88
89	/* Close the word database. */
90	(void)fclose(fp);
91
92	/* Print out the number of records in the database. */
93	if ((ret = dbp->stat(dbp, NULL, &statp, 0)) != 0) {
94		dbp->err(dbp, ret, "DB->stat");
95		goto err1;
96	}
97	printf("%s: database contains %lu records\n",
98	    progname, (u_long)statp->bt_ndata);
99	free(statp);
100
101	/*
102	 * Prompt the user for a record number, then retrieve and display
103	 * that record.
104	 */
105	for (;;) {
106		/* Get a record number. */
107		printf("recno #> ");
108		fflush(stdout);
109		if (fgets(buf, sizeof(buf), stdin) == NULL)
110			break;
111		recno = atoi(buf);
112		rec_display(dbp, recno);
113	}
114
115	recno_display(dbp, "0007atoned");
116
117	if ((ret = dbp->close(dbp, 0)) != 0) {
118		fprintf(stderr,
119		    "%s: DB->close: %s\n", progname, db_strerror(ret));
120		return (1);
121	}
122
123	return (0);
124
125err1:	(void)dbp->close(dbp, 0);
126	return (ret);
127
128}
129int
130rec_display(dbp, recno)
131	DB *dbp;
132	db_recno_t recno;
133{
134	DBT key, data;
135	int ret;
136
137	memset(&key, 0, sizeof(key));
138	key.data = &recno;
139	key.size = sizeof(recno);
140	memset(&data, 0, sizeof(data));
141
142	if ((ret = dbp->get(dbp, NULL, &key, &data, DB_SET_RECNO)) != 0)
143		return (ret);
144	printf("data for %lu: %.*s\n",
145	    (u_long)recno, (int)data.size, (char *)data.data);
146	return (0);
147}])
148m4_indent([dnl
149int
150recno_display(dbp, keyvalue)
151	DB *dbp;
152	char *keyvalue;
153{
154	DBC *dbcp;
155	DBT key, data;
156	db_recno_t recno;
157	int ret, t_ret;
158m4_blank
159	/* Acquire a cursor for the database. */
160	if ((ret = dbp-__GT__cursor(dbp, NULL, &dbcp, 0)) != 0) {
161		dbp-__GT__err(dbp, ret, "DB-__GT__cursor");
162		goto err;
163	}
164m4_blank
165	/* Position the cursor. */
166	memset(&key, 0, sizeof(key));
167	key.data = keyvalue;
168	key.size = strlen(keyvalue);
169	memset(&data, 0, sizeof(data));
170	if ((ret = dbcp-__GT__c_get(dbcp, &key, &data, DB_SET)) != 0) {
171		dbp-__GT__err(dbp, ret, "DBC-__GT__c_get(DB_SET): %s", keyvalue);
172		goto err;
173	}
174m4_blank
175	/*
176	 * Request the record number, and store it into appropriately
177	 * sized and aligned local memory.
178	 */
179	memset(&data, 0, sizeof(data));
180	data.data = &recno;
181	data.ulen = sizeof(recno);
182	data.flags = DB_DBT_USERMEM;
183	if ((ret = dbcp-__GT__c_get(dbcp, &key, &data, DB_GET_RECNO)) != 0) {
184		dbp-__GT__err(dbp, ret, "DBC-__GT__c_get(DB_GET_RECNO)");
185		goto err;
186	}
187m4_blank
188	printf("key for requested key was %lu\n", (u_long)recno);
189m4_blank
190err:	/* Close the cursor. */
191	if ((t_ret = dbcp-__GT__c_close(dbcp)) != 0) {
192		if (ret == 0)
193			ret = t_ret;
194		dbp-__GT__err(dbp, ret, "DBC-__GT__close");
195	}
196	return (ret);
197}])
198