#include <sstream>
#include <string>
#include <vector>
+#include <atomic>
namespace config {
class KVStore {
public:
+ /**
+ * A guard struct for thread synchronization and transaction management.
+ */
+ class Transaction {
+ public:
+ Transaction(KVStore& store);
+ ~Transaction();
+
+ Transaction(const Transaction&) = delete;
+ Transaction& operator=(const Transaction&) = delete;
+
+ void commit();
+ private:
+ std::unique_lock<std::recursive_mutex> mLock;
+ KVStore& mKVStore;
+ bool mIsOuter;
+ };
/**
* @param path configuration database file path
*/
- KVStore(const std::string& path);
- KVStore(const KVStore& store);
+ explicit KVStore(const std::string& path);
~KVStore();
+ KVStore(const KVStore&) = delete;
+ KVStore& operator=(const KVStore&) = delete;
+
/**
* Clears all the stored data
*/
void clear();
/**
- * @return Number of all stored values
+ * @return Is there any data stored
*/
- unsigned int size();
+ bool isEmpty();
/**
* @param key string regexp of the stored values
*
- * @return Number of values corresponding to the passed key
+ * @return Does this key exist in the database
*/
- unsigned int count(const std::string& key);
+ bool exists(const std::string& key);
/**
* Removes values corresponding to the passed key.
return getInternal(key, static_cast<T*>(nullptr));
}
+ /**
+ * Returns all stored keys.
+ */
+ std::vector<std::string> getKeys();
private:
- typedef std::lock_guard<std::mutex> Lock;
+ typedef std::lock_guard<std::recursive_mutex> Lock;
+
+ std::recursive_mutex mMutex;
+ size_t mTransactionDepth;
+ bool mIsTransactionCommited;
void setInternal(const std::string& key, const std::string& value);
void setInternal(const std::string& key, const std::initializer_list<std::string>& values);
template<typename T>
std::vector<T> getInternal(const std::string& key, std::vector<T>*);
- std::mutex mConnMtx;
-
std::string mPath;
sqlite3::Connection mConn;
std::unique_ptr<sqlite3::Statement> mGetValueStmt;
- std::unique_ptr<sqlite3::Statement> mGetValueCountStmt;
- std::unique_ptr<sqlite3::Statement> mGetSizeStmt;
+ std::unique_ptr<sqlite3::Statement> mGetKeyExistsStmt;
+ std::unique_ptr<sqlite3::Statement> mGetIsEmptyStmt;
std::unique_ptr<sqlite3::Statement> mGetValueListStmt;
std::unique_ptr<sqlite3::Statement> mSetValueStmt;
std::unique_ptr<sqlite3::Statement> mRemoveValuesStmt;
+ std::unique_ptr<sqlite3::Statement> mGetKeysStmt;
void setupDb();
void prepareStatements();
-
- void removeInternal(const std::string& key);
- unsigned int countInternal(const std::string& key);
-
+ void createFunctions();
};
namespace {