summaryrefslogtreecommitdiffstats
path: root/common/storage_lmdb.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2015-03-30 23:38:45 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2015-03-31 11:11:08 +0200
commit42f32ea5865c95028c577000e15e8a8631d16e74 (patch)
tree2d9e8a77ccccf088a8807f35f87e4264163d6cdd /common/storage_lmdb.cpp
parent34851314d39307f22df01a4b711e6fd3c5618e23 (diff)
downloadsink-42f32ea5865c95028c577000e15e8a8631d16e74.tar.gz
sink-42f32ea5865c95028c577000e15e8a8631d16e74.zip
Storage: API cleanup/use QByteArray instead of std::string
Diffstat (limited to 'common/storage_lmdb.cpp')
-rw-r--r--common/storage_lmdb.cpp137
1 files changed, 75 insertions, 62 deletions
diff --git a/common/storage_lmdb.cpp b/common/storage_lmdb.cpp
index c97f9ce..4fcb11f 100644
--- a/common/storage_lmdb.cpp
+++ b/common/storage_lmdb.cpp
@@ -36,6 +36,17 @@
36namespace Akonadi2 36namespace Akonadi2
37{ 37{
38 38
39int getErrorCode(int e)
40{
41 switch (e) {
42 case MDB_NOTFOUND:
43 return Storage::ErrorCodes::NotFound;
44 default:
45 break;
46 }
47 return -1;
48}
49
39class Storage::Private 50class Storage::Private
40{ 51{
41public: 52public:
@@ -130,12 +141,14 @@ bool Storage::exists() const
130{ 141{
131 return (d->env != 0); 142 return (d->env != 0);
132} 143}
144
133bool Storage::isInTransaction() const 145bool Storage::isInTransaction() const
134{ 146{
135 return d->transaction; 147 return d->transaction;
136} 148}
137 149
138bool Storage::startTransaction(AccessMode type) 150bool Storage::startTransaction(AccessMode type,
151 const std::function<void(const Storage::Error &error)> &errorHandler)
139{ 152{
140 if (!d->env) { 153 if (!d->env) {
141 return false; 154 return false;
@@ -144,9 +157,12 @@ bool Storage::startTransaction(AccessMode type)
144 bool requestedRead = type == ReadOnly; 157 bool requestedRead = type == ReadOnly;
145 158
146 if (d->mode == ReadOnly && !requestedRead) { 159 if (d->mode == ReadOnly && !requestedRead) {
160 Error error(d->name.toLatin1(), ErrorCodes::GenericError, "Requested read/write transaction in read-only mode.");
161 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
147 return false; 162 return false;
148 } 163 }
149 164
165 //We already have a transaction
150 if (d->transaction && (!d->readTransaction || requestedRead)) { 166 if (d->transaction && (!d->readTransaction || requestedRead)) {
151 return true; 167 return true;
152 } 168 }
@@ -172,11 +188,13 @@ bool Storage::startTransaction(AccessMode type)
172 if (!rc) { 188 if (!rc) {
173 rc = mdb_dbi_open(d->transaction, NULL, d->allowDuplicates ? MDB_DUPSORT : 0, &d->dbi); 189 rc = mdb_dbi_open(d->transaction, NULL, d->allowDuplicates ? MDB_DUPSORT : 0, &d->dbi);
174 if (rc) { 190 if (rc) {
175 qWarning() << "Error while opening transaction: " << mdb_strerror(rc); 191 Error error(d->name.toLatin1(), ErrorCodes::GenericError, "Error while opening transaction: " + QByteArray(mdb_strerror(rc)));
192 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
176 } 193 }
177 } else { 194 } else {
178 if (rc) { 195 if (rc) {
179 qWarning() << "Error while beginning transaction: " << mdb_strerror(rc); 196 Error error(d->name.toLatin1(), ErrorCodes::GenericError, "Error while beginning transaction: " + QByteArray(mdb_strerror(rc)));
197 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
180 } 198 }
181 } 199 }
182 200
@@ -185,7 +203,7 @@ bool Storage::startTransaction(AccessMode type)
185 return !rc; 203 return !rc;
186} 204}
187 205
188bool Storage::commitTransaction() 206bool Storage::commitTransaction(const std::function<void(const Storage::Error &error)> &errorHandler)
189{ 207{
190 if (!d->env) { 208 if (!d->env) {
191 return false; 209 return false;
@@ -200,7 +218,8 @@ bool Storage::commitTransaction()
200 d->transaction = 0; 218 d->transaction = 0;
201 219
202 if (rc) { 220 if (rc) {
203 std::cerr << "mdb_txn_commit: " << rc << " " << mdb_strerror(rc) << std::endl; 221 Error error(d->name.toLatin1(), ErrorCodes::GenericError, "Error during transaction commit: " + QByteArray(mdb_strerror(rc)));
222 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
204 } 223 }
205 224
206 return !rc; 225 return !rc;
@@ -216,25 +235,32 @@ void Storage::abortTransaction()
216 d->transaction = 0; 235 d->transaction = 0;
217} 236}
218 237
219bool Storage::write(const void *keyPtr, size_t keySize, const void *valuePtr, size_t valueSize) 238bool Storage::write(const void *keyPtr, size_t keySize, const void *valuePtr, size_t valueSize,
239 const std::function<void(const Storage::Error &error)> &errorHandler)
220{ 240{
221 if (!d->env) { 241 if (!d->env) {
242 Error error(d->name.toLatin1(), ErrorCodes::NotOpen, "Not open");
243 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
222 return false; 244 return false;
223 } 245 }
224 246
225 if (d->mode == ReadOnly) { 247 if (d->mode == ReadOnly) {
226 std::cerr << "tried to write in read-only mode." << std::endl; 248 Error error(d->name.toLatin1(), ErrorCodes::GenericError, "Tried to write in read-only mode.");
249 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
227 return false; 250 return false;
228 } 251 }
229 252
230 if (!keyPtr || keySize == 0) { 253 if (!keyPtr || keySize == 0) {
231 std::cerr << "tried to write empty key." << std::endl; 254 Error error(d->name.toLatin1(), ErrorCodes::GenericError, "Tried to write empty key.");
255 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
232 return false; 256 return false;
233 } 257 }
234 258
235 const bool implicitTransaction = !d->transaction || d->readTransaction; 259 const bool implicitTransaction = !d->transaction || d->readTransaction;
236 if (implicitTransaction) { 260 if (implicitTransaction) {
237 if (!startTransaction()) { 261 if (!startTransaction()) {
262 Error error(d->name.toLatin1(), ErrorCodes::TransactionError, "Failed to start transaction.");
263 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
238 return false; 264 return false;
239 } 265 }
240 } 266 }
@@ -248,11 +274,14 @@ bool Storage::write(const void *keyPtr, size_t keySize, const void *valuePtr, si
248 rc = mdb_put(d->transaction, d->dbi, &key, &data, 0); 274 rc = mdb_put(d->transaction, d->dbi, &key, &data, 0);
249 275
250 if (rc) { 276 if (rc) {
251 std::cerr << "mdb_put: " << rc << " " << mdb_strerror(rc) << std::endl; 277 Error error(d->name.toLatin1(), ErrorCodes::GenericError, "mdb_put: " + QByteArray(mdb_strerror(rc)));
278 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
252 } 279 }
253 280
254 if (implicitTransaction) { 281 if (implicitTransaction) {
255 if (rc) { 282 if (rc) {
283 Error error(d->name.toLatin1(), ErrorCodes::GenericError, "aborting transaction");
284 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
256 abortTransaction(); 285 abortTransaction();
257 } else { 286 } else {
258 rc = commitTransaction(); 287 rc = commitTransaction();
@@ -262,39 +291,14 @@ bool Storage::write(const void *keyPtr, size_t keySize, const void *valuePtr, si
262 return !rc; 291 return !rc;
263} 292}
264 293
265bool Storage::write(const std::string &sKey, const std::string &sValue) 294int Storage::scan(const QByteArray &k,
266{ 295 const std::function<bool(void *keyPtr, int keySize, void *valuePtr, int valueSize)> &resultHandler,
267 return write(const_cast<char*>(sKey.data()), sKey.size(), const_cast<char*>(sValue.data()), sValue.size()); 296 const std::function<void(const Storage::Error &error)> &errorHandler)
268}
269
270void Storage::read(const std::string &sKey,
271 const std::function<bool(const std::string &value)> &resultHandler,
272 const std::function<void(const Storage::Error &error)> &errorHandler)
273{
274 read(sKey,
275 [&](void *ptr, int size) -> bool {
276 const std::string resultValue(static_cast<char*>(ptr), size);
277 return resultHandler(resultValue);
278 }, errorHandler);
279}
280
281void Storage::read(const std::string &sKey,
282 const std::function<bool(void *ptr, int size)> &resultHandler,
283 const std::function<void(const Storage::Error &error)> &errorHandler)
284{
285 scan(sKey.data(), sKey.size(), [resultHandler](void *keyPtr, int keySize, void *valuePtr, int valueSize) {
286 return resultHandler(valuePtr, valueSize);
287 }, errorHandler);
288}
289
290void Storage::scan(const char *keyData, uint keySize,
291 const std::function<bool(void *keyPtr, int keySize, void *valuePtr, int valueSize)> &resultHandler,
292 const std::function<void(const Storage::Error &error)> &errorHandler)
293{ 297{
294 if (!d->env) { 298 if (!d->env) {
295 Error error(d->name.toStdString(), -1, "Not open"); 299 Error error(d->name.toLatin1(), ErrorCodes::NotOpen, "Not open");
296 errorHandler(error); 300 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
297 return; 301 return 0;
298 } 302 }
299 303
300 int rc; 304 int rc;
@@ -302,29 +306,33 @@ void Storage::scan(const char *keyData, uint keySize,
302 MDB_val data; 306 MDB_val data;
303 MDB_cursor *cursor; 307 MDB_cursor *cursor;
304 308
305 key.mv_data = (void*)keyData; 309 key.mv_data = (void*)k.constData();
306 key.mv_size = keySize; 310 key.mv_size = k.size();
307 311
308 const bool implicitTransaction = !d->transaction; 312 const bool implicitTransaction = !d->transaction;
309 if (implicitTransaction) { 313 if (implicitTransaction) {
310 if (!startTransaction(ReadOnly)) { 314 if (!startTransaction(ReadOnly)) {
311 Error error(d->name.toStdString(), -2, "Could not start transaction"); 315 Error error(d->name.toLatin1(), ErrorCodes::TransactionError, "Could not start transaction");
312 errorHandler(error); 316 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
313 return; 317 return 0;
314 } 318 }
315 } 319 }
316 320
317 rc = mdb_cursor_open(d->transaction, d->dbi, &cursor); 321 rc = mdb_cursor_open(d->transaction, d->dbi, &cursor);
318 if (rc) { 322 if (rc) {
319 Error error(d->name.toStdString(), rc, std::string("Error during mdb_cursor open: ") + mdb_strerror(rc)); 323 Error error(d->name.toLatin1(), getErrorCode(rc), QByteArray("Error during mdb_cursor open: ") + QByteArray(mdb_strerror(rc)));
320 errorHandler(error); 324 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
321 return; 325 return 0;
322 } 326 }
323 327
324 if (!keyData || keySize == 0 || d->allowDuplicates) { 328 int numberOfRetrievedValues = 0;
329
330 if (k.isEmpty() || d->allowDuplicates) {
325 if ((rc = mdb_cursor_get(cursor, &key, &data, d->allowDuplicates ? MDB_SET_RANGE : MDB_FIRST)) == 0) { 331 if ((rc = mdb_cursor_get(cursor, &key, &data, d->allowDuplicates ? MDB_SET_RANGE : MDB_FIRST)) == 0) {
332 numberOfRetrievedValues++;
326 if (resultHandler(key.mv_data, key.mv_size, data.mv_data, data.mv_size)) { 333 if (resultHandler(key.mv_data, key.mv_size, data.mv_data, data.mv_size)) {
327 while ((rc = mdb_cursor_get(cursor, &key, &data, d->allowDuplicates ? MDB_NEXT_DUP : MDB_NEXT)) == 0) { 334 while ((rc = mdb_cursor_get(cursor, &key, &data, d->allowDuplicates ? MDB_NEXT_DUP : MDB_NEXT)) == 0) {
335 numberOfRetrievedValues++;
328 if (!resultHandler(key.mv_data, key.mv_size, data.mv_data, data.mv_size)) { 336 if (!resultHandler(key.mv_data, key.mv_size, data.mv_data, data.mv_size)) {
329 break; 337 break;
330 } 338 }
@@ -338,6 +346,7 @@ void Storage::scan(const char *keyData, uint keySize,
338 } 346 }
339 } else { 347 } else {
340 if ((rc = mdb_cursor_get(cursor, &key, &data, MDB_SET)) == 0) { 348 if ((rc = mdb_cursor_get(cursor, &key, &data, MDB_SET)) == 0) {
349 numberOfRetrievedValues++;
341 resultHandler(key.mv_data, key.mv_size, data.mv_data, data.mv_size); 350 resultHandler(key.mv_data, key.mv_size, data.mv_data, data.mv_size);
342 } 351 }
343 } 352 }
@@ -345,39 +354,42 @@ void Storage::scan(const char *keyData, uint keySize,
345 mdb_cursor_close(cursor); 354 mdb_cursor_close(cursor);
346 355
347 if (rc) { 356 if (rc) {
348 Error error(d->name.toStdString(), rc, std::string("Key: ") + std::string(keyData, keySize) + " : " + mdb_strerror(rc)); 357 Error error(d->name.toLatin1(), getErrorCode(rc), QByteArray("Key: ") + k + " : " + QByteArray(mdb_strerror(rc)));
349 errorHandler(error); 358 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
350 } 359 }
351 360
352 if (implicitTransaction) { 361 if (implicitTransaction) {
353 abortTransaction(); 362 abortTransaction();
354 } 363 }
364 return numberOfRetrievedValues;
355} 365}
356 366
357void Storage::remove(const void *keyData, uint keySize) 367void Storage::remove(const QByteArray &key,
368 const std::function<void(const Storage::Error &error)> &errorHandler)
358{ 369{
359 remove(keyData, keySize, basicErrorHandler()); 370 remove(key.data(), key.size(), errorHandler);
360} 371}
361 372
362void Storage::remove(const void *keyData, uint keySize, const std::function<void(const Storage::Error &error)> &errorHandler) 373void Storage::remove(const void *keyData, uint keySize,
374 const std::function<void(const Storage::Error &error)> &errorHandler)
363{ 375{
364 if (!d->env) { 376 if (!d->env) {
365 Error error(d->name.toStdString(), -1, "Not open"); 377 Error error(d->name.toLatin1(), ErrorCodes::GenericError, "Not open");
366 errorHandler(error); 378 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
367 return; 379 return;
368 } 380 }
369 381
370 if (d->mode == ReadOnly) { 382 if (d->mode == ReadOnly) {
371 Error error(d->name.toStdString(), -3, "Tried to write in read-only mode"); 383 Error error(d->name.toLatin1(), ErrorCodes::ReadOnlyError, "Tried to write in read-only mode");
372 errorHandler(error); 384 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
373 return; 385 return;
374 } 386 }
375 387
376 const bool implicitTransaction = !d->transaction || d->readTransaction; 388 const bool implicitTransaction = !d->transaction || d->readTransaction;
377 if (implicitTransaction) { 389 if (implicitTransaction) {
378 if (!startTransaction()) { 390 if (!startTransaction()) {
379 Error error(d->name.toStdString(), -2, "Could not start transaction"); 391 Error error(d->name.toLatin1(), ErrorCodes::TransactionError, "Could not start transaction");
380 errorHandler(error); 392 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
381 return; 393 return;
382 } 394 }
383 } 395 }
@@ -389,8 +401,8 @@ void Storage::remove(const void *keyData, uint keySize, const std::function<void
389 rc = mdb_del(d->transaction, d->dbi, &key, 0); 401 rc = mdb_del(d->transaction, d->dbi, &key, 0);
390 402
391 if (rc) { 403 if (rc) {
392 Error error(d->name.toStdString(), -1, QString("Error on mdb_del: %1 %2").arg(rc).arg(mdb_strerror(rc)).toStdString()); 404 Error error(d->name.toLatin1(), ErrorCodes::GenericError, QString("Error on mdb_del: %1 %2").arg(rc).arg(mdb_strerror(rc)).toLatin1());
393 errorHandler(error); 405 errorHandler ? errorHandler(error) : defaultErrorHandler()(error);
394 } 406 }
395 407
396 if (implicitTransaction) { 408 if (implicitTransaction) {
@@ -413,6 +425,7 @@ qint64 Storage::diskUsage() const
413void Storage::removeFromDisk() const 425void Storage::removeFromDisk() const
414{ 426{
415 const QString fullPath(d->storageRoot + '/' + d->name); 427 const QString fullPath(d->storageRoot + '/' + d->name);
428 qDebug() << "removing " << fullPath;
416 QMutexLocker locker(&d->sMutex); 429 QMutexLocker locker(&d->sMutex);
417 QDir dir(fullPath); 430 QDir dir(fullPath);
418 if (!dir.removeRecursively()) { 431 if (!dir.removeRecursively()) {