make kv store return its type interface directly
This commit is contained in:
parent
f1c989ad36
commit
8b4302a7db
47
kv_store.hpp
47
kv_store.hpp
@ -5,20 +5,29 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
class KeyValueStore {
|
class KeyValueStore {
|
||||||
public:
|
public:
|
||||||
void set(const string& key, const string& value) {
|
using Value = std::variant<int, double, string, bool>;
|
||||||
|
|
||||||
|
void set(const string& key, const Value& value) {
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
data_[key] = value;
|
data_[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<string> get(const string& key) {
|
template<typename T>
|
||||||
|
std::optional<T> get(const string& key) {
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
auto it = data_.find(key);
|
auto it = data_.find(key);
|
||||||
return it != data_.end() ? std::optional<string>{it->second} : std::nullopt;
|
if (it == data_.end()) return std::nullopt;
|
||||||
|
if (auto* ptr = std::get_if<T>(&it->second)) {
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool del(const string& key) {
|
bool del(const string& key) {
|
||||||
@ -43,8 +52,17 @@ public:
|
|||||||
string line;
|
string line;
|
||||||
while (std::getline(file, line)) {
|
while (std::getline(file, line)) {
|
||||||
size_t eq = line.find('=');
|
size_t eq = line.find('=');
|
||||||
if (eq != string::npos) {
|
if (eq == string::npos || eq < 2) continue;
|
||||||
data_[line.substr(0, eq)] = line.substr(eq + 1);
|
|
||||||
|
string key = line.substr(2, eq - 2);
|
||||||
|
string val_str = line.substr(eq + 1);
|
||||||
|
char type = line[0];
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'i': data_[key] = std::stoi(val_str); break;
|
||||||
|
case 'd': data_[key] = std::stod(val_str); break;
|
||||||
|
case 's': data_[key] = val_str; break;
|
||||||
|
case 'b': data_[key] = (val_str == "1"); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,12 +73,27 @@ public:
|
|||||||
if (!file.is_open()) return;
|
if (!file.is_open()) return;
|
||||||
|
|
||||||
for (const auto& [key, value] : data_) {
|
for (const auto& [key, value] : data_) {
|
||||||
file << key << "=" << value << "\n";
|
file << serialize_entry(key, value) << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<string, string> data_;
|
string serialize_entry(const string& key, const Value& value) {
|
||||||
|
return std::visit([&key](const auto& val) -> string {
|
||||||
|
using T = std::decay_t<decltype(val)>;
|
||||||
|
if constexpr (std::is_same_v<T, int>) {
|
||||||
|
return "i:" + key + "=" + std::to_string(val);
|
||||||
|
} else if constexpr (std::is_same_v<T, double>) {
|
||||||
|
return "d:" + key + "=" + std::to_string(val);
|
||||||
|
} else if constexpr (std::is_same_v<T, string>) {
|
||||||
|
return "s:" + key + "=" + val;
|
||||||
|
} else if constexpr (std::is_same_v<T, bool>) {
|
||||||
|
return "b:" + key + "=" + (val ? "1" : "0");
|
||||||
|
}
|
||||||
|
}, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<string, Value> data_;
|
||||||
mutable std::mutex mutex_;
|
mutable std::mutex mutex_;
|
||||||
string filename_ = "store.txt";
|
string filename_ = "store.txt";
|
||||||
};
|
};
|
||||||
|
6
main.cpp
6
main.cpp
@ -61,9 +61,9 @@ int main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.get("/admin/counter", [](const HttpRequest& req, HttpResponse& res) {
|
router.get("/admin/counter", [](const HttpRequest& req, HttpResponse& res) {
|
||||||
auto current = server->store.get("visit_count");
|
auto current = server->store.get<int>("visit_count");
|
||||||
int count = current ? std::stoi(current.value()) : 0;
|
int count = current ? current.value() : 0;
|
||||||
server->store.set("visit_count", std::to_string(count + 1));
|
server->store.set("visit_count", count + 1);
|
||||||
|
|
||||||
res.set_text("Counter: " + std::to_string(count + 1));
|
res.set_text("Counter: " + std::to_string(count + 1));
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user