feat/update_config #10

Merged
tqcq merged 26 commits from feat/update_config into master 2024-10-14 10:15:01 +08:00
5 changed files with 108 additions and 17 deletions
Showing only changes of commit 5a02a4c750 - Show all commits

1
.gitignore vendored
View File

@ -2,3 +2,4 @@ out/
build/
.cache/
compile_commands.json
.gdb_history

View File

@ -302,6 +302,9 @@ function(add_test_group prefix group_name)
# convert to relative path message(STATUS "${prefix} -> ${TEST_FILE}")
file(RELATIVE_PATH TEST_NAME "${prefix}" "${SRC_FILE}")
string(REPLACE "/" "_" TEST_NAME "${TEST_NAME}")
string(REPLACE ".cpp" "" TEST_NAME "${TEST_NAME}")
string(REPLACE ".cc" "" TEST_NAME "${TEST_NAME}")
string(REPLACE ".c" "" TEST_NAME "${TEST_NAME}")
# if group_name is not empty, add suffix _
if (NOT group_name STREQUAL "")
set(TEST_NAME "${group_name}_${TEST_NAME}")

View File

@ -22,33 +22,39 @@ bool JSONConfiguration::load(std::istream &istr) {
}
void JSONConfiguration::SetInt(const Slice &key, int value) {
Configuration::ScopedLock _(*this);
SetValue(key, value);
}
void JSONConfiguration::SetBool(const Slice &key, bool value) {
Configuration::ScopedLock _(*this);
SetValue(key, value);
}
void JSONConfiguration::SetDouble(const Slice &key, double value) {
Configuration::ScopedLock _(*this);
SetValue(key, value);
}
void JSONConfiguration::SetString(const Slice &key, const std::string &value) {
Configuration::ScopedLock _(*this);
SetValue(key, value);
}
void JSONConfiguration::RemoveRaw(const Slice &key) {
Configuration::ScopedLock _(*this);
Json::Value root;
Json::Value *root;
Slice last_part;
if (!FindStart(key, &last_part, &root)) {
return;
}
root.removeMember(last_part.ToString());
root->removeMember(last_part.ToString());
}
std::string JSONConfiguration::Dump() const {
Configuration::ScopedLock _(*this);
return object_.toStyledString();
}
bool JSONConfiguration::GetRaw(const Slice &key, std::string *value) const {
Configuration::ScopedLock _(*this);
auto keys = Split(key, '.');
auto root = object_;
for (std::size_t i = 0; i < keys.size(); ++i) {
@ -57,13 +63,17 @@ bool JSONConfiguration::GetRaw(const Slice &key, std::string *value) const {
TILE_LOG_ERROR("Invalid key: {}", key);
return false;
}
if (!object_.isMember(cur_key)) {
if (!root.isMember(cur_key)) {
return false;
}
root = root[cur_key];
}
*value = root.asString();
if (root.isConvertibleTo(Json::stringValue)) {
*value = root.asString();
} else {
*value = root.toStyledString();
}
return true;
}
@ -83,7 +93,7 @@ Configuration::Keys JSONConfiguration::Enumerate(const Slice &range) const {
TILE_LOG_ERROR("Invalid range: {}", range);
return key_set;
}
if (!object_.isMember(cur_key)) {
if (!root.isMember(cur_key)) {
return key_set;
}
root = root[cur_key];
@ -96,13 +106,13 @@ Configuration::Keys JSONConfiguration::Enumerate(const Slice &range) const {
}
bool JSONConfiguration::FindStart(const Slice &key, Slice *last_part,
Json::Value *parent_obj) {
Json::Value **parent_obj) {
auto keys = Split(key, '.');
if (keys.empty()) {
return false;
}
auto root = object_;
Json::Value *root = &object_;
for (std::size_t i = 0; i < keys.size() - 1; ++i) {
const auto &cur_key = keys[i];
if (cur_key.empty()) {
@ -110,14 +120,14 @@ bool JSONConfiguration::FindStart(const Slice &key, Slice *last_part,
return false;
}
if (!root.isMember(cur_key)) {
root[cur_key] = Json::Value(Json::objectValue);
} else if (!root[cur_key].isObject()) {
if (!root->isMember(cur_key)) {
(*root)[cur_key] = Json::Value(Json::objectValue);
} else if (!(*root)[cur_key].isObject()) {
TILE_LOG_ERROR("only leaf nodes can be set: key: {}, cur_key(idx={}): {}",
key, i, cur_key);
return false;
}
root = root[cur_key];
root = &(*root)[cur_key];
}
*last_part = keys.back();

View File

@ -21,13 +21,15 @@ public:
void SetString(const Slice &key, const std::string &value) override;
void RemoveRaw(const Slice &key) override;
std::string Dump() const;
protected:
bool GetRaw(const Slice &key, std::string *value) const override;
bool SetRaw(const Slice &key, const Slice &value) override;
Keys Enumerate(const Slice &range) const override;
private:
bool FindStart(const Slice &key, Slice *last_prt, Json::Value *parent_obj);
bool FindStart(const Slice &key, Slice *last_prt, Json::Value **parent_obj);
template <typename T> bool SetValue(const Slice &key, T value);
Json::Value object_;
};
@ -35,12 +37,11 @@ private:
template <typename T>
bool JSONConfiguration::SetValue(const Slice &key, T value) {
Slice last_part;
Json::Value root;
Configuration::ScopedLock _(*this);
Json::Value *root;
if (!FindStart(key, &last_part, &root)) {
return false;
}
root[last_part] = Json::Value(value);
(*root)[last_part] = Json::Value(value);
return true;
}
} // namespace tile

View File

@ -0,0 +1,76 @@
#include "tile/base/config/json_configuration.h"
#include "gtest/gtest.h"
namespace tile {
namespace {
const char *kJsonConfig = R"(
{
"key1": "value1",
"key2": 2,
"key3": 3.0,
"key4": true,
"key5": {
"key51": "value51",
"key52": 52
}
}
)";
}
TEST(JSONConfiguration, Load) {
JSONConfiguration config;
std::istringstream istr(kJsonConfig);
ASSERT_TRUE(config.load(istr));
}
TEST(JSONConfiguration, Has) {
JSONConfiguration config;
std::istringstream istr(kJsonConfig);
ASSERT_TRUE(config.load(istr));
ASSERT_TRUE(config.Has("key1"));
ASSERT_TRUE(config.Has("key2"));
ASSERT_TRUE(config.Has("key3"));
ASSERT_TRUE(config.Has("key4"));
ASSERT_TRUE(config.Has("key5"));
ASSERT_TRUE(config.Has("key5.key51"));
ASSERT_TRUE(config.Has("key5.key52"));
}
TEST(JSONConfiguration, SampleSet) {
JSONConfiguration config;
std::istringstream istr(kJsonConfig);
ASSERT_TRUE(config.load(istr));
ASSERT_TRUE(config.GetInt32("key2"));
ASSERT_EQ(*config.GetInt32("key2"), 2);
config.SetInt("key2", 20);
ASSERT_TRUE(config.GetInt32("key2"));
ASSERT_EQ(20, *config.GetInt32("key2")) << config.Dump();
config.SetDouble("key3", 30.0);
ASSERT_TRUE(config.GetDouble("key3"));
ASSERT_NEAR(30.0, *config.GetDouble("key3"), 0.0001) << config.Dump();
config.SetBool("key4", false);
ASSERT_TRUE(config.GetBool("key4"));
ASSERT_FALSE(*config.GetBool("key4")) << config.Dump();
}
TEST(JSONConfiguration, LayeredSet) {
JSONConfiguration config;
std::istringstream istr(kJsonConfig);
ASSERT_TRUE(config.load(istr));
// ASSERT_TRUE(config.GetInt32("key5.key52"));
config.SetInt("key5.key52", 520);
ASSERT_TRUE(config.GetInt32("key5.key52")) << config.Dump();
ASSERT_EQ(520, *config.GetInt32("key5.key52")) << config.Dump();
// override by other type
config.SetBool("key5.key52", false);
ASSERT_TRUE(config.GetBool("key5.key52")) << config.Dump();
ASSERT_FALSE(*config.GetBool("key5.key52")) << config.Dump();
}
} // namespace tile