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/ build/
.cache/ .cache/
compile_commands.json 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}") # convert to relative path message(STATUS "${prefix} -> ${TEST_FILE}")
file(RELATIVE_PATH TEST_NAME "${prefix}" "${SRC_FILE}") file(RELATIVE_PATH TEST_NAME "${prefix}" "${SRC_FILE}")
string(REPLACE "/" "_" TEST_NAME "${TEST_NAME}") 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 group_name is not empty, add suffix _
if (NOT group_name STREQUAL "") if (NOT group_name STREQUAL "")
set(TEST_NAME "${group_name}_${TEST_NAME}") 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) { void JSONConfiguration::SetInt(const Slice &key, int value) {
Configuration::ScopedLock _(*this);
SetValue(key, value); SetValue(key, value);
} }
void JSONConfiguration::SetBool(const Slice &key, bool value) { void JSONConfiguration::SetBool(const Slice &key, bool value) {
Configuration::ScopedLock _(*this);
SetValue(key, value); SetValue(key, value);
} }
void JSONConfiguration::SetDouble(const Slice &key, double value) { void JSONConfiguration::SetDouble(const Slice &key, double value) {
Configuration::ScopedLock _(*this);
SetValue(key, value); SetValue(key, value);
} }
void JSONConfiguration::SetString(const Slice &key, const std::string &value) { void JSONConfiguration::SetString(const Slice &key, const std::string &value) {
Configuration::ScopedLock _(*this);
SetValue(key, value); SetValue(key, value);
} }
void JSONConfiguration::RemoveRaw(const Slice &key) { void JSONConfiguration::RemoveRaw(const Slice &key) {
Configuration::ScopedLock _(*this); Json::Value *root;
Json::Value root;
Slice last_part; Slice last_part;
if (!FindStart(key, &last_part, &root)) { if (!FindStart(key, &last_part, &root)) {
return; 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 { bool JSONConfiguration::GetRaw(const Slice &key, std::string *value) const {
Configuration::ScopedLock _(*this);
auto keys = Split(key, '.'); auto keys = Split(key, '.');
auto root = object_; auto root = object_;
for (std::size_t i = 0; i < keys.size(); ++i) { 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); TILE_LOG_ERROR("Invalid key: {}", key);
return false; return false;
} }
if (!object_.isMember(cur_key)) { if (!root.isMember(cur_key)) {
return false; return false;
} }
root = root[cur_key]; root = root[cur_key];
} }
*value = root.asString(); if (root.isConvertibleTo(Json::stringValue)) {
*value = root.asString();
} else {
*value = root.toStyledString();
}
return true; return true;
} }
@ -83,7 +93,7 @@ Configuration::Keys JSONConfiguration::Enumerate(const Slice &range) const {
TILE_LOG_ERROR("Invalid range: {}", range); TILE_LOG_ERROR("Invalid range: {}", range);
return key_set; return key_set;
} }
if (!object_.isMember(cur_key)) { if (!root.isMember(cur_key)) {
return key_set; return key_set;
} }
root = root[cur_key]; 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, bool JSONConfiguration::FindStart(const Slice &key, Slice *last_part,
Json::Value *parent_obj) { Json::Value **parent_obj) {
auto keys = Split(key, '.'); auto keys = Split(key, '.');
if (keys.empty()) { if (keys.empty()) {
return false; return false;
} }
auto root = object_; Json::Value *root = &object_;
for (std::size_t i = 0; i < keys.size() - 1; ++i) { for (std::size_t i = 0; i < keys.size() - 1; ++i) {
const auto &cur_key = keys[i]; const auto &cur_key = keys[i];
if (cur_key.empty()) { if (cur_key.empty()) {
@ -110,14 +120,14 @@ bool JSONConfiguration::FindStart(const Slice &key, Slice *last_part,
return false; return false;
} }
if (!root.isMember(cur_key)) { if (!root->isMember(cur_key)) {
root[cur_key] = Json::Value(Json::objectValue); (*root)[cur_key] = Json::Value(Json::objectValue);
} else if (!root[cur_key].isObject()) { } else if (!(*root)[cur_key].isObject()) {
TILE_LOG_ERROR("only leaf nodes can be set: key: {}, cur_key(idx={}): {}", TILE_LOG_ERROR("only leaf nodes can be set: key: {}, cur_key(idx={}): {}",
key, i, cur_key); key, i, cur_key);
return false; return false;
} }
root = root[cur_key]; root = &(*root)[cur_key];
} }
*last_part = keys.back(); *last_part = keys.back();

View File

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