Electroneum
lmdb.cpp File Reference
#include <boost/range/algorithm_ext/iota.hpp>
#include <boost/range/algorithm/equal.hpp>
#include <gtest/gtest.h>
#include "lmdb/database.h"
#include "lmdb/table.h"
#include "lmdb/transaction.h"
#include "lmdb/util.h"
Include dependency graph for lmdb.cpp:

Go to the source code of this file.

Enumerations

enum  choice : unsigned
 
enum  big_choice : unsigned long
 

Functions

 TEST (LMDB, Traits)
 
 TEST (LMDB, ToNative)
 
 TEST (LMDB, Conversions)
 
 TEST (LMDB, LessSort)
 
 TEST (LMDB, SortCompare)
 
 TEST (LMDB, Table)
 
 TEST (LMDB, InvalidDatabase)
 
 TEST (LMDB, InvalidValueStream)
 
 TEST (LMDB, InvalidValueIterator)
 
 TEST (LMDB, InvalidKeyStream)
 
 TEST (LMDB, InvalidKeyIterator)
 

Enumeration Type Documentation

◆ big_choice

enum big_choice : unsigned long
strong

Definition at line 41 of file lmdb.cpp.

41 : unsigned long {};

◆ choice

enum choice : unsigned
strong

Definition at line 40 of file lmdb.cpp.

40 : unsigned {};

Function Documentation

◆ TEST() [1/11]

TEST ( LMDB  ,
Traits   
)

Definition at line 58 of file lmdb.cpp.

59 {
60  EXPECT_TRUE((std::is_same<void, lmdb::identity<void>::type>()));
61  EXPECT_TRUE((std::is_same<unsigned, lmdb::identity<unsigned>::type>()));
62 
63  EXPECT_TRUE((std::is_same<void, lmdb::native_type<void>>()));
64  EXPECT_TRUE((std::is_same<unsigned, lmdb::native_type<unsigned>>()));
65  EXPECT_TRUE((std::is_same<unsigned, lmdb::native_type<choice>>()));
66  EXPECT_TRUE((std::is_same<unsigned long, lmdb::native_type<big_choice>>()));
67 }
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
typename std::conditional< std::is_enum< T >::value, std::underlying_type< T >, identity< T > >::type::type native_type
Definition: util.h:77

◆ TEST() [2/11]

TEST ( LMDB  ,
ToNative   
)

Definition at line 69 of file lmdb.cpp.

70 {
71  enum class negative_choice : int {};
72 
73  EXPECT_TRUE((std::is_same<unsigned, decltype(lmdb::to_native(choice(0)))>()));
75  (std::is_same<unsigned long, decltype(lmdb::to_native(big_choice(0)))>())
76  );
78  (std::is_same<int, decltype(lmdb::to_native(negative_choice(0)))>())
79  );
80 
81  EXPECT_EQ(unsigned(0), lmdb::to_native(choice(0)));
82  EXPECT_EQ(unsigned(0xffffffff), lmdb::to_native(choice(0xffffffff)));
83  EXPECT_EQ(-1, lmdb::to_native(negative_choice(-1)));
84 
85  // test constexpr
86  static_assert(100 == lmdb::to_native(choice(100)), "to_native failed");
87  static_assert(-100 == lmdb::to_native(negative_choice(-100)), "to_native failed");
88 }
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
choice
Definition: lmdb.cpp:40
big_choice
Definition: lmdb.cpp:41
constexpr U to_native(T value) noexcept
Definition: util.h:81
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
Here is the call graph for this function:

◆ TEST() [3/11]

TEST ( LMDB  ,
Conversions   
)

Definition at line 90 of file lmdb.cpp.

