diff options
-rw-r--r-- | common/pipeline.cpp | 2 | ||||
-rw-r--r-- | common/storage.h | 1 | ||||
-rw-r--r-- | common/storage/entitystore.cpp | 18 | ||||
-rw-r--r-- | common/storage/entitystore.h | 2 | ||||
-rw-r--r-- | common/storage_lmdb.cpp | 13 | ||||
-rw-r--r-- | tests/dummyresourcetest.cpp | 2 |
6 files changed, 30 insertions, 8 deletions
diff --git a/common/pipeline.cpp b/common/pipeline.cpp index ee9d3af..4afe9f3 100644 --- a/common/pipeline.cpp +++ b/common/pipeline.cpp | |||
@@ -63,7 +63,7 @@ public: | |||
63 | Pipeline::Pipeline(const ResourceContext &context, const Sink::Log::Context &ctx) : QObject(nullptr), d(new Private(context, ctx)) | 63 | Pipeline::Pipeline(const ResourceContext &context, const Sink::Log::Context &ctx) : QObject(nullptr), d(new Private(context, ctx)) |
64 | { | 64 | { |
65 | //Create main store immediately on first start | 65 | //Create main store immediately on first start |
66 | d->entityStore.createIfMissing(); | 66 | d->entityStore.initialize(); |
67 | } | 67 | } |
68 | 68 | ||
69 | Pipeline::~Pipeline() | 69 | Pipeline::~Pipeline() |
diff --git a/common/storage.h b/common/storage.h index 5a4fb45..2451040 100644 --- a/common/storage.h +++ b/common/storage.h | |||
@@ -222,6 +222,7 @@ public: | |||
222 | static void getUids(const QByteArray &type, const Transaction &, const std::function<void(const QByteArray &uid)> &); | 222 | static void getUids(const QByteArray &type, const Transaction &, const std::function<void(const QByteArray &uid)> &); |
223 | 223 | ||
224 | bool exists() const; | 224 | bool exists() const; |
225 | static bool exists(const QString &storageRoot, const QString &name); | ||
225 | 226 | ||
226 | static bool isInternalKey(const char *key); | 227 | static bool isInternalKey(const char *key); |
227 | static bool isInternalKey(void *key, int keySize); | 228 | static bool isInternalKey(void *key, int keySize); |
diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp index 6021344..d5a7c5f 100644 --- a/common/storage/entitystore.cpp +++ b/common/storage/entitystore.cpp | |||
@@ -158,13 +158,23 @@ EntityStore::EntityStore(const ResourceContext &context, const Log::Context &ctx | |||
158 | 158 | ||
159 | } | 159 | } |
160 | 160 | ||
161 | void EntityStore::createIfMissing() | 161 | void EntityStore::initialize() |
162 | { | 162 | { |
163 | if (!d->exists()) { | 163 | //This function is only called in the resource code where we want to be able to write to the databse. |
164 | |||
165 | //Check for the existience of the db without creating it or the envrionment. | ||
166 | //This is required to be able to set the database version only in the case where we create a new database. | ||
167 | if (!Storage::DataStore::exists(Sink::storageLocation(), d->resourceContext.instanceId())) { | ||
168 | //The first time we open the environment we always want it to be read/write. Otherwise subsequent tries to open a write transaction will fail. | ||
164 | startTransaction(Sink::Storage::DataStore::ReadWrite); | 169 | startTransaction(Sink::Storage::DataStore::ReadWrite); |
170 | //Create the database with the correct version if it wasn't existing before | ||
171 | SinkLogCtx(d->logCtx) << "Creating resource database."; | ||
165 | Storage::DataStore::setDatabaseVersion(d->transaction, Sink::latestDatabaseVersion()); | 172 | Storage::DataStore::setDatabaseVersion(d->transaction, Sink::latestDatabaseVersion()); |
166 | commitTransaction(); | 173 | } else { |
174 | //The first time we open the environment we always want it to be read/write. Otherwise subsequent tries to open a write transaction will fail. | ||
175 | startTransaction(Sink::Storage::DataStore::ReadWrite); | ||
167 | } | 176 | } |
177 | commitTransaction(); | ||
168 | } | 178 | } |
169 | 179 | ||
170 | void EntityStore::startTransaction(Sink::Storage::DataStore::AccessMode accessMode) | 180 | void EntityStore::startTransaction(Sink::Storage::DataStore::AccessMode accessMode) |
@@ -383,9 +393,11 @@ void EntityStore::cleanupEntityRevisionsUntil(qint64 revision) | |||
383 | 393 | ||
384 | bool EntityStore::cleanupRevisions(qint64 revision) | 394 | bool EntityStore::cleanupRevisions(qint64 revision) |
385 | { | 395 | { |
396 | Q_ASSERT(d->exists()); | ||
386 | bool implicitTransaction = false; | 397 | bool implicitTransaction = false; |
387 | if (!d->transaction) { | 398 | if (!d->transaction) { |
388 | startTransaction(Sink::Storage::DataStore::ReadWrite); | 399 | startTransaction(Sink::Storage::DataStore::ReadWrite); |
400 | Q_ASSERT(d->transaction); | ||
389 | implicitTransaction = true; | 401 | implicitTransaction = true; |
390 | } | 402 | } |
391 | const auto lastCleanRevision = DataStore::cleanedUpRevision(d->transaction); | 403 | const auto lastCleanRevision = DataStore::cleanedUpRevision(d->transaction); |
diff --git a/common/storage/entitystore.h b/common/storage/entitystore.h index 985e7f9..003a2ca 100644 --- a/common/storage/entitystore.h +++ b/common/storage/entitystore.h | |||
@@ -39,7 +39,7 @@ public: | |||
39 | EntityStore(const ResourceContext &resourceContext, const Sink::Log::Context &); | 39 | EntityStore(const ResourceContext &resourceContext, const Sink::Log::Context &); |
40 | ~EntityStore() = default; | 40 | ~EntityStore() = default; |
41 | 41 | ||
42 | void createIfMissing(); | 42 | void initialize(); |
43 | 43 | ||
44 | //Only the pipeline may call the following functions outside of tests | 44 | //Only the pipeline may call the following functions outside of tests |
45 | bool add(const QByteArray &type, ApplicationDomain::ApplicationDomainType newEntity, bool replayToSource); | 45 | bool add(const QByteArray &type, ApplicationDomain::ApplicationDomainType newEntity, bool replayToSource); |
diff --git a/common/storage_lmdb.cpp b/common/storage_lmdb.cpp index 9d0bd6b..49f30b5 100644 --- a/common/storage_lmdb.cpp +++ b/common/storage_lmdb.cpp | |||
@@ -566,6 +566,11 @@ public: | |||
566 | const int rc = mdb_txn_begin(env, NULL, requestedRead ? MDB_RDONLY : 0, &transaction); | 566 | const int rc = mdb_txn_begin(env, NULL, requestedRead ? MDB_RDONLY : 0, &transaction); |
567 | // Trace_area("storage." + name.toLatin1()) << "Started transaction " << mdb_txn_id(transaction) << transaction; | 567 | // Trace_area("storage." + name.toLatin1()) << "Started transaction " << mdb_txn_id(transaction) << transaction; |
568 | if (rc) { | 568 | if (rc) { |
569 | unsigned int flags; | ||
570 | mdb_env_get_flags(env, &flags); | ||
571 | if (flags & MDB_RDONLY && !requestedRead) { | ||
572 | SinkError() << "Tried to open a write transation in a read-only enironment"; | ||
573 | } | ||
569 | defaultErrorHandler(Error(name.toLatin1(), ErrorCodes::GenericError, "Error while opening transaction: " + QByteArray(mdb_strerror(rc)))); | 574 | defaultErrorHandler(Error(name.toLatin1(), ErrorCodes::GenericError, "Error while opening transaction: " + QByteArray(mdb_strerror(rc)))); |
570 | } | 575 | } |
571 | } | 576 | } |
@@ -916,10 +921,14 @@ DataStore::~DataStore() | |||
916 | delete d; | 921 | delete d; |
917 | } | 922 | } |
918 | 923 | ||
924 | bool DataStore::exists(const QString &storageRoot, const QString &name) | ||
925 | { | ||
926 | return QFileInfo(storageRoot + '/' + name + "/data.mdb").exists(); | ||
927 | } | ||
928 | |||
919 | bool DataStore::exists() const | 929 | bool DataStore::exists() const |
920 | { | 930 | { |
921 | QFileInfo info(d->storageRoot + '/' + d->name + "/data.mdb"); | 931 | return (d->env != 0) && DataStore::exists(d->storageRoot, d->name); |
922 | return (d->env != 0) && info.exists(); | ||
923 | } | 932 | } |
924 | 933 | ||
925 | DataStore::Transaction DataStore::createTransaction(AccessMode type, const std::function<void(const DataStore::Error &error)> &errorHandlerArg) | 934 | DataStore::Transaction DataStore::createTransaction(AccessMode type, const std::function<void(const DataStore::Error &error)> &errorHandlerArg) |
diff --git a/tests/dummyresourcetest.cpp b/tests/dummyresourcetest.cpp index 6f307e6..08138b3 100644 --- a/tests/dummyresourcetest.cpp +++ b/tests/dummyresourcetest.cpp | |||
@@ -244,7 +244,7 @@ private slots: | |||
244 | event.setProperty("uid", "testuid"); | 244 | event.setProperty("uid", "testuid"); |
245 | QCOMPARE(event.getProperty("uid").toByteArray(), QByteArray("testuid")); | 245 | QCOMPARE(event.getProperty("uid").toByteArray(), QByteArray("testuid")); |
246 | event.setProperty("summary", "summaryValue"); | 246 | event.setProperty("summary", "summaryValue"); |
247 | Sink::Store::create<Event>(event).exec().waitForFinished(); | 247 | VERIFYEXEC(Sink::Store::create<Event>(event)); |
248 | 248 | ||
249 | // Test create | 249 | // Test create |
250 | Event event2; | 250 | Event event2; |