1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1997,2008 Oracle.  All rights reserved.
5 *
6 * $Id: TestKeyRange.cpp,v 12.7 2008/01/08 20:58:54 bostic Exp $
7 */
8
9/*
10 * NOTE: AccessExample changed to test Db.key_range.  We made a global
11 * change of /AccessExample/TestKeyRange/, the only other changes are
12 * marked with comments that are notated as 'ADDED'.
13 */
14#include <sys/types.h>
15
16#include <iostream.h>
17#include <errno.h>
18#include <stdlib.h>
19#include <string.h>
20#ifndef _MSC_VER
21#include <unistd.h>
22#endif
23
24#include <iomanip.h>
25#include <db_cxx.h>
26
27class TestKeyRange
28{
29public:
30	TestKeyRange();
31	void run();
32
33private:
34	static const char FileName[];
35
36	// no need for copy and assignment
37	TestKeyRange(const TestKeyRange &);
38	void operator = (const TestKeyRange &);
39};
40
41static void usage();          // forward
42
43int main(int argc, char *argv[])
44{
45	if (argc > 1) {
46		usage();
47	}
48
49	// Use a try block just to report any errors.
50	// An alternate approach to using exceptions is to
51	// use error models (see DbEnv::set_error_model()) so
52	// that error codes are returned for all Berkeley DB methods.
53	//
54	try {
55		TestKeyRange app;
56		app.run();
57		return 0;
58	}
59	catch (DbException &dbe) {
60		cerr << "TestKeyRange: " << dbe.what() << "\n";
61		return 1;
62	}
63}
64
65static void usage()
66{
67	cerr << "usage: TestKeyRange\n";
68	exit(1);
69}
70
71const char TestKeyRange::FileName[] = "access.db";
72
73TestKeyRange::TestKeyRange()
74{
75}
76
77void TestKeyRange::run()
78{
79	// Remove the previous database.
80	(void)unlink(FileName);
81
82	// Create the database object.
83	// There is no environment for this simple example.
84	Db db(0, 0);
85
86	db.set_error_stream(&cerr);
87	db.set_errpfx("TestKeyRange");
88	db.set_pagesize(1024);		/* Page size: 1K. */
89	db.set_cachesize(0, 32 * 1024, 0);
90	db.open(NULL, FileName, NULL, DB_BTREE, DB_CREATE, 0664);
91
92	//
93	// Insert records into the database, where the key is the user
94	// input and the data is the user input in reverse order.
95	//
96	char buf[1024];
97	char rbuf[1024];
98	char *t;
99	char *p;
100	int ret;
101	int len;
102	Dbt *firstkey = NULL;
103	char firstbuf[1024];
104
105	for (;;) {
106		cout << "input>";
107		cout.flush();
108
109		cin.getline(buf, sizeof(buf));
110		if (cin.eof())
111			break;
112
113		if ((len = strlen(buf)) <= 0)
114			continue;
115		for (t = rbuf, p = buf + (len - 1); p >= buf;)
116			*t++ = *p--;
117		*t++ = '\0';
118
119		Dbt key(buf, len + 1);
120		Dbt data(rbuf, len + 1);
121		if (firstkey == NULL) {
122			strcpy(firstbuf, buf);
123			firstkey = new Dbt(firstbuf, len + 1);
124		}
125
126		ret = db.put(0, &key, &data, DB_NOOVERWRITE);
127		if (ret == DB_KEYEXIST) {
128			cout << "Key " << buf << " already exists.\n";
129		}
130		cout << "\n";
131	}
132
133	// We put a try block around this section of code
134	// to ensure that our database is properly closed
135	// in the event of an error.
136	//
137	try {
138		// Acquire a cursor for the table.
139		Dbc *dbcp;
140		db.cursor(NULL, &dbcp, 0);
141
142		/*ADDED...*/
143		DB_KEY_RANGE range;
144		memset(&range, 0, sizeof(range));
145
146		db.key_range(NULL, firstkey, &range, 0);
147		printf("less: %f\n", range.less);
148		printf("equal: %f\n", range.equal);
149		printf("greater: %f\n", range.greater);
150		/*end ADDED*/
151
152		Dbt key;
153		Dbt data;
154
155		// Walk through the table, printing the key/data pairs.
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 << "TestKeyRange: " << dbe.what() << "\n";
165	}
166
167	db.close(0);
168}
169