91 {
92  struct one
93  {
94  big_choice i;
95  choice j;
96  };
97 
98  const one test{big_choice(100), choice(95)};
99  one test2{big_choice(1000), choice(950)};
100 
101  EXPECT_EQ(&test, lmdb::to_val(test).mv_data);
102  EXPECT_NE(&test2, lmdb::to_val(test).mv_data);
103  EXPECT_EQ(
104  &test,
105  static_cast<const void*>(lmdb::to_byte_span(lmdb::to_val(test)).begin())
106  );
107  EXPECT_EQ(sizeof(test), lmdb::to_val(test).mv_size);
108  EXPECT_EQ(sizeof(test), lmdb::to_byte_span(lmdb::to_val(test)).size());
109 
110  EXPECT_EQ(&test2, lmdb::to_val(test2).mv_data);
111  EXPECT_NE(&test, lmdb::to_val(test2).mv_data);
112  EXPECT_EQ(
113  &test2,
114  static_cast<const void*>(lmdb::to_byte_span(lmdb::to_val(test2)).begin())
115  );
116  EXPECT_EQ(sizeof(test2), lmdb::to_val(test2).mv_size);
118 }
choice
Definition: lmdb.cpp:40
big_choice
Definition: lmdb.cpp:41
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
void test2()
MDB_val to_val(T &&value) noexcept
Definition: util.h:88
constexpr epee::span< const std::uint8_t > to_byte_span(MDB_val value) noexcept
Definition: util.h:97
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922

◆ TEST() [4/11]

TEST ( LMDB  ,
LessSort   
)

Definition at line 120 of file lmdb.cpp.

121 {
122  struct one
123  {
124  unsigned i;
125  unsigned j;
126  };
127 
128  struct two
129  {
130  unsigned i;
131  choice j;
132  };
133 
134  EXPECT_EQ(0, run_compare(0u, 0u, &lmdb::less<unsigned>));
135  EXPECT_EQ(-1, run_compare(0u, 1u, &lmdb::less<unsigned>));
136  EXPECT_EQ(1, run_compare(1u, 0u, &lmdb::less<unsigned>));
137 
138  EXPECT_EQ(0, run_compare<one>({0, 1}, {0, 1}, &lmdb::less<unsigned, sizeof(unsigned)>));
139  EXPECT_EQ(-1, run_compare<one>({0, 0}, {0, 1}, &lmdb::less<unsigned, sizeof(unsigned)>));
140  EXPECT_EQ(1, run_compare<one>({0, 1}, {0, 0}, &lmdb::less<unsigned, sizeof(unsigned)>));
141 
142  EXPECT_EQ(0, run_compare<one>({0, 1}, {0, 1}, ELECTRONEUM_SORT_BY(one, j)));
143  EXPECT_EQ(-1, run_compare<one>({0, 0}, {0, 1}, ELECTRONEUM_SORT_BY(one, j)));
144  EXPECT_EQ(1, run_compare<one>({0, 1}, {0, 0}, ELECTRONEUM_SORT_BY(one, j)));
145 
146  EXPECT_EQ(0, run_compare<two>({0, choice(1)}, {0, choice(1)}, ELECTRONEUM_SORT_BY(two, j)));
147  EXPECT_EQ(-1, run_compare<two>({0, choice(0)}, {0, choice(1)}, ELECTRONEUM_SORT_BY(two, j)));
148  EXPECT_EQ(1, run_compare<two>({0, choice(1)}, {0, choice(0)}, ELECTRONEUM_SORT_BY(two, j)));
149 
150  // compare function addresses
151  EXPECT_EQ((ELECTRONEUM_SORT_BY(one, i)), (ELECTRONEUM_SORT_BY(two, i)));
152  EXPECT_EQ((ELECTRONEUM_SORT_BY(one, j)), (ELECTRONEUM_SORT_BY(two, j)));
153  EXPECT_NE((ELECTRONEUM_SORT_BY(one, i)), (ELECTRONEUM_SORT_BY(two, j)));
154  EXPECT_NE((ELECTRONEUM_SORT_BY(one, j)), (ELECTRONEUM_SORT_BY(two, i)));
155 }
choice
Definition: lmdb.cpp:40
#define ELECTRONEUM_SORT_BY(obj, field)
Expands to lmdb::less for the value field within obj.
Definition: util.h:44
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922

