2 #include <BerkelyDB/Environment.h>
3 #include <BerkelyDB/KeyDataPair.h>
4 #include <BerkelyDB/Exceptions/CursorError.h>
5 #ifdef HAVE_BOOST_FILESYSTEM
6 #include <boost/filesystem/path.hpp>
7 #include <boost/filesystem/operations.hpp>
8 #include <boost/filesystem/convenience.hpp>
14 CPPUNIT_TEST_SUITE_REGISTRATION(BerkelyDB
);
16 void BerkelyDB::setUp()
19 void BerkelyDB::tearDown()
22 #ifdef HAVE_BOOST_FILESYSTEM
23 void BerkelyDB::createEnvironment()
25 std::string
env_name(createTempName());
26 env_name
= "test/" + env_name
;
27 boost::filesystem::create_directories(boost::filesystem::path(env_name
, boost::filesystem::native
));
28 ::BerkelyDB::Environment
env(env_name
);
31 void BerkelyDB::createDatabaseInEnvironment()
33 std::string
env_name(createTempName());
34 env_name
= "test/" + env_name
;
35 boost::filesystem::create_directories(boost::filesystem::path(env_name
, boost::filesystem::native
));
36 ::BerkelyDB::Environment
env(env_name
);
37 ::BerkelyDB::Database
db(&env
, createTempName());
41 void BerkelyDB::createDatabaseWithoutEnvironment()
43 std::string
temp_name("test/");
44 temp_name
+= createTempName();
45 CPPUNIT_ASSERT_THROW(::BerkelyDB::Database
db(0, temp_name
), std::invalid_argument
);
48 #ifdef HAVE_BOOST_FILESYSTEM
49 void BerkelyDB::checkEmptyDatabaseIterators()
51 std::string
temp_name("test/");
52 temp_name
+= createTempName();
53 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
54 ::BerkelyDB::Environment
env(temp_name
);
55 ::BerkelyDB::Database
db(&env
, createTempName());
56 CPPUNIT_ASSERT_MESSAGE("On a freshly created database, the cursors begin and end should be the same", db
.begin() == db
.end());
59 void BerkelyDB::checkEmptyDatabaseAccessors()
61 std::string
temp_name("test/");
62 temp_name
+= createTempName();
63 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
64 ::BerkelyDB::Environment
env(temp_name
);
65 temp_name
= createTempName();
66 ::BerkelyDB::Database
db(&env
, temp_name
);
67 CPPUNIT_ASSERT_MESSAGE("On a freshly created database, the \"empty\" accessor should return true", db
.empty());
68 CPPUNIT_ASSERT_MESSAGE("On a freshly created database, the \"size\" accessor should return 0", db
.size() == 0);
71 void BerkelyDB::createDatabaseAndReopen()
73 std::string
temp_name("test/");
74 temp_name
+= createTempName();
75 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
76 ::BerkelyDB::Environment
env(temp_name
);
77 std::string
db_name(createTempName());
79 ::BerkelyDB::Database
db(&env
, db_name
);
81 ::BerkelyDB::Database
db(&env
, db_name
);
84 void BerkelyDB::addValueToDatabase()
86 ::BerkelyDB::KeyDataPair
kdp("Key", "Data");
87 ::BerkelyDB::KeyDataPair
kdp_empty("KeyEmpty", "");
88 std::string
temp_name("test/");
89 temp_name
+= createTempName();
90 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
91 ::BerkelyDB::Environment
env(temp_name
);
92 std::string
db_name(createTempName());
93 ::BerkelyDB::Database
db(&env
, db_name
);
96 CPPUNIT_ASSERT(db
.size() == 2);
99 void BerkelyDB::addValueAndReadBackThroughCursor()
101 ::BerkelyDB::KeyDataPair
kdp("Key", "Data");
102 std::string
temp_name("test/");
103 temp_name
+= createTempName();
104 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
105 ::BerkelyDB::Environment
env(temp_name
);
106 std::string
db_name(createTempName());
107 ::BerkelyDB::Database
db(&env
, db_name
);
110 ::BerkelyDB::Cursor
beg(db
.begin());
111 ::BerkelyDB::KeyDataPair
kdp2(*beg
);
112 CPPUNIT_ASSERT(kdp
== kdp2
);
115 void BerkelyDB::addValueAndReadBackThroughCursor2()
117 /* Cursors should not invalidate for an insertion: if we take a
118 * begin and an end cursor and insert something, begin should
119 * point to the newly inserted entry without further modification */
120 ::BerkelyDB::KeyDataPair
kdp2("Key2", "Data2");
121 std::string
temp_name("test/");
122 temp_name
+= createTempName();
123 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
124 ::BerkelyDB::Environment
env(temp_name
);
125 std::string
db_name(createTempName());
126 ::BerkelyDB::Database
db(&env
, db_name
);
127 ::BerkelyDB::Cursor
beg(db
.begin());
130 ::BerkelyDB::KeyDataPair
kdp3(*beg
);
131 CPPUNIT_ASSERT(kdp2
== kdp3
);
134 void BerkelyDB::addManyValuesAndReadBackThroughCursor()
136 /* Cursors should not invalidate for an insertion: if we take a
137 * begin and an end cursor and insert something, begin should
138 * point to the newly inserted entry without further modification */
139 std::string
temp_name("test/");
140 temp_name
+= createTempName();
141 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
142 ::BerkelyDB::Environment
env(temp_name
);
143 std::string
db_name(createTempName());
144 ::BerkelyDB::Database
db(&env
, db_name
);
145 ::BerkelyDB::Cursor
beg(db
.begin());
148 char * a("can break here to check memory usage before cache is filled");
150 for (int index(0); index
< 10000; ++index
)
151 db
.insert(::BerkelyDB::KeyDataPair(index
, 1));
153 char * b("can break here to check memory usage once the cache is filled");
155 for (int index(-1); index
> -10000; --index
)
156 db
.insert(::BerkelyDB::KeyDataPair(index
, 1));
158 char * c("can break here to check memory usage; should be the same as in b");
161 ::BerkelyDB::Cursor
current(db
.begin());
162 for (; current
!= db
.end(); ++current
)
164 ::BerkelyDB::KeyDataPair
key_data(*current
);
168 char * d("can break here to check memory usage; should be the same as in b");
172 void BerkelyDB::writeThroughCursor()
174 ::BerkelyDB::KeyDataPair
kdp("Key", "Data");
175 std::string
temp_name("test/");
176 temp_name
+= createTempName();
177 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
178 ::BerkelyDB::Environment
env(temp_name
);
179 std::string
db_name(createTempName());
180 ::BerkelyDB::Database
db(&env
, db_name
);
181 ::BerkelyDB::Cursor
beg(db
.begin());
185 void BerkelyDB::writeThroughCursor2()
187 ::BerkelyDB::KeyDataPair
kdp("Key", "Data");
188 std::string
temp_name("test/");
189 temp_name
+= createTempName();
190 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
191 ::BerkelyDB::Environment
env(temp_name
);
192 std::string
db_name(createTempName());
193 ::BerkelyDB::Database
db(&env
, db_name
);
194 ::BerkelyDB::Cursor
beg(db
.begin());
196 ::BerkelyDB::Cursor
beg2(db
.begin());
197 ::BerkelyDB::KeyDataPair
kdp2(*beg2
);
198 CPPUNIT_ASSERT(kdp
== kdp2
);
201 void BerkelyDB::writeThroughCursor3()
203 ::BerkelyDB::KeyDataPair
kdp1("Key", "Data1");
204 ::BerkelyDB::KeyDataPair
kdp2("Key", "Data2");
205 std::string
temp_name("test/");
206 temp_name
+= createTempName();
207 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
208 ::BerkelyDB::Environment
env(temp_name
);
209 std::string
db_name(createTempName());
210 ::BerkelyDB::Database
db(&env
, db_name
);
212 ::BerkelyDB::Cursor
beg(db
.begin());
214 ::BerkelyDB::Cursor
beg2(db
.begin());
215 ::BerkelyDB::KeyDataPair
kdp3(*beg2
);
216 CPPUNIT_ASSERT(kdp2
== kdp3
);
219 void BerkelyDB::writeThroughCursor4()
221 ::BerkelyDB::KeyDataPair
kdp1("Key1", "Data1");
222 ::BerkelyDB::KeyDataPair
kdp2("Key2", "Data2");
223 std::string
temp_name("test/");
224 temp_name
+= createTempName();
225 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
226 ::BerkelyDB::Environment
env(temp_name
);
227 std::string
db_name(createTempName());
228 ::BerkelyDB::Database
db(&env
, db_name
);
230 ::BerkelyDB::Cursor
beg(db
.begin());
231 CPPUNIT_ASSERT_THROW(*beg
= kdp2
, ::BerkelyDB::Exceptions::CursorError
);
234 void BerkelyDB::erase()
236 ::BerkelyDB::KeyDataPair
kdp1("Key1", "Data1");
237 std::string
temp_name("test/");
238 temp_name
+= createTempName();
239 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
240 ::BerkelyDB::Environment
env(temp_name
);
241 std::string
db_name(createTempName());
242 ::BerkelyDB::Database
db(&env
, db_name
);
244 CPPUNIT_ASSERT(db
.size() == 1);
246 CPPUNIT_ASSERT(db
.empty());
247 CPPUNIT_ASSERT(db
.size() == 0);
250 void BerkelyDB::clear()
252 ::BerkelyDB::KeyDataPair
kdp1("Key1", "Data1");
253 ::BerkelyDB::KeyDataPair
kdp2("Key2", "Data2");
254 std::string
temp_name("test/");
255 temp_name
+= createTempName();
256 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
257 ::BerkelyDB::Environment
env(temp_name
);
258 std::string
db_name(createTempName());
259 ::BerkelyDB::Database
db(&env
, db_name
);
262 CPPUNIT_ASSERT(db
.size() == 2);
264 CPPUNIT_ASSERT(db
.empty());
265 CPPUNIT_ASSERT(db
.size() == 0);
268 void BerkelyDB::get()
270 std::string
temp_name("test/");
271 temp_name
+= createTempName();
272 boost::filesystem::create_directories(boost::filesystem::path(temp_name
, boost::filesystem::native
));
273 ::BerkelyDB::Environment
env(temp_name
);
274 std::string
db_name(createTempName());
275 ::BerkelyDB::Database
db(&env
, db_name
);
277 ::BerkelyDB::KeyDataPair
kdp1("Key1", "Data1");
278 ::BerkelyDB::KeyDataPair
kdp2("Key2", "Data2");
282 CPPUNIT_ASSERT(db
.size() == 2);
284 ::BerkelyDB::KeyDataPair
result1("Key1", "");
285 ::BerkelyDB::KeyDataPair
result2("Key2", "");
286 ::BerkelyDB::KeyDataPair
result3("Key3", "");
288 bool result_code1
= db
.get(result1
);
289 CPPUNIT_ASSERT(result_code1
== true);
290 CPPUNIT_ASSERT(result1
== ::BerkelyDB::KeyDataPair("Key1", "Data1"));
292 bool result_code2
= db
.get(result2
);
293 CPPUNIT_ASSERT(result_code2
== true);
294 CPPUNIT_ASSERT(result2
== ::BerkelyDB::KeyDataPair("Key2", "Data2"));
296 bool result_code3
= db
.get(result3
);
297 CPPUNIT_ASSERT(result_code3
== false);
298 CPPUNIT_ASSERT(result3
== ::BerkelyDB::KeyDataPair("Key3", ""));
302 std::string
BerkelyDB::createTempName()
304 /* Creating an environment shouldn't fail if the directory it is created in exists */
305 // create a temporary directory from a subset of a randomly shuffled alphabet :)
306 std::string
alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
307 static bool initialized__(false);
310 std::srand(static_cast< unsigned int >(std::time(0)));
311 initialized__
= true;
314 { /* already initialized */ }
315 std::random_shuffle(alphabet
.begin(), alphabet
.end());