diff options
Diffstat (limited to 'store/database.cpp')
-rw-r--r-- | store/database.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/store/database.cpp b/store/database.cpp index 7e2019e..2d93266 100644 --- a/store/database.cpp +++ b/store/database.cpp | |||
@@ -101,3 +101,77 @@ void Database::read(const std::string &sKey, const std::function<void(const std: | |||
101 | mdb_txn_abort(txn); | 101 | mdb_txn_abort(txn); |
102 | } | 102 | } |
103 | 103 | ||
104 | |||
105 | |||
106 | ReadTransaction::ReadTransaction(const QString &path) | ||
107 | { | ||
108 | int rc; | ||
109 | |||
110 | //create file | ||
111 | rc = mdb_env_create(&env); | ||
112 | //FIXME MDB_NOTLS required to so we can have multiple read-only transactions per resource? | ||
113 | rc = mdb_env_open(env, path.toStdString().data(), 0, 0664); | ||
114 | const int dbSize = 10485760*100; //10MB * 100 | ||
115 | mdb_env_set_mapsize(env, dbSize); | ||
116 | |||
117 | if (rc) { | ||
118 | std::cerr << "mdb_env_open: " << rc << mdb_strerror(rc) << std::endl; | ||
119 | } | ||
120 | } | ||
121 | |||
122 | ReadTransaction::~ReadTransaction() | ||
123 | { | ||
124 | mdb_txn_abort(txn); | ||
125 | |||
126 | mdb_dbi_close(env, dbi); | ||
127 | mdb_env_close(env); | ||
128 | } | ||
129 | |||
130 | void ReadTransaction::read(const std::string &sKey, const std::function<void(void *data, int size)> &resultHandler) | ||
131 | { | ||
132 | int rc; | ||
133 | MDB_val key; | ||
134 | MDB_val data; | ||
135 | MDB_cursor *cursor; | ||
136 | |||
137 | key.mv_size = sKey.size(); | ||
138 | key.mv_data = (void*)sKey.data(); | ||
139 | |||
140 | { | ||
141 | //A write transaction is at least required the first time | ||
142 | rc = mdb_txn_begin(env, nullptr, 0, &txn); | ||
143 | //Open the database | ||
144 | //With this we could open multiple named databases if we wanted to | ||
145 | rc = mdb_dbi_open(txn, nullptr, 0, &dbi); | ||
146 | mdb_txn_abort(txn); | ||
147 | } | ||
148 | |||
149 | rc = mdb_txn_begin(env, nullptr, MDB_RDONLY, &txn); | ||
150 | rc = mdb_cursor_open(txn, dbi, &cursor); | ||
151 | if (rc) { | ||
152 | std::cerr << "mdb_cursor_open: " << rc << mdb_strerror(rc) << std::endl; | ||
153 | } | ||
154 | if (sKey.empty()) { | ||
155 | std::cout << "Iterating over all values of store!" << std::endl; | ||
156 | rc = mdb_cursor_get(cursor, &key, &data, MDB_FIRST); | ||
157 | while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { | ||
158 | resultHandler(data.mv_data, data.mv_size); | ||
159 | } | ||
160 | //We never find the last value | ||
161 | if (rc == MDB_NOTFOUND) { | ||
162 | rc = 0; | ||
163 | } | ||
164 | } else { | ||
165 | if ((rc = mdb_cursor_get(cursor, &key, &data, MDB_SET)) == 0) { | ||
166 | resultHandler(data.mv_data, data.mv_size); | ||
167 | } else { | ||
168 | std::cout << "couldn't find value " << sKey << std::endl; | ||
169 | } | ||
170 | } | ||
171 | if (rc) { | ||
172 | std::cerr << "mdb_cursor_get: " << rc << mdb_strerror(rc) << std::endl; | ||
173 | } | ||
174 | mdb_cursor_close(cursor); | ||
175 | //We keep the transaction open since we want to keep the returned values alive | ||
176 | } | ||
177 | |||