◆ TEST() [5/11]

TEST ( LMDB  ,
SortCompare   
)

Definition at line 157 of file lmdb.cpp.

158 {
159  struct one
160  {
161  unsigned i;
162  bytes j;
163  };
164 
165  one test{55};
166  boost::iota(test.j.data, 10);
167 
168  const one test2 = test;
169 
170  EXPECT_EQ(0, run_compare(test, test2, ELECTRONEUM_COMPARE(one, j)));
171 
172  test.j.data[15] = 1;
173  EXPECT_GT(0, run_compare(test, test2, ELECTRONEUM_COMPARE(one, j)));
174 
175  test.j.data[15] = 100;
176  EXPECT_LT(0, run_compare(test, test2, ELECTRONEUM_COMPARE(one, j)));
177 }
#define EXPECT_GT(val1, val2)
Definition: gtest.h:1934
#define EXPECT_LT(val1, val2)
Definition: gtest.h:1930
#define ELECTRONEUM_COMPARE(obj, field)
Expands to lmdb::compare for the value field within obj.
Definition: util.h:51
void test2()
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922

◆ TEST() [6/11]

TEST ( LMDB  ,
Table   
)

Definition at line 179 of file lmdb.cpp.

180 {
181  struct one
182  {
183  bytes i;
184  bytes j;
185  };
186 
187  constexpr lmdb::basic_table<choice, bytes> test{"foo"};
188 
189  EXPECT_STREQ("foo", test.name);
190  static_assert(test.flags == 0, "bad flags");
191  static_assert(&lmdb::less<unsigned> == test.key_cmp, "bad key_cmp");
192  static_assert(test.value_cmp == nullptr, "bad value_cmp");
193  EXPECT_TRUE(test.get_value<bytes>(MDB_val{}).matches(std::errc::invalid_argument));
194 
196  "foo2", MDB_DUPSORT, &lmdb::compare<one>
197  };
198 
199  EXPECT_STREQ("foo2", test2.name);
201  EXPECT_EQ(&lmdb::less<unsigned long>, test2.key_cmp);
202  EXPECT_EQ(&lmdb::compare<one>, test2.value_cmp);
203  EXPECT_TRUE(test2.get_value<one>(MDB_val{}).matches(std::errc::invalid_argument));
204 
205  one record{};
206  boost::iota(record.i.data, 0);
207  boost::iota(record.i.data, 20);
208 
209  const one record_copy = ELECTRONEUM_UNWRAP(test2.get_value<one>(lmdb::to_val(record)));
210  EXPECT_TRUE(boost::equal(record.i.data, record_copy.i.data));
211  EXPECT_TRUE(boost::equal(record.j.data, record_copy.j.data));
212 
213  const bytes j_copy = ELECTRONEUM_UNWRAP(
214  test2.get_value<ELECTRONEUM_FIELD(one, j)>(lmdb::to_val(record))
215  );
216  EXPECT_TRUE(boost::equal(record.j.data, j_copy.data));
217 
218  EXPECT_TRUE(
219  test.get_key_stream(test_cursor{}).matches(std::errc::invalid_argument)
220  );
221  EXPECT_TRUE(
222  test2.get_key_stream(test_cursor{}).matches(std::errc::invalid_argument)
223  );
224 
225 
226  EXPECT_TRUE(
227  test.get_value_stream(choice(0), test_cursor{}).matches(std::errc::invalid_argument)
228  );
229  EXPECT_TRUE(
230  test2.get_value_stream(big_choice(0), test_cursor{}).matches(std::errc::invalid_argument)
231  );
232 }
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_STREQ(s1, s2)
Definition: gtest.h:1995
choice
Definition: lmdb.cpp:40
big_choice
Definition: lmdb.cpp:41
Helper for grouping typical LMDB DBI options when key and value are fixed types.
Definition: table.h:27
#define MDB_DUPFIXED
Definition: lmdb.h:351
#define ELECTRONEUM_FIELD(obj, field)
Definition: util.h:40
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:286
#define ELECTRONEUM_UNWRAP(...)
Definition: expect.h:60
void test2()
MDB_val to_val(T &&value) noexcept
Definition: util.h:88
#define MDB_DUPSORT
Definition: lmdb.h:345
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922

