1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2002-2009 Oracle.  All rights reserved.
5 */
6
7#include "db_cxx.h"
8#include "stdlib.h"
9
10void test1()
11{
12	int numberOfKeysToWrite= 10000;
13	Db db(0,DB_CXX_NO_EXCEPTIONS);
14	db.set_pagesize(512);
15	int err= db.open(0, "test1.db", 0, DB_BTREE, DB_CREATE, 0);
16	{
17		int i= 0;
18		Dbt key(&i,sizeof(i));
19		Dbt data(&i,sizeof(i));
20		for(;i<numberOfKeysToWrite;++i)
21		{
22			db.put(0,&key,&data,0);
23		}
24	}
25
26	{
27		Dbc *dbc;
28		err= db.cursor(0,&dbc,0);
29
30		char *check= (char*)calloc(numberOfKeysToWrite,1);
31		char buffer[8192];
32		int numberOfKeysRead= 0;
33		Dbt multikey(&numberOfKeysRead,sizeof(numberOfKeysRead));
34		Dbt multidata(&buffer,sizeof(buffer));
35		multidata.set_flags(DB_DBT_USERMEM);
36		multidata.set_ulen(sizeof(buffer));
37		err= 0;
38		while(err==0)
39		{
40			err= dbc->get(&multikey,&multidata,DB_NEXT|DB_MULTIPLE_KEY);
41			if(err==0)
42			{
43				Dbt key, data;
44				DbMultipleKeyDataIterator i(multidata);
45				while(err==0 && i.next(key,data))
46				{
47					int actualKey= *((int*)key.get_data());
48					int actualData= *((int*)data.get_data());
49					if(actualKey!=actualData)
50					{
51						std::cout << "Error: key/data mismatch. " << actualKey << "!=" << actualData << std::endl;
52						err= -1;
53					}
54					else
55					{
56						check[actualKey]++;
57					}
58					numberOfKeysRead++;
59				}
60			} else if(err!=DB_NOTFOUND)
61				std::cout << "Error: dbc->get: " << db_strerror(err) << std::endl;
62		}
63		if(numberOfKeysRead!=numberOfKeysToWrite)
64		{
65			std::cout << "Error: key count mismatch. " << numberOfKeysRead << "!=" << numberOfKeysToWrite << std::endl;
66		}
67		for(int n=0;n<numberOfKeysToWrite;++n)
68		{
69			if(check[n]!=1)
70			{
71				std::cout << "Error: key " << n << " was written to the database, but not read back." << std::endl;
72			}
73		}
74		free(check);
75		dbc->close();
76	}
77
78	db.close(0);
79}
80
81void test2()
82{
83	int numberOfKeysToWrite= 10000;
84	Db db(0,DB_CXX_NO_EXCEPTIONS);
85	db.set_flags(DB_DUP);
86	db.set_pagesize(512);
87	int err= db.open(0, "test2.db", 0, DB_BTREE, DB_CREATE, 0);
88
89	{
90		int i= 0;
91		int k= 0;
92		Dbt key(&k,sizeof(k));
93		Dbt data(&i,sizeof(i));
94		for(;i<numberOfKeysToWrite;++i)
95		{
96			err= db.put(0,&key,&data,0);
97		}
98	}
99
100	{
101		Dbc *dbc;
102		err= db.cursor(0,&dbc,0);
103
104		char buffer[8192];
105		int numberOfKeysRead= 0;
106		Dbt multikey(&numberOfKeysRead,sizeof(numberOfKeysRead));
107		Dbt multidata(&buffer,sizeof(buffer));
108		multidata.set_flags(DB_DBT_USERMEM);
109		multidata.set_ulen(sizeof(buffer));
110		err= 0;
111		while(err==0)
112		{
113			err= dbc->get(&multikey,&multidata,DB_NEXT|DB_MULTIPLE);
114			if(err==0)
115			{
116				Dbt data;
117				DbMultipleDataIterator i(multidata);
118				while(err==0 && i.next(data))
119				{
120					int actualData= *((int*)data.get_data());
121					if(numberOfKeysRead!=actualData)
122					{
123						std::cout << "Error: key/data mismatch. " << numberOfKeysRead << "!=" << actualData << std::endl;
124						err= -1;
125					}
126					numberOfKeysRead++;
127				}
128			} else if(err!=DB_NOTFOUND)
129				std::cout << "Error: dbc->get: " << db_strerror(err) << std::endl;
130		}
131		if(numberOfKeysRead!=numberOfKeysToWrite)
132		{
133			std::cout << "Error: key count mismatch. " << numberOfKeysRead << "!=" << numberOfKeysToWrite << std::endl;
134		}
135		dbc->close();
136	}
137	db.close(0);
138}
139
140void test3()
141{
142	int numberOfKeysToWrite= 10000;
143	Db db(0,DB_CXX_NO_EXCEPTIONS);
144	db.set_pagesize(512);
145	int err= db.open(0, "test3.db", 0, DB_RECNO, DB_CREATE, 0);
146
147	{
148		int i= 0;
149		Dbt key;
150		Dbt data(&i,sizeof(i));
151		for(;i<numberOfKeysToWrite;++i)
152		{
153			err= db.put(0,&key,&data,DB_APPEND);
154		}
155	}
156
157	{
158		Dbc *dbc;
159		err= db.cursor(0,&dbc,0);
160
161		char buffer[8192];
162		int numberOfKeysRead= 0;
163		Dbt multikey(&numberOfKeysRead,sizeof(numberOfKeysRead));
164		Dbt multidata(&buffer,sizeof(buffer));
165		multidata.set_flags(DB_DBT_USERMEM);
166		multidata.set_ulen(sizeof(buffer));
167		err= 0;
168		while(err==0)
169		{
170			err= dbc->get(&multikey,&multidata,DB_NEXT|DB_MULTIPLE_KEY);
171			if(err==0)
172			{
173				u_int32_t recno= 0;
174				Dbt data;
175				DbMultipleRecnoDataIterator i(multidata);
176				while(err==0 && i.next(recno,data))
177				{
178					int actualData= *((int*)data.get_data());
179					if(recno!=actualData+1)
180					{
181						std::cout << "Error: recno/data mismatch. " << recno << "!=" << actualData << "+1" << std::endl;
182						err= -1;
183					}
184					numberOfKeysRead++;
185				}
186			} else if(err!=DB_NOTFOUND)
187				std::cout << "Error: dbc->get: " << db_strerror(err) << std::endl;
188		}
189		if(numberOfKeysRead!=numberOfKeysToWrite)
190		{
191			std::cout << "Error: key count mismatch. " << numberOfKeysRead << "!=" << numberOfKeysToWrite << std::endl;
192		}
193		dbc->close();
194	}
195
196	db.close(0);
197}
198
199int main()
200{
201	test1();
202	test2();
203	test3();
204	return (0);
205}
206
207