summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/queryrunner.cpp16
-rw-r--r--common/storage.h1
-rw-r--r--common/storage_lmdb.cpp44
3 files changed, 57 insertions, 4 deletions
diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp
index ea17176..fd966a9 100644
--- a/common/queryrunner.cpp
+++ b/common/queryrunner.cpp
@@ -408,9 +408,19 @@ QPair<qint64, qint64> QueryWorker<DomainType>::load(const Sink::Query &query, co
408 QTime time; 408 QTime time;
409 time.start(); 409 time.start();
410 410
411 Sink::Storage storage(Sink::storageLocation(), mResourceInstanceIdentifier); 411 Sink::Storage::Transaction transaction;
412 storage.setDefaultErrorHandler([](const Sink::Storage::Error &error) { Warning() << "Error during query: " << error.store << error.message; }); 412 {
413 auto transaction = storage.createTransaction(Sink::Storage::ReadOnly); 413 Sink::Storage storage(Sink::storageLocation(), mResourceInstanceIdentifier);
414 storage.setDefaultErrorHandler([](const Sink::Storage::Error &error) { Warning() << "Error during query: " << error.store << error.message; });
415 transaction = storage.createTransaction(Sink::Storage::ReadOnly);
416 }
417
418 //FIXME this is a temporary measure to recover from a failure to open the named databases correctly.
419 //Once the actual problem is fixed it will be enough to simply crash if we open the wrong database (which we check in openDatabase already).
420 while (!transaction.validateNamedDatabases()) {
421 Sink::Storage storage(Sink::storageLocation(), mResourceInstanceIdentifier);
422 transaction = storage.createTransaction(Sink::Storage::ReadOnly);
423 }
414 auto db = Storage::mainDatabase(transaction, mBufferType); 424 auto db = Storage::mainDatabase(transaction, mBufferType);
415 425
416 QSet<QByteArray> remainingFilters; 426 QSet<QByteArray> remainingFilters;
diff --git a/common/storage.h b/common/storage.h
index 87573e2..0527c4f 100644
--- a/common/storage.h
+++ b/common/storage.h
@@ -141,6 +141,7 @@ public:
141 void abort(); 141 void abort();
142 142
143 QList<QByteArray> getDatabaseNames() const; 143 QList<QByteArray> getDatabaseNames() const;
144 bool validateNamedDatabases();
144 145
145 NamedDatabase openDatabase(const QByteArray &name = QByteArray("default"), 146 NamedDatabase openDatabase(const QByteArray &name = QByteArray("default"),
146 const std::function<void(const Storage::Error &error)> &errorHandler = std::function<void(const Storage::Error &error)>(), bool allowDuplicates = false) const; 147 const std::function<void(const Storage::Error &error)> &errorHandler = std::function<void(const Storage::Error &error)>(), bool allowDuplicates = false) const;
diff --git a/common/storage_lmdb.cpp b/common/storage_lmdb.cpp
index cc8b28d..ae4bfba 100644
--- a/common/storage_lmdb.cpp
+++ b/common/storage_lmdb.cpp
@@ -437,6 +437,43 @@ void Storage::Transaction::abort()
437 d->transaction = nullptr; 437 d->transaction = nullptr;
438} 438}
439 439
440//Ensure that we opened the correct database by comparing the expected identifier with the one
441//we write to the database on first open.
442static bool ensureCorrectDb(Storage::NamedDatabase &database, const QByteArray &db, bool readOnly)
443{
444 bool openedTheWrongDatabase = false;
445 auto count = database.scan("__internal_dbname", [db, &openedTheWrongDatabase](const QByteArray &key, const QByteArray &value) ->bool {
446 if (value != db) {
447 Warning() << "Opened the wrong database, got " << value << " instead of " << db;
448 openedTheWrongDatabase = true;
449 }
450 return false;
451 },
452 [](const Storage::Error &error) -> bool{
453 return false;
454 }, false);
455 //This is the first time we open this database in a write transaction, write the db name
456 if (!count) {
457 if (!readOnly) {
458 database.write("__internal_dbname", db);
459 }
460 }
461 return !openedTheWrongDatabase;
462}
463
464bool Storage::Transaction::validateNamedDatabases()
465{
466 auto databases = getDatabaseNames();
467 for (const auto &dbName : databases) {
468 auto db = openDatabase(dbName);
469 if (!db) {
470 Warning() << "Failed to open the database: " << dbName;
471 return false;
472 }
473 }
474 return true;
475}
476
440Storage::NamedDatabase Storage::Transaction::openDatabase(const QByteArray &db, const std::function<void(const Storage::Error &error)> &errorHandler, bool allowDuplicates) const 477Storage::NamedDatabase Storage::Transaction::openDatabase(const QByteArray &db, const std::function<void(const Storage::Error &error)> &errorHandler, bool allowDuplicates) const
441{ 478{
442 if (!d) { 479 if (!d) {
@@ -450,7 +487,12 @@ Storage::NamedDatabase Storage::Transaction::openDatabase(const QByteArray &db,
450 delete p; 487 delete p;
451 return Storage::NamedDatabase(); 488 return Storage::NamedDatabase();
452 } 489 }
453 return Storage::NamedDatabase(p); 490 auto database = Storage::NamedDatabase(p);
491 if (!ensureCorrectDb(database, db, d->requestedRead)) {
492 Warning() << "Failed to open the database";
493 return Storage::NamedDatabase();
494 }
495 return database;
454} 496}
455 497
456QList<QByteArray> Storage::Transaction::getDatabaseNames() const 498QList<QByteArray> Storage::Transaction::getDatabaseNames() const