◆ TEST() [7/11]

TEST ( LMDB  ,
InvalidDatabase   
)

Definition at line 234 of file lmdb.cpp.

235 {
237 
238  EXPECT_TRUE(test.resize().matches(std::errc::invalid_argument));
239  EXPECT_TRUE(test.create_read_txn().matches(std::errc::invalid_argument));
240  EXPECT_TRUE(test.reset_txn(lmdb::read_txn{}).matches(std::errc::invalid_argument));
241  EXPECT_TRUE(test.create_write_txn().matches(std::errc::invalid_argument));
242  EXPECT_TRUE(test.commit(lmdb::write_txn{}).matches(std::errc::invalid_argument));
243 
244  EXPECT_TRUE(
245  test.try_write( [](MDB_txn&) { return success(); } ).matches(std::errc::invalid_argument)
246  );
247 }
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::unique_ptr< MDB_txn, abort_write_txn > write_txn
Definition: transaction.h:94
std::unique_ptr< MDB_env, close_env > environment
Definition: database.h:51
std::unique_ptr< MDB_txn, release_read_txn > read_txn
Definition: transaction.h:93
struct MDB_txn MDB_txn
Opaque structure for a transaction handle.
Definition: lmdb.h:267
Manages a LMDB environment for safe memory-map resizing. Thread-safe.
Definition: database.h:64

◆ TEST() [8/11]

TEST ( LMDB  ,
InvalidValueStream   
)

Definition at line 249 of file lmdb.cpp.

250 {
251  struct one
252  {
253  choice i;
254  choice j;
255  bytes k;
256  };
257 
258  lmdb::value_stream<one, close_test_cursor> test{test_cursor{}};
259 
260  EXPECT_TRUE((std::is_same<one, decltype(*(test.make_iterator()))>()));
261  EXPECT_TRUE((std::is_same<one, decltype(*(test.make_range().begin()))>()));
262  EXPECT_TRUE(
263  (std::is_same<bytes, decltype(*(test.make_iterator<ELECTRONEUM_FIELD(one, k)>()))>())
264  );
265  EXPECT_TRUE(
266  (std::is_same<bytes, decltype(*(test.make_range<ELECTRONEUM_FIELD(one, k)>().begin()))>())
267  );
268 
269  EXPECT_NO_THROW(test.reset());
270  EXPECT_EQ(0u, test.count());
271  EXPECT_TRUE(test.make_iterator().is_end());
272  EXPECT_TRUE(test.make_range().empty());
273  EXPECT_EQ(nullptr, test.give_cursor());
274 
275  EXPECT_EQ(0u, test.count());
276  EXPECT_TRUE(test.make_iterator().is_end());
277  EXPECT_TRUE(test.make_range().empty());
278  EXPECT_EQ(nullptr, test.give_cursor());
279 }
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
choice
Definition: lmdb.cpp:40
#define ELECTRONEUM_FIELD(obj, field)
Definition: util.h:40
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922

◆ TEST() [9/11]

TEST ( LMDB  ,
InvalidValueIterator   
)

Definition at line 281 of file lmdb.cpp.

