Advertisement
Guest User

Untitled

a guest
Mar 22nd, 2014
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.08 KB | None | 0 0
  1.  
  2. #include <lmdb.h>
  3. #include <iostream>
  4. #include <cstring>
  5.  
  6. using namespace std;
  7.  
  8. class mdb_exception : public exception {
  9.   const char *msg;
  10. public:
  11.   inline explicit mdb_exception(int rc) {
  12.     msg = mdb_strerror(rc);
  13.   }
  14.   inline const char *what() const noexcept {
  15.     return msg;
  16.   }
  17. };
  18.  
  19. inline int C(int rc) {
  20.   if (rc != 0 && rc != MDB_NOTFOUND) {
  21.     throw mdb_exception(rc);
  22.   }
  23.   return rc;
  24. }
  25.  
  26. inline void print(const MDB_val &key, const MDB_val &data) {
  27.   cout << "---> key: " << string(static_cast<char*>(key.mv_data), key.mv_size / sizeof(char)) << endl;
  28.   cout << "---> data: " << string(static_cast<char*>(data.mv_data), data.mv_size / sizeof(char)) << endl;
  29. }
  30.  
  31. int main() {
  32.   MDB_val key, data;
  33.   MDB_env *env;
  34.   MDB_dbi dbi;
  35.   MDB_txn *txn;
  36.   MDB_cursor *cursor;
  37.  
  38.   // test data
  39.   unsigned testN = 6;
  40.   const char* testKeys[] = { "a", "b", "c", "e", "f", "g" };
  41.   const char* testData[] = { "helló_1", "wőúéáűrld_2", "42_3", "hello_4", "world_5", "42_6"  };
  42.  
  43.   // set up env
  44.   C(mdb_env_create(&env));
  45.   C(mdb_env_set_maxdbs(env, 10));
  46.   C(mdb_env_open(env, "./testdata", 0, 0644));
  47.  
  48.   // ------ open a clean dbi + fill up with test data
  49.  
  50.   // begin a txn
  51.   C(mdb_txn_begin(env, nullptr, 0, &txn));
  52.  
  53.   // ensure there is an empty dbi
  54.   C(mdb_dbi_open(txn, "my_test_data", MDB_CREATE, &dbi));
  55.   C(mdb_drop(txn, dbi, 1));
  56.   C(mdb_dbi_open(txn, "my_test_data", MDB_CREATE, &dbi));
  57.  
  58.   // fill up with some data
  59.   for (unsigned i = 0; i < testN; i++) {
  60.     key.mv_data = const_cast<char*>(testKeys[i]);
  61.     key.mv_size = sizeof(char) * strlen(testKeys[i]);
  62.     data.mv_data = const_cast<char*>(testData[i]);
  63.     data.mv_size = sizeof(char) * strlen(testData[i]);
  64.  
  65.     mdb_put(txn, dbi, &key, &data, 0);
  66.   }
  67.  
  68.   // commit the txn
  69.   C(mdb_txn_commit(txn));
  70.  
  71.   // ------ use a cursor
  72.  
  73.   // begin a txn + cursor
  74.   C(mdb_txn_begin(env, nullptr, 0, &txn));
  75.   C(mdb_cursor_open(txn, dbi, &cursor));
  76.  
  77.   // mess with the stuff
  78.   cout << "first (expected a)" << endl;
  79.   C(mdb_cursor_get(cursor, &key, &data, MDB_FIRST));
  80.   C(mdb_cursor_get(cursor, &key, &data, MDB_GET_CURRENT));
  81.   print(key, data);
  82.  
  83.   cout << "next (expected b)" << endl;
  84.   C(mdb_cursor_get(cursor, &key, &data, MDB_NEXT));
  85.   C(mdb_cursor_get(cursor, &key, &data, MDB_GET_CURRENT));
  86.   print(key, data);
  87.  
  88.   cout << "next (expected c)" << endl;
  89.   C(mdb_cursor_get(cursor, &key, &data, MDB_NEXT));
  90.   C(mdb_cursor_get(cursor, &key, &data, MDB_GET_CURRENT));
  91.   print(key, data);
  92.  
  93.   cout << "next (expected e)" << endl;
  94.   C(mdb_cursor_get(cursor, &key, &data, MDB_NEXT));
  95.   C(mdb_cursor_get(cursor, &key, &data, MDB_GET_CURRENT));
  96.   print(key, data);
  97.  
  98.   cout << "prev (expected c)" << endl;
  99.   C(mdb_cursor_get(cursor, &key, &data, MDB_PREV));
  100.   C(mdb_cursor_get(cursor, &key, &data, MDB_GET_CURRENT));
  101.   print(key, data);
  102.  
  103.   cout << "last (expected g)" << endl;
  104.   C(mdb_cursor_get(cursor, &key, &data, MDB_LAST));
  105.   C(mdb_cursor_get(cursor, &key, &data, MDB_GET_CURRENT));
  106.   print(key, data);
  107.  
  108.   // oops
  109.   mdb_dbi_close(env, dbi);
  110.  
  111.   cout << "go to key b (expected b)" << endl;
  112.   key.mv_data = (void*) "b";
  113.   key.mv_size = sizeof(char);
  114.   C(mdb_cursor_get(cursor, &key, &data, MDB_SET));
  115.   C(mdb_cursor_get(cursor, &key, &data, MDB_GET_CURRENT));
  116.   print(key, data);
  117.  
  118.   cout << "go to key d (expected e)" << endl;
  119.   key.mv_data = (void*) "d";
  120.   key.mv_size = sizeof(char);
  121.   C(mdb_cursor_get(cursor, &key, &data, MDB_SET_RANGE));
  122.   C(mdb_cursor_get(cursor, &key, &data, MDB_GET_CURRENT));
  123.   print(key, data);
  124.  
  125.   cout << "del (expected f)" << endl;
  126.   C(mdb_cursor_del(cursor, 0));
  127.   C(mdb_cursor_get(cursor, &key, &data, MDB_GET_CURRENT));
  128.   print(key, data);
  129.  
  130.   // now go through all keys
  131.   cout << "---------------------------------" << endl;
  132.   C(mdb_cursor_get(cursor, &key, &data, MDB_FIRST));
  133.   do {
  134.     print(key, data);
  135.   } while (C(mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0);
  136.  
  137.   // close cursor + commit the txn
  138.   mdb_cursor_close(cursor);
  139.   C(mdb_txn_commit(txn));
  140.  
  141.   // close dbi & env
  142.   mdb_dbi_close(env, dbi);
  143.   mdb_env_close(env);
  144.  
  145.   return 0;
  146. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement