From 130affe4addb1aff1618d8fb849889b2d4453ef2 Mon Sep 17 00:00:00 2001 From: Aaron Seigo Date: Fri, 5 Dec 2014 12:56:33 +0100 Subject: require users of a Storage class to state up-front if they are read or readwrite --- common/storage.h | 6 +++--- common/storage_kyoto.cpp | 25 ++++++++++++++++++------- common/storage_lmdb.cpp | 17 ++++++++++++----- 3 files changed, 33 insertions(+), 15 deletions(-) (limited to 'common') diff --git a/common/storage.h b/common/storage.h index 0b548fb..846e15b 100644 --- a/common/storage.h +++ b/common/storage.h @@ -5,12 +5,12 @@ class Storage { public: - enum TransactionType { ReadOnly, ReadWrite }; + enum AccessMode { ReadOnly, ReadWrite }; - Storage(const QString &storageRoot, const QString &name); + Storage(const QString &storageRoot, const QString &name, AccessMode mode = ReadOnly); ~Storage(); bool isInTransaction() const; - bool startTransaction(TransactionType type = ReadWrite); + bool startTransaction(AccessMode mode = ReadWrite); bool commitTransaction(); void abortTransaction(); bool write(const char *key, size_t keySize, const char *value, size_t valueSize); diff --git a/common/storage_kyoto.cpp b/common/storage_kyoto.cpp index 40bd3e6..3d7ab8c 100644 --- a/common/storage_kyoto.cpp +++ b/common/storage_kyoto.cpp @@ -15,23 +15,30 @@ class Storage::Private { public: - Private(const QString &storageRoot, const QString &name); + Private(const QString &storageRoot, const QString &name, AccessMode m); ~Private(); kyotocabinet::TreeDB db; + AccessMode mode; bool dbOpen; bool inTransaction; }; -Storage::Private::Private(const QString &storageRoot, const QString &name) - : inTransaction(false) +Storage::Private::Private(const QString &storageRoot, const QString &name, AccessMode m) + : mode(m), + dbOpen(false), + inTransaction(false) { QDir dir; dir.mkdir(storageRoot); //create file - dbOpen = db.open((storageRoot + "/" + name + ".kch").toStdString(), kyotocabinet::BasicDB::OWRITER | kyotocabinet::BasicDB::OCREATE); + uint32_t openMode = kyotocabinet::BasicDB::OCREATE | + (mode == ReadOnly ? kyotocabinet::BasicDB::OREADER + : kyotocabinet::BasicDB::OWRITER); + dbOpen = db.open((storageRoot + "/" + name + ".kch").toStdString(), openMode); if (!dbOpen) { + std::cerr << "Could not open database: " << db.error().codename(db.error().code()) << " " << db.error().message() << std::endl; // TODO: handle error } } @@ -43,8 +50,8 @@ Storage::Private::~Private() } } -Storage::Storage(const QString &storageRoot, const QString &name) - : d(new Private(storageRoot, name)) +Storage::Storage(const QString &storageRoot, const QString &name, AccessMode mode) + : d(new Private(storageRoot, name, mode)) { } @@ -58,12 +65,16 @@ bool Storage::isInTransaction() const return d->inTransaction; } -bool Storage::startTransaction(TransactionType type) +bool Storage::startTransaction(AccessMode type) { if (!d->dbOpen) { return false; } + if (type == ReadWrite && d->mode != ReadWrite) { + return false; + } + if (d->inTransaction) { return true; } diff --git a/common/storage_lmdb.cpp b/common/storage_lmdb.cpp index 8e9b05c..7e23fd3 100644 --- a/common/storage_lmdb.cpp +++ b/common/storage_lmdb.cpp @@ -14,7 +14,7 @@ class Storage::Private { public: - Private(const QString &s, const QString &name); + Private(const QString &s, const QString &name, AccessMode m); ~Private(); QString storageRoot; @@ -23,14 +23,16 @@ public: MDB_dbi dbi; MDB_env *env; MDB_txn *transaction; + AccessMode mode; bool readTransaction; bool firstOpen; }; -Storage::Private::Private(const QString &s, const QString &n) +Storage::Private::Private(const QString &s, const QString &n, AccessMode m) : storageRoot(s), name(n), transaction(0), + mode(m), readTransaction(false), firstOpen(true) { @@ -65,8 +67,8 @@ Storage::Private::~Private() mdb_env_close(env); } -Storage::Storage(const QString &storageRoot, const QString &name) - : d(new Private(storageRoot, name)) +Storage::Storage(const QString &storageRoot, const QString &name, AccessMode mode) + : d(new Private(storageRoot, name, mode)) { } @@ -80,13 +82,18 @@ bool Storage::isInTransaction() const return d->transaction; } -bool Storage::startTransaction(TransactionType type) +bool Storage::startTransaction(AccessMode type) { if (!d->env) { return false; } bool requestedRead = type == ReadOnly; + + if (d->mode == ReadOnly && !requestedRead) { + return false; + } + if (d->transaction && (!d->readTransaction || requestedRead)) { return true; } -- cgit v1.2.3