282 {
283  struct one
284  {
285  choice i;
286  choice j;
287  bytes k;
288  };
289 
291 
292  EXPECT_TRUE((std::is_same<one, decltype(*test1)>()));
293  EXPECT_TRUE(
294  (std::is_same<bytes, decltype(test1.get_value<ELECTRONEUM_FIELD(one, k)>())>())
295  );
296 
297  EXPECT_TRUE(test1.is_end());
300  EXPECT_TRUE(test1.is_end());
301 
303 
304  EXPECT_TRUE(test2.is_end());
307  EXPECT_TRUE(test2.is_end());
308 
309  EXPECT_TRUE(test1.equal(test2));
310  EXPECT_TRUE(test2.equal(test1));
311  EXPECT_TRUE(test1 == test2);
312  EXPECT_TRUE(test2 == test1);
315 
317 
318  EXPECT_TRUE((std::is_same<bytes, decltype(*test3)>()));
319  EXPECT_TRUE((std::is_same<one, decltype(test3.get_value<one>())>()));
320  EXPECT_TRUE(
321  (std::is_same<choice, decltype(test1.get_value<ELECTRONEUM_FIELD(one, j)>())>())
322  );
323 
324  EXPECT_TRUE(test3.is_end());
327  EXPECT_TRUE(test3.is_end());
328 }
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
void test3()
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
choice
Definition: lmdb.cpp:40
#define ELECTRONEUM_FIELD(obj, field)
Definition: util.h:40
void test2()
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
void test1()
Here is the call graph for this function:

◆ TEST() [10/11]

TEST ( LMDB  ,
InvalidKeyStream   
)

Definition at line 330 of file lmdb.cpp.

331 {
332  struct one
333  {
334  choice i;
335  choice j;
336  bytes k;
337  };
338 
339  using record = std::pair<choice, boost::iterator_range<lmdb::value_iterator<one>>>;
340 
342 
343  EXPECT_TRUE((std::is_same<record, decltype(*(test.make_iterator()))>()));
344  EXPECT_TRUE((std::is_same<record, decltype(*(test.make_range().begin()))>()));
345 
346  EXPECT_NO_THROW(test.reset());
347  EXPECT_TRUE(test.make_iterator().is_end());
348  EXPECT_TRUE(test.make_range().empty());
349  EXPECT_EQ(nullptr, test.give_cursor());
350 
351  EXPECT_TRUE(test.make_iterator().is_end());
352  EXPECT_TRUE(test.make_range().empty());
353  EXPECT_EQ(nullptr, test.give_cursor());
354 }
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
choice
Definition: lmdb.cpp:40
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922

◆ TEST() [11/11]

TEST ( LMDB  ,
InvalidKeyIterator   
)

Definition at line 356 of file lmdb.cpp.

357 {
358  struct one
359  {
360  choice i;
361  choice j;
362  bytes k;
363  };
364 
365  using record = std::pair<choice, boost::iterator_range<lmdb::value_iterator<one>>>;
366 
368 
369  EXPECT_TRUE((std::is_same<record, decltype(*test1)>()));
370  EXPECT_TRUE((std::is_same<choice, decltype(test1.get_key())>()));
371  EXPECT_TRUE((std::is_same<one, decltype(*(test1.make_value_iterator()))>()));
372  EXPECT_TRUE((std::is_same<one, decltype(*(test1.make_value_range().begin()))>()));
373  EXPECT_TRUE(
374  (std::is_same<bytes, decltype(*(test1.make_value_iterator<ELECTRONEUM_FIELD(one, k)>()))>())
375  );
376  EXPECT_TRUE(
377  (std::is_same<bytes, decltype(*(test1.make_value_range<ELECTRONEUM_FIELD(one, k)>().begin()))>())
378  );
379 
380  EXPECT_TRUE(test1.is_end());
383  EXPECT_TRUE(test1.is_end());
384  EXPECT_TRUE(test1.make_value_iterator().is_end());
385  EXPECT_TRUE(test1.make_value_range().empty());
386 
388 
389  EXPECT_TRUE(test2.is_end());
392  EXPECT_TRUE(test2.is_end());
393  EXPECT_TRUE(test2.make_value_iterator().is_end());
394  EXPECT_TRUE(test2.make_value_range().empty());
395 
396  EXPECT_TRUE(test1.equal(test2));
397  EXPECT_TRUE(test2.equal(test1));
398  EXPECT_TRUE(test1 == test2);
399  EXPECT_TRUE(test2 == test1);
402 }
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
choice
Definition: lmdb.cpp:40
#define ELECTRONEUM_FIELD(obj, field)
Definition: util.h:40
void test2()
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
void test1()
Here is the call graph for this function: