From ec4a44e4de4c3cb5983af55d349dc11bda718713 Mon Sep 17 00:00:00 2001 From: Martchus Date: Sun, 30 Jan 2022 21:32:08 +0100 Subject: [PATCH] Format tests and examples as well --- CMakeLists.txt | 12 +- examples/basic.cc | 60 +++--- examples/multi.cc | 83 ++++---- examples/rel.cc | 240 ++++++++++----------- examples/resize.cc | 131 ++++++------ examples/scale.cc | 93 +++++---- examples/typed.cc | 361 ++++++++++++++++---------------- examples/view.cc | 57 +++-- tests/basic.cc | 511 ++++++++++++++++++++++----------------------- tests/typed.cc | 87 ++++---- 10 files changed, 811 insertions(+), 824 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7194326..2ca0f58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,16 @@ use_package(TARGET_NAME Catch2::Catch2 PACKAGE_NAME Catch2 LIBRARIES_VARIABLE "T # find threading library (required by examples) use_package(TARGET_NAME Threads::Threads PACKAGE_NAME Threads LIBRARIES_VARIABLE "TEST_LIBRARIES") +# add test/example files to EXCLUDED_FILES so they're formatted +set(TESTS basic typed) +set(EXAMPLES basic multi rel resize scale typed view) +foreach (TEST ${TESTS}) + list(APPEND EXCLUDED_FILES "tests/${TEST}.cc") +endforeach () +foreach (EXAMPLE ${EXAMPLES}) + list(APPEND EXCLUDED_FILES "examples/${EXAMPLE}.cc") +endforeach () + # include modules to apply configuration include(BasicConfig) include(WindowsResources) @@ -71,11 +81,9 @@ include(ConfigHeader) # configure test targets include(TestUtilities) list(APPEND TEST_LIBRARIES ${META_TARGET_NAME}) -set(TESTS basic typed) foreach (TEST ${TESTS}) configure_test_target(TEST_NAME "${TEST}_tests" SRC_FILES "tests/${TEST}.cc" LIBRARIES "${TEST_LIBRARIES}") endforeach () -set(EXAMPLES basic multi rel resize scale typed view) foreach (EXAMPLE ${EXAMPLES}) configure_test_target(TEST_NAME "${EXAMPLE}_example" SRC_FILES "examples/${EXAMPLE}.cc" LIBRARIES "${TEST_LIBRARIES}") endforeach () diff --git a/examples/basic.cc b/examples/basic.cc index bef1126..52f3d08 100644 --- a/examples/basic.cc +++ b/examples/basic.cc @@ -3,42 +3,40 @@ using namespace std; using namespace LMDBSafe; -void checkLMDB(MDBEnv* env, MDBDbi dbi) +void checkLMDB(MDBEnv *env, MDBDbi dbi) { - auto rotxn = env->getROTransaction(); - MDBOutVal data; - if(!rotxn->get(dbi, "lmdb", data)) { - cout<< "Outside RW transaction, found that lmdb = " << data.get() <getROTransaction(); + MDBOutVal data; + if (!rotxn->get(dbi, "lmdb", data)) { + cout << "Outside RW transaction, found that lmdb = " << data.get() << endl; + } else + cout << "Outside RW transaction, found nothing" << endl; } int main() { - auto env = getMDBEnv("./database", MDB_NOSUBDIR, 0600); - auto dbi = env->openDB("example", MDB_CREATE); - - auto txn = env->getRWTransaction(); - mdb_drop(*txn, dbi, 0); - txn->put(dbi, "lmdb", "great"); + auto env = getMDBEnv("./database", MDB_NOSUBDIR, 0600); + auto dbi = env->openDB("example", MDB_CREATE); - MDBOutVal data; - if(!txn->get(dbi, "lmdb", data)) { - cout<< "Within RW transaction, found that lmdb = " << data.get() <getRWTransaction(); + mdb_drop(*txn, dbi, 0); + txn->put(dbi, "lmdb", "great"); - std::thread elsewhere(checkLMDB, env.get(), dbi); - elsewhere.join(); - - txn->commit(); - - cout<<"Committed data"<getRWTransaction(); - mdb_drop(*txn, dbi, 0); - txn->commit(); + MDBOutVal data; + if (!txn->get(dbi, "lmdb", data)) { + cout << "Within RW transaction, found that lmdb = " << data.get() << endl; + } else + cout << "Found nothing" << endl; + + std::thread elsewhere(checkLMDB, env.get(), dbi); + elsewhere.join(); + + txn->commit(); + + cout << "Committed data" << endl; + + checkLMDB(env.get(), dbi); + txn = env->getRWTransaction(); + mdb_drop(*txn, dbi, 0); + txn->commit(); } diff --git a/examples/multi.cc b/examples/multi.cc index 15134a7..96abc19 100644 --- a/examples/multi.cc +++ b/examples/multi.cc @@ -7,56 +7,53 @@ using namespace LMDBSafe; int main() { - unlink("./multi"); - auto env = getMDBEnv("multi", MDB_NOSUBDIR, 0600); - auto dbi = env->openDB("qnames", MDB_DUPSORT | MDB_CREATE); + unlink("./multi"); + auto env = getMDBEnv("multi", MDB_NOSUBDIR, 0600); + auto dbi = env->openDB("qnames", MDB_DUPSORT | MDB_CREATE); - auto txn = env->getRWTransaction(); - txn->clear(dbi); + auto txn = env->getRWTransaction(); + txn->clear(dbi); - txn->put(dbi, "bdb", "old"); - txn->put(dbi, "lmdb", "hot"); - txn->put(dbi, "lmdb", "fast"); - txn->put(dbi, "lmdb", "zooms"); - txn->put(dbi, "lmdb", "c"); - txn->put(dbi, "mdb", "old name"); + txn->put(dbi, "bdb", "old"); + txn->put(dbi, "lmdb", "hot"); + txn->put(dbi, "lmdb", "fast"); + txn->put(dbi, "lmdb", "zooms"); + txn->put(dbi, "lmdb", "c"); + txn->put(dbi, "mdb", "old name"); - string_view v1; - if(!txn->get(dbi, "mdb", v1)) { - cout<commit(); - - txn = env->getRWTransaction(); - auto cursor = txn->getRWCursor(dbi); + string_view v1; + if (!txn->get(dbi, "mdb", v1)) { + cout << v1 << endl; + } else { + cout << "found nothing" << endl; + } + txn->commit(); - MDBOutVal key, data; + txn = env->getRWTransaction(); + auto cursor = txn->getRWCursor(dbi); - for(int rc = cursor.find("lmdb", key, data); !rc; rc = cursor.get(key, data, MDB_NEXT_DUP)) { - cout << key.get() << " = " << data.get() <() << " = " << data.get() <() << " = " << data.get() << endl; + } - cout << "Now going to delete 'lmdb' keys" << endl; + cout << "Dump of complete database: " << endl; + for (int rc = cursor.first(key, data); !rc; rc = cursor.next(key, data)) { + cout << key.get() << " = " << data.get() << endl; + } + cout << "Done!" << endl; - for(int rc = cursor.first(key, data); !rc; rc = cursor.next(key, data)) { - if(key.get() == "lmdb") - cursor.del(); - } + cout << "Now going to delete 'lmdb' keys" << endl; - cout <<"Complete database after deleting 'lmdb' keys: " << endl; - - for(int rc = cursor.first(key, data); !rc; rc = cursor.next(key, data)) { - cout << key.get() << " = " << data.get() <() == "lmdb") + cursor.del(); + } + + cout << "Complete database after deleting 'lmdb' keys: " << endl; + + for (int rc = cursor.first(key, data); !rc; rc = cursor.next(key, data)) { + cout << key.get() << " = " << data.get() << endl; + } } diff --git a/examples/rel.cc b/examples/rel.cc index c9d4513..b78551b 100644 --- a/examples/rel.cc +++ b/examples/rel.cc @@ -1,7 +1,7 @@ #include "../lmdb-safe.hh" -#include #include +#include #include @@ -10,157 +10,149 @@ using namespace std; using namespace LMDBSafe; -struct Record -{ +struct Record { - friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int version) - { - CPP_UTILITIES_UNUSED(version) - ar & id & domain_id & name & type & ttl & content & enabled & auth; - } - - unsigned int id; - unsigned int domain_id; // needs index - std::string name; // needs index - std::string type; - unsigned int ttl{0}; - std::string content; - bool enabled{true}; - bool auth{true}; + friend class boost::serialization::access; + template void serialize(Archive &ar, const unsigned int version) + { + CPP_UTILITIES_UNUSED(version) + ar &id &domain_id &name &type &ttl &content &enabled &auth; + } + unsigned int id; + unsigned int domain_id; // needs index + std::string name; // needs index + std::string type; + unsigned int ttl{ 0 }; + std::string content; + bool enabled{ true }; + bool auth{ true }; }; -static unsigned int getMaxID(MDBRWTransaction& txn, MDBDbi& dbi) +static unsigned int getMaxID(MDBRWTransaction &txn, MDBDbi &dbi) { - auto cursor = txn->getRWCursor(dbi); - MDBOutVal maxidval, maxcontent; - unsigned int maxid{0}; - if(!cursor.get(maxidval, maxcontent, MDB_LAST)) { - maxid = maxidval.get(); - } - return maxid; + auto cursor = txn->getRWCursor(dbi); + MDBOutVal maxidval, maxcontent; + unsigned int maxid{ 0 }; + if (!cursor.get(maxidval, maxcontent, MDB_LAST)) { + maxid = maxidval.get(); + } + return maxid; } -static void store(MDBRWTransaction& txn, MDBDbi& records, MDBDbi& domainidx, MDBDbi&nameidx, const Record& r) +static void store(MDBRWTransaction &txn, MDBDbi &records, MDBDbi &domainidx, MDBDbi &nameidx, const Record &r) { - ostringstream oss; - boost::archive::binary_oarchive oa(oss,boost::archive::no_header ); - oa << r; - - txn->put(records, r.id, oss.str(), MDB_APPEND); - txn->put(domainidx, r.domain_id, r.id); - txn->put(nameidx, r.name, r.id); + ostringstream oss; + boost::archive::binary_oarchive oa(oss, boost::archive::no_header); + oa << r; + + txn->put(records, r.id, oss.str(), MDB_APPEND); + txn->put(domainidx, r.domain_id, r.id); + txn->put(nameidx, r.name, r.id); } - -int main(int argc, char** argv) +int main(int argc, char **argv) { - auto env = getMDBEnv("pdns", MDB_NOSUBDIR, 0600); - auto records = env->openDB("records", MDB_INTEGERKEY | MDB_CREATE ); - auto domainidx = env->openDB("domainidx", MDB_INTEGERKEY | MDB_DUPFIXED | MDB_DUPSORT | MDB_CREATE); - auto nameidx = env->openDB("nameidx", MDB_DUPFIXED | MDB_DUPSORT | MDB_CREATE); + auto env = getMDBEnv("pdns", MDB_NOSUBDIR, 0600); + auto records = env->openDB("records", MDB_INTEGERKEY | MDB_CREATE); + auto domainidx = env->openDB("domainidx", MDB_INTEGERKEY | MDB_DUPFIXED | MDB_DUPSORT | MDB_CREATE); + auto nameidx = env->openDB("nameidx", MDB_DUPFIXED | MDB_DUPSORT | MDB_CREATE); - auto txn = env->getRWTransaction(); + auto txn = env->getRWTransaction(); - /* + /* txn.clear(records); txn.clear(domainidx); txn.clear(domainidx); txn.clear(nameidx); */ - unsigned int maxid=getMaxID(txn, records); - unsigned int maxdomainid=getMaxID(txn, domainidx); - - cout<<"Maxid = "<= 3 ? argv[2] : "10"); - for(int n=0; n < lim; ++n) { - string domain; - if(n) - domain.assign(prefix+std::to_string(n)+".com"); - else - domain="powerdns.com"; - Record r; - r.id=++maxid; - r.domain_id = ++maxdomainid; - r.name = domain; - r.ttl = 3600; - r.type = "SOA"; - r.content = "ns1.powerdns.com ahu.powerdns.com 1"; + cout << "Maxid = " << maxid << ", Max domain ID = " << maxdomainid << endl; - store(txn, records, domainidx, nameidx, r); + string prefix(argc >= 2 ? argv[1] : "prefix"); + auto lim = atoi(argc >= 3 ? argv[2] : "10"); + for (int n = 0; n < lim; ++n) { + string domain; + if (n) + domain.assign(prefix + std::to_string(n) + ".com"); + else + domain = "powerdns.com"; + Record r; + r.id = ++maxid; + r.domain_id = ++maxdomainid; + r.name = domain; + r.ttl = 3600; + r.type = "SOA"; + r.content = "ns1.powerdns.com ahu.powerdns.com 1"; - r.id=++maxid; - r.type="NS"; - r.content="ns1.powerdns.com"; - store(txn, records, domainidx, nameidx, r); + store(txn, records, domainidx, nameidx, r); + r.id = ++maxid; + r.type = "NS"; + r.content = "ns1.powerdns.com"; + store(txn, records, domainidx, nameidx, r); - r.id=++maxid; - r.type="A"; - r.content="1.2.3.4"; - store(txn, records, domainidx, nameidx, r); + r.id = ++maxid; + r.type = "A"; + r.content = "1.2.3.4"; + store(txn, records, domainidx, nameidx, r); - r.id=++maxid; - r.type="AAAA"; - r.content="::1"; - store(txn, records, domainidx, nameidx, r); + r.id = ++maxid; + r.type = "AAAA"; + r.content = "::1"; + store(txn, records, domainidx, nameidx, r); - r.id=++maxid; - r.type="CAA"; - r.content="letsencrypt.org"; - store(txn, records, domainidx, nameidx, r); - + r.id = ++maxid; + r.type = "CAA"; + r.content = "letsencrypt.org"; + store(txn, records, domainidx, nameidx, r); - r.id=++maxid; - r.type="AAAA"; - r.name="www."+domain; - r.content="::1"; - store(txn, records, domainidx, nameidx, r); + r.id = ++maxid; + r.type = "AAAA"; + r.name = "www." + domain; + r.content = "::1"; + store(txn, records, domainidx, nameidx, r); - r.id=++maxid; - r.type="A"; - r.name="www."+domain; - r.content="127.0.0.1"; - store(txn, records, domainidx, nameidx, r); - } - - txn->commit(); - - auto rotxn = env->getROTransaction(); - auto rotxn2 = env->getROTransaction(); - - auto rocursor = rotxn->getCursor(nameidx); - - MDBOutVal data; - int count = 0; - MDBOutVal key; - - MDBInVal tmp("www.powerdns.com"); - key.d_mdbval = tmp.d_mdbval; - - // ugh - - while(!rocursor.get(key, data, count ? MDB_NEXT_DUP : MDB_SET)) { - unsigned int id = data.get(); - cout<<"Got something: id="<get(records, data, record)) { - Record test; - stringstream istr{record.get()}; - boost::archive::binary_iarchive oi(istr,boost::archive::no_header ); - oi >> test; - cout <<"Record: "<commit(); + + auto rotxn = env->getROTransaction(); + auto rotxn2 = env->getROTransaction(); + + auto rocursor = rotxn->getCursor(nameidx); + + MDBOutVal data; + int count = 0; + MDBOutVal key; + + MDBInVal tmp("www.powerdns.com"); + key.d_mdbval = tmp.d_mdbval; + + // ugh + + while (!rocursor.get(key, data, count ? MDB_NEXT_DUP : MDB_SET)) { + unsigned int id = data.get(); + cout << "Got something: id=" << id << endl; + MDBOutVal record; + + if (!rotxn->get(records, data, record)) { + Record test; + stringstream istr{ record.get() }; + boost::archive::binary_iarchive oi(istr, boost::archive::no_header); + oi >> test; + cout << "Record: " << test.name << " " << test.type << " " << test.ttl << " " << test.content << endl; + } else { + cout << "Did not find anything for id " << id << endl; + } + ++count; } - ++count; - } - } diff --git a/examples/resize.cc b/examples/resize.cc index 63c6ceb..dbefe96 100644 --- a/examples/resize.cc +++ b/examples/resize.cc @@ -5,87 +5,78 @@ using namespace std; using namespace LMDBSafe; -template -struct Pair { +template struct Pair { First first; Second second; }; -int main(int argc, char**) +int main(int argc, char **) { - auto env = getMDBEnv("resize", MDB_NOSUBDIR | MDB_NOSYNC, 0600); - auto main = env->openDB("ahu", MDB_CREATE ); + auto env = getMDBEnv("resize", MDB_NOSUBDIR | MDB_NOSYNC, 0600); + auto main = env->openDB("ahu", MDB_CREATE); - MDBInVal key("counter"); + MDBInVal key("counter"); - auto rwtxn = env->getRWTransaction(); - rwtxn->put(main, "counter", "1234"); - rwtxn->put(main, MDBInVal::fromStruct(Pair{12,13}), "hoi dan 12,13"); + auto rwtxn = env->getRWTransaction(); + rwtxn->put(main, "counter", "1234"); + rwtxn->put(main, MDBInVal::fromStruct(Pair{ 12, 13 }), "hoi dan 12,13"); - rwtxn->put(main, MDBInVal::fromStruct(Pair{14,15}), - MDBInVal::fromStruct(Pair{20,23})); + rwtxn->put(main, MDBInVal::fromStruct(Pair{ 14, 15 }), MDBInVal::fromStruct(Pair{ 20, 23 })); - - MDBOutVal out; - if(!rwtxn->get(main, MDBInVal::fromStruct(Pair{12,13}), out)) - cout << "Got: " << out.get() << endl; - else - cout << "Got nothing!1"<get(main, MDBInVal::fromStruct(Pair{14,15}), out)) { - auto res = out.get_struct>(); - cout << "Got: " << res.first<<", "<get(main, MDBInVal::fromStruct(Pair{ 12, 13 }), out)) + cout << "Got: " << out.get() << endl; + else + cout << "Got nothing!1" << endl; - rwtxn->put(main, 12.12, 7.3); - if(!rwtxn->get(main, 12.12, out)) { - cout<<"Got: "<< out.get() <get(main, MDBInVal::fromStruct(Pair{ 14, 15 }), out)) { + auto res = out.get_struct>(); + cout << "Got: " << res.first << ", " << res.second << endl; + } else + cout << "Got nothing!1" << endl; - - rwtxn->commit(); - return 0; - - if(argc==1) { - for(;;) { - auto rotxn = env->getROTransaction(); - MDBOutVal data; - if(!rotxn->get(main, key, data)) { - cout<<"Counter is "<() << endl; - cout <() << endl; - cout<() << endl; + rwtxn->put(main, 12.12, 7.3); + if (!rwtxn->get(main, 12.12, out)) { + cout << "Got: " << out.get() << endl; + } else + cout << "Got nothing!1" << endl; - struct Bert - { - uint16_t x,y; - }; - auto b = data.get_struct(); - cout<() << endl; - } - else - cout<<"Didn't find it"<commit(); + return 0; + + if (argc == 1) { + for (;;) { + auto rotxn = env->getROTransaction(); + MDBOutVal data; + if (!rotxn->get(main, key, data)) { + cout << "Counter is " << data.get() << endl; + cout << data.get() << endl; + cout << data.get() << endl; + + struct Bert { + uint16_t x, y; + }; + auto b = data.get_struct(); + cout << b.x << " " << b.y << endl; + cout << data.get() << endl; + } else + cout << "Didn't find it" << endl; + exit(1); + } + } else { + size_t size = 1ULL * 4096 * 244140ULL; + for (unsigned int n = 0;; ++n) { + if (!(n % 16384)) { + size += 16384; + if (int rc = mdb_env_set_mapsize(*env.get(), size)) + throw std::runtime_error("Resizing: " + string(mdb_strerror(rc))); + cout << "Did resize" << endl; + } + auto txn = env->getRWTransaction(); + txn->put(main, key, MDBInVal(n)); + for (unsigned int k = 0; k < 100; ++k) + txn->put(main, MDBInVal(n + 1000 * k), MDBInVal(n + 1000 * k)); + txn->commit(); + } } - } - else { - size_t size = 1ULL*4096*244140ULL; - for(unsigned int n=0;;++n) { - if(!(n%16384)) { - size += 16384; - if(int rc=mdb_env_set_mapsize(*env.get(), size)) - throw std::runtime_error("Resizing: "+string(mdb_strerror(rc))); - cout<<"Did resize"<getRWTransaction(); - txn->put(main, key, MDBInVal(n)); - for(unsigned int k=0; k < 100; ++k) - txn->put(main, MDBInVal(n+1000*k), MDBInVal(n+1000*k)); - txn->commit(); - } - } } diff --git a/examples/scale.cc b/examples/scale.cc index 74a7b11..6f9388e 100644 --- a/examples/scale.cc +++ b/examples/scale.cc @@ -5,54 +5,57 @@ using namespace std; using namespace LMDBSafe; -struct MDBVal -{ - MDBVal(unsigned int v) : d_v(v) - { - d_mdbval.mv_size = sizeof(d_v); - d_mdbval.mv_data = &d_v; - } - operator const MDB_val&() - { - return d_mdbval; - } - unsigned int d_v; - MDB_val d_mdbval; +struct MDBVal { + MDBVal(unsigned int v) + : d_v(v) + { + d_mdbval.mv_size = sizeof(d_v); + d_mdbval.mv_data = &d_v; + } + operator const MDB_val &() + { + return d_mdbval; + } + unsigned int d_v; + MDB_val d_mdbval; }; - -int main(int argc, char** argv) +int main(int argc, char **argv) { - auto env = getMDBEnv("./database", MDB_NOSUBDIR, 0600); - auto dbi = env->openDB(std::string_view(), MDB_CREATE | MDB_INTEGERKEY); - auto txn = env->getRWTransaction(); + auto env = getMDBEnv("./database", MDB_NOSUBDIR, 0600); + auto dbi = env->openDB(std::string_view(), MDB_CREATE | MDB_INTEGERKEY); + auto txn = env->getRWTransaction(); - unsigned int limit=20; - if(argc > 1) - limit = CppUtilities::stringToNumber(argv[1]); - - cout<<"Counting records.. "; cout.flush(); - auto cursor = txn->getCursor(dbi); - MDBOutVal key, data; - int count=0; - while(!cursor.get(key, data, count ? MDB_NEXT : MDB_FIRST)) { - auto d = data.get(); - if(d==17) - cout <<"Got 17!"< 1) + limit = CppUtilities::stringToNumber(argv[1]); - cout << "Adding "<put(dbi, n, n, MDB_APPEND); - } - cout <<"Done!"<commit(); - cout<<"Done!"<getCursor(dbi); + MDBOutVal key, data; + int count = 0; + while (!cursor.get(key, data, count ? MDB_NEXT : MDB_FIRST)) { + auto d = data.get(); + if (d == 17) + cout << "Got 17!" << endl; + count++; + } + cout << "Have " << count << "!" << endl; + + cout << "Clearing records.. "; + cout.flush(); + mdb_drop(*txn, dbi, 0); // clear records + cout << "Done!" << endl; + + cout << "Adding " << limit << " values .. "; + cout.flush(); + for (unsigned long n = 0; n < limit; ++n) { + txn->put(dbi, n, n, MDB_APPEND); + } + cout << "Done!" << endl; + cout << "Calling commit.. "; + cout.flush(); + txn->commit(); + cout << "Done!" << endl; } diff --git a/examples/typed.cc b/examples/typed.cc index 50069b2..ef1e89c 100644 --- a/examples/typed.cc +++ b/examples/typed.cc @@ -10,225 +10,232 @@ using namespace std; using namespace LMDBSafe; -struct DNSResourceRecord -{ - string qname; // index - uint16_t qtype{0}; - uint32_t domain_id{0}; // index - string content; - uint32_t ttl{0}; - string ordername; // index - bool auth{true}; +struct DNSResourceRecord { + string qname; // index + uint16_t qtype{ 0 }; + uint32_t domain_id{ 0 }; // index + string content; + uint32_t ttl{ 0 }; + string ordername; // index + bool auth{ true }; }; -struct DomainInfo -{ - string qname; - string master; +struct DomainInfo { + string qname; + string master; }; -template -void serialize(Archive & ar, DomainInfo& g, const unsigned int version) +template void serialize(Archive &ar, DomainInfo &g, const unsigned int version) { - CPP_UTILITIES_UNUSED(version) - ar & g.qname & g.master; + CPP_UTILITIES_UNUSED(version) + ar &g.qname &g.master; } -template -void serialize(Archive & ar, DNSResourceRecord& g, const unsigned int version) +template void serialize(Archive &ar, DNSResourceRecord &g, const unsigned int version) { - CPP_UTILITIES_UNUSED(version) - ar & g.qtype; - ar & g.qname; - ar & g.content; - ar & g.ttl; - ar & g.domain_id; - ar & g.ordername; - ar & g.auth; + CPP_UTILITIES_UNUSED(version) + ar &g.qtype; + ar &g.qname; + ar &g.content; + ar &g.ttl; + ar &g.domain_id; + ar &g.ordername; + ar &g.auth; } - -struct compound -{ - std::string operator()(const DNSResourceRecord& rr) - { - std::string ret; - uint32_t id = htonl(rr.domain_id); - ret.assign(reinterpret_cast(&id), 4); - ret.append(rr.ordername); - return ret; - } +struct compound { + std::string operator()(const DNSResourceRecord &rr) + { + std::string ret; + uint32_t id = htonl(rr.domain_id); + ret.assign(reinterpret_cast(&id), 4); + ret.append(rr.ordername); + return ret; + } }; int main() { - TypedDBI, - index_on, - index_on_function - > tdbi(getMDBEnv("./typed.lmdb", MDB_NOSUBDIR, 0600), "records"); + TypedDBI, + index_on, index_on_function> + tdbi(getMDBEnv("./typed.lmdb", MDB_NOSUBDIR, 0600), "records"); - TypedDBI - > tdomains(tdbi.getEnv(), "domains"); + TypedDBI> tdomains(tdbi.getEnv(), "domains"); - - { - auto rotxn = tdbi.getROTransaction(); - DNSResourceRecord rr0; - if(rotxn.get(2, rr0)) { - cout << "id 2, found "<("powerdns.com"); - for(auto iter = std::move(range.first); iter != range.second; ++iter) { - cout << iter->qname << " " << iter->qtype << " " <content <("powerdns.com"); + for (auto iter = std::move(range.first); iter != range.second; ++iter) { + cout << iter->qname << " " << iter->qtype << " " << iter->content << endl; + } + cout << "Currently have " << rotxn.size() << " entries" << endl; + cout << " " << rotxn.size<0>() << " " << rotxn.size<1>() << " " << rotxn.size<2>() << endl; + cout << " " << rotxn.cardinality<0>() << endl; + cout << " " << rotxn.cardinality<1>() << endl; + cout << " " << rotxn.cardinality<2>() << endl; } - cout<<"Currently have "<< rotxn.size()<< " entries"<() << " " << rotxn.size<1>() << " " << rotxn.size<2>() << endl; - cout<<" " << rotxn.cardinality<0>() << endl; - cout<<" " << rotxn.cardinality<1>() << endl; - cout<<" " << rotxn.cardinality<2>() << endl; - } - - auto txn = tdbi.getRWTransaction(); - auto domtxn = tdomains.getRWTransaction(txn.getTransactionHandle()); - cout << domtxn.size()<<" domains in table"<() << " " << txn.size<1>() << " " << txn.size<2>() << endl; - cout<<" " << txn.cardinality<0>() << endl; - cout<<" " << txn.cardinality<1>() << endl; - cout<<" " << txn.cardinality<2>() << endl; - DomainInfo di{"powerdns.com", "ns1.powerdns.com"}; - domtxn.put(di, 11); - - DNSResourceRecord rr; - rr.domain_id=11; rr.qtype = 5; rr.ttl = 3600; rr.qname = "www.powerdns.com"; rr.ordername = "www"; - rr.content = "powerdns.com"; - - auto id = txn.put(rr); - cout<<"Puted as id "<() << " " << txn.size<1>() << " " << txn.size<2>() << endl; + cout << " " << txn.cardinality<0>() << endl; + cout << " " << txn.cardinality<1>() << endl; + cout << " " << txn.cardinality<2>() << endl; - rr.qtype = 2; rr.content = "ns1.powerdns.com"; rr.ordername = "ns1"; - id = txn.put(rr); - cout<<"Puted as id "<("www.powerdns.com", rr2); + DomainInfo di2{ "ds9a.nl", "ns1.powerdns.com" }; + domtxn.put(di, 10); - cout<<"Retrieved id "<< id <<", content: "<("powerdns.com", rr2); + rr.qname = "ds9a.nl"; + rr.content = "ns1.ds9a.nl bert.ds9a.nl 1"; + rr.qtype = 6; + rr.ordername = ""; + txn.put(rr); - cout<<"Retrieved id "<< id <<", content: "<("powerdns.com", rr3); - cout<< id << endl; + rr.qname = "ns1.ds9a.nl"; + rr.content = "1.2.3.4"; + rr.qtype = 1; + rr.ordername = "ns1"; + txn.put(rr); + rr.qname = "ns1.ds9a.nl"; + rr.content = "::1"; + rr.qtype = 26; + txn.put(rr); + rr.qname = "ns2.ds9a.nl"; + rr.content = "1.2.3.4"; + rr.qtype = 1; + rr.ordername = "ns2"; + txn.put(rr); + rr.qname = "ns2.ds9a.nl"; + rr.content = "::1"; + rr.qtype = 26; + txn.put(rr); - cout<<"Going to iterate over everything, ordered by name!"<(); iter != txn.end(); ++iter) { - cout << iter.getID()<<": "<qname << " " << iter->qtype << " " << iter->content <("www.powerdns.com", rr2); - cout<<"Going to iterate over everything, ordered by domain_id!"<(); iter != txn.end(); ++iter) { - cout << iter.getID()<<": "<qname << " " << iter->qtype << " " << iter->content <qname << " " << iter->qtype << " " << iter->content <("powerdns.com", rr2); - cout<<"Going to iterate over everything, ordered by compound index!"<(); iter != txn.end(); ++iter) { - cout << iter.getID()<<": "<qname << " " << iter->qtype << " " << iter->content <<" # "<ordername << endl; - } + cout << "Retrieved id " << id << ", content: " << rr2.content << endl; - compound c; - rr3.ordername = "vvv"; - rr3.domain_id = 10; - auto iter = txn.lower_bound<2>(c(rr3)); - cout <<"Found for '"<qname<< " # '" <ordername<< "'"<qname<< " # '" <ordername<<"'"<("powerdns.com", rr3); + cout << id << endl; - for(auto iter2 = txn.equal_range<0>("powerdns.com"); iter2.first != iter2.second; ++iter2.first) { - cout << iter2.first.getID()<<": "<qname << " " << iter2.first->qtype << " " << iter2.first->content <(); iter != txn.end(); ++iter) { + cout << iter.getID() << ": " << iter->qname << " " << iter->qtype << " " << iter->content << endl; + } - cout<<"Going to iterate over the zone ds9a.nl!"<(); iter != txn.end(); ++iter) { + cout << iter.getID() << ": " << iter->qname << " " << iter->qtype << " " << iter->content << endl; + } - for(auto iter2 = txn.find<1>(10); iter2 != txn.end(); ++iter2) { - cout << iter2.getID()<<": "<qname << " " << iter2->qtype << " " << iter2->content <qname << " " << iter->qtype << " " << iter->content << endl; + } - DNSResourceRecord change; - txn.get(1, change); - cout<<"1.auth: "<(); iter != txn.end(); ++iter) { + cout << iter.getID() << ": " << iter->qname << " " << iter->qtype << " " << iter->content << " # " << iter->ordername << endl; + } - // DNSResourceRecord rr4; - // id = txn.get3("ns1", rr4); - // cout<<"Found "<(c(rr3)); + cout << "Found for '" << rr3.ordername << "' using compound index: " << iter->qname << " # '" << iter->ordername << "'" << endl; + for (int n = 0; n < 4; ++n) { + --iter; + cout << "Found PREV using compound index: " << iter->qname << " # '" << iter->ordername << "'" << endl; + } - txn.commit(); + cout << "Going to iterate over the name powerdns.com!" << endl; + + for (auto iter2 = txn.equal_range<0>("powerdns.com"); iter2.first != iter2.second; ++iter2.first) { + cout << iter2.first.getID() << ": " << iter2.first->qname << " " << iter2.first->qtype << " " << iter2.first->content << endl; + } + cout << "Done iterating" << endl; + + cout << "Going to iterate over the zone ds9a.nl!" << endl; + + for (auto iter2 = txn.find<1>(10); iter2 != txn.end(); ++iter2) { + cout << iter2.getID() << ": " << iter2->qname << " " << iter2->qtype << " " << iter2->content << endl; + } + cout << "Done iterating" << endl; + + DNSResourceRecord change; + txn.get(1, change); + cout << "1.auth: " << change.auth << endl; + txn.modify(1, [](DNSResourceRecord &record) { record.auth = false; }); + txn.get(1, change); + cout << "1.auth: " << change.auth << endl; + txn.del(1); + + // DNSResourceRecord rr4; + // id = txn.get3("ns1", rr4); + // cout<<"Found "<openDB(dbname, 0); - auto cursor = txn->getCursor(db); - uint32_t count = 0; - MDBOutVal key, val; - while(!cursor.get(key, val, count ? MDB_NEXT : MDB_FIRST)) { - cout << key.get(); - if(key.d_mdbval.mv_size == 4) - cout << " " << key.get(); - cout<<": " << val.get(); - cout << "\n"; - ++count; - - } - cout <openDB(dbname, 0); + auto cursor = txn->getCursor(db); + uint32_t count = 0; + MDBOutVal key, val; + while (!cursor.get(key, val, count ? MDB_NEXT : MDB_FIRST)) { + cout << key.get(); + if (key.d_mdbval.mv_size == 4) + cout << " " << key.get(); + cout << ": " << val.get(); + cout << "\n"; + ++count; + } + cout << count << endl; } -int main(int argc, char** argv) +int main(int argc, char **argv) { - MDBEnv env(argc >= 2 ? argv[1] : "./database", MDB_RDONLY | MDB_NOSUBDIR, 0600); - auto main = env.openDB("", 0); - auto txn = env.getROTransaction(); + MDBEnv env(argc >= 2 ? argv[1] : "./database", MDB_RDONLY | MDB_NOSUBDIR, 0600); + auto main = env.openDB("", 0); + auto txn = env.getROTransaction(); - auto cursor = txn->getCursor(main); + auto cursor = txn->getCursor(main); - MDBOutVal key, val; - if(cursor.get(key, val, MDB_FIRST)) { - cout << "Database is empty" <() << endl; - countDB(env, txn, key.get()); - } while(!cursor.get(key, val, MDB_NEXT)); - - + MDBOutVal key, val; + if (cursor.get(key, val, MDB_FIRST)) { + cout << "Database is empty" << endl; + } + do { + cout << key.get() << endl; + countDB(env, txn, key.get()); + } while (!cursor.get(key, val, MDB_NEXT)); } diff --git a/tests/basic.cc b/tests/basic.cc index 5fae39a..a342812 100644 --- a/tests/basic.cc +++ b/tests/basic.cc @@ -10,326 +10,323 @@ using namespace std; using namespace LMDBSafe; -TEST_CASE("Most basic tests", "[mostbasic]") { - unlink("./tests"); - - MDBEnv env("./tests", MDB_NOSUBDIR, 0600); - REQUIRE(1); - - MDBDbi main = env.openDB("", MDB_CREATE); - - auto txn = env.getRWTransaction(); - MDBOutVal out; - - REQUIRE(txn->get(main, "lmdb", out) == MDB_NOTFOUND); - - txn->put(main, "lmdb", "hot"); - - REQUIRE(txn->get(main, "lmdb", out) == 0); - REQUIRE(out.get() == "hot"); - txn->abort(); - - auto rotxn = env.getROTransaction(); - REQUIRE(rotxn->get(main, "lmdb", out) == MDB_NOTFOUND); -} - -TEST_CASE("Range tests", "[range]") { - unlink("./tests"); - - MDBEnv env("./tests", MDB_NOSUBDIR, 0600); - REQUIRE(1); - - MDBDbi main = env.openDB("", MDB_CREATE); - - auto txn = env.getRWTransaction(); - MDBOutVal out; - - REQUIRE(txn->get(main, "lmdb", out) == MDB_NOTFOUND); - - txn->put(main, "bert", "hubert"); - txn->put(main, "bertt", "1975"); - txn->put(main, "berthubert", "lmdb"); - txn->put(main, "bert1", "one"); - txn->put(main, "beru", "not"); - - { - auto cursor = txn->getCursor(main); - MDBInVal bert("bert"); - MDBOutVal key, val; - REQUIRE(cursor.lower_bound(bert, key, val) == 0); - REQUIRE(key.get() == "bert"); - REQUIRE(val.get() == "hubert"); - - REQUIRE(cursor.next(key, val) == 0); - REQUIRE(key.get() == "bert1"); - REQUIRE(val.get() == "one"); - - REQUIRE(cursor.next(key, val) == 0); - REQUIRE(key.get() == "berthubert"); - REQUIRE(val.get() == "lmdb"); - - REQUIRE(cursor.lower_bound("kees", key, val) == MDB_NOTFOUND); - - txn->commit(); - } - - auto rotxn = env.getROTransaction(); - { - auto cursor = rotxn->getCursor(main); - MDBInVal bert("bert"); - MDBOutVal key, val; - REQUIRE(cursor.lower_bound(bert, key, val) == 0); - REQUIRE(key.get() == "bert"); - REQUIRE(val.get() == "hubert"); - - REQUIRE(cursor.next(key, val) == 0); - REQUIRE(key.get() == "bert1"); - REQUIRE(val.get() == "one"); - - REQUIRE(cursor.next(key, val) == 0); - REQUIRE(key.get() == "berthubert"); - REQUIRE(val.get() == "lmdb"); - - REQUIRE(cursor.lower_bound("kees", key, val) == MDB_NOTFOUND); - } - -} - -TEST_CASE("moving transactions") +TEST_CASE("Most basic tests", "[mostbasic]") { - unlink("./tests"); + unlink("./tests"); - MDBEnv env("./tests", MDB_NOSUBDIR, 0600); - REQUIRE(1); + MDBEnv env("./tests", MDB_NOSUBDIR, 0600); + REQUIRE(1); - MDBDbi main = env.openDB("", MDB_CREATE); + MDBDbi main = env.openDB("", MDB_CREATE); - auto txn = env.getRWTransaction(); - MDBOutVal out; - - REQUIRE(txn->get(main, "lmdb", out) == MDB_NOTFOUND); - - txn->put(main, "bert", "hubert"); - txn->put(main, "bertt", "1975"); - txn->put(main, "berthubert", "lmdb"); - txn->put(main, "bert1", "one"); - txn->put(main, "beru", "not"); - - auto cursor = txn->getCursor(main); - auto txn2 = std::move(txn); - { - auto cursor2 = std::move(cursor); - } -} - -TEST_CASE("transaction inheritance and moving") -{ - unlink("./tests"); - - MDBEnv env("./tests", MDB_NOSUBDIR, 0600); - MDBDbi main = env.openDB("", MDB_CREATE); - - MDBRWCursor cursor; - { - MDBRWTransaction txn = env.getRWTransaction(); + auto txn = env.getRWTransaction(); + MDBOutVal out; + + REQUIRE(txn->get(main, "lmdb", out) == MDB_NOTFOUND); + + txn->put(main, "lmdb", "hot"); + + REQUIRE(txn->get(main, "lmdb", out) == 0); + REQUIRE(out.get() == "hot"); + txn->abort(); + + auto rotxn = env.getROTransaction(); + REQUIRE(rotxn->get(main, "lmdb", out) == MDB_NOTFOUND); +} + +TEST_CASE("Range tests", "[range]") +{ + unlink("./tests"); + + MDBEnv env("./tests", MDB_NOSUBDIR, 0600); + REQUIRE(1); + + MDBDbi main = env.openDB("", MDB_CREATE); + + auto txn = env.getRWTransaction(); MDBOutVal out; REQUIRE(txn->get(main, "lmdb", out) == MDB_NOTFOUND); - // lets just keep this cursor to ensure that it invalidates - cursor = txn->getRWCursor(main); txn->put(main, "bert", "hubert"); txn->put(main, "bertt", "1975"); txn->put(main, "berthubert", "lmdb"); txn->put(main, "bert1", "one"); txn->put(main, "beru", "not"); - MDBROTransaction ro_txn(std::move(txn)); - // despite being moved to an ro_txn (which normally commits instead of - // aborting by default) - } + { + auto cursor = txn->getCursor(main); + MDBInVal bert("bert"); + MDBOutVal key, val; + REQUIRE(cursor.lower_bound(bert, key, val) == 0); + REQUIRE(key.get() == "bert"); + REQUIRE(val.get() == "hubert"); - CHECK(!const_cast(cursor)); + REQUIRE(cursor.next(key, val) == 0); + REQUIRE(key.get() == "bert1"); + REQUIRE(val.get() == "one"); + + REQUIRE(cursor.next(key, val) == 0); + REQUIRE(key.get() == "berthubert"); + REQUIRE(val.get() == "lmdb"); + + REQUIRE(cursor.lower_bound("kees", key, val) == MDB_NOTFOUND); + + txn->commit(); + } + + auto rotxn = env.getROTransaction(); + { + auto cursor = rotxn->getCursor(main); + MDBInVal bert("bert"); + MDBOutVal key, val; + REQUIRE(cursor.lower_bound(bert, key, val) == 0); + REQUIRE(key.get() == "bert"); + REQUIRE(val.get() == "hubert"); + + REQUIRE(cursor.next(key, val) == 0); + REQUIRE(key.get() == "bert1"); + REQUIRE(val.get() == "one"); + + REQUIRE(cursor.next(key, val) == 0); + REQUIRE(key.get() == "berthubert"); + REQUIRE(val.get() == "lmdb"); + + REQUIRE(cursor.lower_bound("kees", key, val) == MDB_NOTFOUND); + } +} + +TEST_CASE("moving transactions") +{ + unlink("./tests"); + + MDBEnv env("./tests", MDB_NOSUBDIR, 0600); + REQUIRE(1); + + MDBDbi main = env.openDB("", MDB_CREATE); + + auto txn = env.getRWTransaction(); + MDBOutVal out; + + REQUIRE(txn->get(main, "lmdb", out) == MDB_NOTFOUND); + + txn->put(main, "bert", "hubert"); + txn->put(main, "bertt", "1975"); + txn->put(main, "berthubert", "lmdb"); + txn->put(main, "bert1", "one"); + txn->put(main, "beru", "not"); + + auto cursor = txn->getCursor(main); + auto txn2 = std::move(txn); + { + auto cursor2 = std::move(cursor); + } +} + +TEST_CASE("transaction inheritance and moving") +{ + unlink("./tests"); + + MDBEnv env("./tests", MDB_NOSUBDIR, 0600); + MDBDbi main = env.openDB("", MDB_CREATE); + + MDBRWCursor cursor; + { + MDBRWTransaction txn = env.getRWTransaction(); + MDBOutVal out; + + REQUIRE(txn->get(main, "lmdb", out) == MDB_NOTFOUND); + + // lets just keep this cursor to ensure that it invalidates + cursor = txn->getRWCursor(main); + txn->put(main, "bert", "hubert"); + txn->put(main, "bertt", "1975"); + txn->put(main, "berthubert", "lmdb"); + txn->put(main, "bert1", "one"); + txn->put(main, "beru", "not"); + + MDBROTransaction ro_txn(std::move(txn)); + // despite being moved to an ro_txn (which normally commits instead of + // aborting by default) + } + + CHECK(!const_cast(cursor)); } TEST_CASE("nested RW transactions", "[transactions]") { - unlink("./tests"); + unlink("./tests"); - MDBEnv env("./tests", MDB_NOSUBDIR, 0600); - REQUIRE(1); + MDBEnv env("./tests", MDB_NOSUBDIR, 0600); + REQUIRE(1); - MDBDbi main = env.openDB("", MDB_CREATE); + MDBDbi main = env.openDB("", MDB_CREATE); - /* bootstrap some data */ - { - auto txn = env.getRWTransaction(); - txn->put(main, "bert", "hubert"); - txn->put(main, "bertt", "1975"); - txn->put(main, "berthubert", "lmdb"); - txn->put(main, "bert1", "one"); - txn->put(main, "beru", "not"); - txn->commit(); - } + /* bootstrap some data */ + { + auto txn = env.getRWTransaction(); + txn->put(main, "bert", "hubert"); + txn->put(main, "bertt", "1975"); + txn->put(main, "berthubert", "lmdb"); + txn->put(main, "bert1", "one"); + txn->put(main, "beru", "not"); + txn->commit(); + } - auto main_txn = env.getRWTransaction(); - main_txn->del(main, "bertt", "1975"); + auto main_txn = env.getRWTransaction(); + main_txn->del(main, "bertt", "1975"); - MDBOutVal dummy{}; - CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); + MDBOutVal dummy{}; + CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); - { - auto sub_txn = main_txn->getRWTransaction(); - CHECK(sub_txn->get(main, "berthubert", dummy) == 0); - sub_txn->del(main, "berthubert", "lmdb"); - CHECK(sub_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); - } + { + auto sub_txn = main_txn->getRWTransaction(); + CHECK(sub_txn->get(main, "berthubert", dummy) == 0); + sub_txn->del(main, "berthubert", "lmdb"); + CHECK(sub_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); + } - /* check that subtransaction got rolled back */ - CHECK(main_txn->get(main, "berthubert", dummy) == 0); - /* and that the main changes are still there */ - CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); + /* check that subtransaction got rolled back */ + CHECK(main_txn->get(main, "berthubert", dummy) == 0); + /* and that the main changes are still there */ + CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); - { - auto sub_txn = main_txn->getRWTransaction(); - CHECK(sub_txn->get(main, "berthubert", dummy) == 0); - sub_txn->del(main, "berthubert", "lmdb"); - CHECK(sub_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); - /* this time for real! */ - sub_txn->commit(); - } + { + auto sub_txn = main_txn->getRWTransaction(); + CHECK(sub_txn->get(main, "berthubert", dummy) == 0); + sub_txn->del(main, "berthubert", "lmdb"); + CHECK(sub_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); + /* this time for real! */ + sub_txn->commit(); + } - CHECK(main_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); - CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); + CHECK(main_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); + CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); } - TEST_CASE("nesting RW -> RO", "[transactions]") { - unlink("./tests"); + unlink("./tests"); - MDBEnv env("./tests", MDB_NOSUBDIR, 0600); - REQUIRE(1); + MDBEnv env("./tests", MDB_NOSUBDIR, 0600); + REQUIRE(1); - MDBDbi main = env.openDB("", MDB_CREATE); + MDBDbi main = env.openDB("", MDB_CREATE); - /* bootstrap some data */ - { - auto txn = env.getRWTransaction(); - txn->put(main, "bert", "hubert"); - txn->put(main, "bertt", "1975"); - txn->put(main, "berthubert", "lmdb"); - txn->put(main, "bert1", "one"); - txn->put(main, "beru", "not"); - txn->commit(); - } - - auto main_txn = env.getRWTransaction(); - main_txn->del(main, "bertt", "1975"); - - MDBOutVal dummy{}; - CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); - - { - MDBROTransaction sub_txn = main_txn->getROTransaction(); - CHECK(sub_txn->get(main, "berthubert", dummy) == 0); - } - - /* check that subtransaction got rolled back */ - CHECK(main_txn->get(main, "berthubert", dummy) == 0); - /* and that the main changes are still there */ - CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); - - { - auto sub_txn = main_txn->getRWTransaction(); - CHECK(sub_txn->get(main, "berthubert", dummy) == 0); - sub_txn->del(main, "berthubert", "lmdb"); - CHECK(sub_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); + /* bootstrap some data */ { - MDBROTransaction sub_sub_txn = sub_txn->getROTransaction(); - CHECK(sub_sub_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); + auto txn = env.getRWTransaction(); + txn->put(main, "bert", "hubert"); + txn->put(main, "bertt", "1975"); + txn->put(main, "berthubert", "lmdb"); + txn->put(main, "bert1", "one"); + txn->put(main, "beru", "not"); + txn->commit(); } - /* this time for real! */ - sub_txn->commit(); - } - CHECK(main_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); - CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); + auto main_txn = env.getRWTransaction(); + main_txn->del(main, "bertt", "1975"); + + MDBOutVal dummy{}; + CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); + + { + MDBROTransaction sub_txn = main_txn->getROTransaction(); + CHECK(sub_txn->get(main, "berthubert", dummy) == 0); + } + + /* check that subtransaction got rolled back */ + CHECK(main_txn->get(main, "berthubert", dummy) == 0); + /* and that the main changes are still there */ + CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); + + { + auto sub_txn = main_txn->getRWTransaction(); + CHECK(sub_txn->get(main, "berthubert", dummy) == 0); + sub_txn->del(main, "berthubert", "lmdb"); + CHECK(sub_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); + { + MDBROTransaction sub_sub_txn = sub_txn->getROTransaction(); + CHECK(sub_sub_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); + } + /* this time for real! */ + sub_txn->commit(); + } + + CHECK(main_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); + CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); } TEST_CASE("try to nest twice", "[transactions]") { - unlink("./tests"); + unlink("./tests"); - MDBEnv env("./tests", MDB_NOSUBDIR, 0600); - REQUIRE(1); + MDBEnv env("./tests", MDB_NOSUBDIR, 0600); + REQUIRE(1); - MDBDbi main = env.openDB("", MDB_CREATE); + MDBDbi main = env.openDB("", MDB_CREATE); - /* bootstrap some data */ - { - auto txn = env.getRWTransaction(); - txn->put(main, "bert", "hubert"); - txn->put(main, "bertt", "1975"); - txn->put(main, "berthubert", "lmdb"); - txn->put(main, "bert1", "one"); - txn->put(main, "beru", "not"); - txn->commit(); - } + /* bootstrap some data */ + { + auto txn = env.getRWTransaction(); + txn->put(main, "bert", "hubert"); + txn->put(main, "bertt", "1975"); + txn->put(main, "berthubert", "lmdb"); + txn->put(main, "bert1", "one"); + txn->put(main, "beru", "not"); + txn->commit(); + } - auto main_txn = env.getRWTransaction(); - main_txn->del(main, "bertt", "1975"); + auto main_txn = env.getRWTransaction(); + main_txn->del(main, "bertt", "1975"); - MDBOutVal dummy{}; - CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); + MDBOutVal dummy{}; + CHECK(main_txn->get(main, "bertt", dummy) == MDB_NOTFOUND); - { - auto sub_txn = main_txn->getRWTransaction(); - CHECK(sub_txn->get(main, "berthubert", dummy) == 0); - sub_txn->del(main, "berthubert", "lmdb"); - CHECK(sub_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); + { + auto sub_txn = main_txn->getRWTransaction(); + CHECK(sub_txn->get(main, "berthubert", dummy) == 0); + sub_txn->del(main, "berthubert", "lmdb"); + CHECK(sub_txn->get(main, "berthubert", dummy) == MDB_NOTFOUND); - CHECK_THROWS_AS( - main_txn->getRWTransaction(), - std::runtime_error - ); - } + CHECK_THROWS_AS(main_txn->getRWTransaction(), std::runtime_error); + } } TEST_CASE("transaction counter correctness for RW->RW nesting") { - unlink("./tests"); + unlink("./tests"); - MDBEnv env("./tests", MDB_NOSUBDIR, 0600); - REQUIRE(1); + MDBEnv env("./tests", MDB_NOSUBDIR, 0600); + REQUIRE(1); - MDBDbi main = env.openDB("", MDB_CREATE); - CPP_UTILITIES_UNUSED(main) + MDBDbi main = env.openDB("", MDB_CREATE); + CPP_UTILITIES_UNUSED(main) - { - auto txn = env.getRWTransaction(); - auto sub_txn = txn->getRWTransaction(); - } + { + auto txn = env.getRWTransaction(); + auto sub_txn = txn->getRWTransaction(); + } - CHECK_NOTHROW(env.getRWTransaction()); - CHECK_NOTHROW(env.getROTransaction()); + CHECK_NOTHROW(env.getRWTransaction()); + CHECK_NOTHROW(env.getROTransaction()); } TEST_CASE("transaction counter correctness for RW->RO nesting") { - unlink("./tests"); + unlink("./tests"); - MDBEnv env("./tests", MDB_NOSUBDIR, 0600); - REQUIRE(1); + MDBEnv env("./tests", MDB_NOSUBDIR, 0600); + REQUIRE(1); - MDBDbi main = env.openDB("", MDB_CREATE); - CPP_UTILITIES_UNUSED(main) + MDBDbi main = env.openDB("", MDB_CREATE); + CPP_UTILITIES_UNUSED(main) - { - auto txn = env.getRWTransaction(); - auto sub_txn = txn->getROTransaction(); - } + { + auto txn = env.getRWTransaction(); + auto sub_txn = txn->getROTransaction(); + } - CHECK_NOTHROW(env.getRWTransaction()); - CHECK_NOTHROW(env.getROTransaction()); + CHECK_NOTHROW(env.getRWTransaction()); + CHECK_NOTHROW(env.getROTransaction()); } diff --git a/tests/typed.cc b/tests/typed.cc index dbd8349..52201a9 100644 --- a/tests/typed.cc +++ b/tests/typed.cc @@ -13,60 +13,57 @@ using namespace std; using namespace LMDBSafe; -struct Member -{ - std::string firstName; - std::string lastName; - time_t enrolled; +struct Member { + std::string firstName; + std::string lastName; + time_t enrolled; }; -template -void serialize(Archive & ar, Member& g, const unsigned int version) +template void serialize(Archive &ar, Member &g, const unsigned int version) { - CPP_UTILITIES_UNUSED(version) - ar & g.firstName & g.lastName & g.enrolled; + CPP_UTILITIES_UNUSED(version) + ar &g.firstName &g.lastName &g.enrolled; } -TEST_CASE("Basic typed tests", "[basictyped]") { - unlink("./tests-typed"); - typedef TypedDBI, - index_on, - index_on - > tmembers_t; +TEST_CASE("Basic typed tests", "[basictyped]") +{ + unlink("./tests-typed"); + typedef TypedDBI, index_on, + index_on> + tmembers_t; - auto tmembers = tmembers_t(getMDBEnv("./tests-typed", MDB_CREATE | MDB_NOSUBDIR, 0600), "members"); - - REQUIRE(1); + auto tmembers = tmembers_t(getMDBEnv("./tests-typed", MDB_CREATE | MDB_NOSUBDIR, 0600), "members"); - auto txn = tmembers.getRWTransaction(); - Member m{"bert", "hubert"}; - txn.put(m); - m.firstName="bertus"; - m.lastName = "testperson"; - m.enrolled = time(0); - txn.put(m); + REQUIRE(1); - m.firstName = "other"; - txn.put(m); - - Member out; - REQUIRE(txn.get(1,out)); - REQUIRE(out.firstName == "bert"); - REQUIRE(txn.get(2,out)); - REQUIRE(out.lastName == "testperson"); + auto txn = tmembers.getRWTransaction(); + Member m{ "bert", "hubert" }; + txn.put(m); + m.firstName = "bertus"; + m.lastName = "testperson"; + m.enrolled = time(0); + txn.put(m); - REQUIRE(!txn.get(4,out)); + m.firstName = "other"; + txn.put(m); - auto range = txn.prefix_range<0>("bert"); - vector names; - for(auto& iter = range.first; iter != range.second; ++iter) { - names.push_back(iter->firstName); - } - REQUIRE(names == vector{"bert", "bertus"}); + Member out; + REQUIRE(txn.get(1, out)); + REQUIRE(out.firstName == "bert"); + REQUIRE(txn.get(2, out)); + REQUIRE(out.lastName == "testperson"); - auto range2 = txn.prefix_range<0>("nosuchperson"); - REQUIRE(!(range2.first == range2.second)); - - txn.abort(); + REQUIRE(!txn.get(4, out)); + + auto range = txn.prefix_range<0>("bert"); + vector names; + for (auto &iter = range.first; iter != range.second; ++iter) { + names.push_back(iter->firstName); + } + REQUIRE(names == vector{ "bert", "bertus" }); + + auto range2 = txn.prefix_range<0>("nosuchperson"); + REQUIRE(!(range2.first == range2.second)); + + txn.abort(); }