100 lines
4.5 KiB
C++
100 lines
4.5 KiB
C++
#include "Source_Feed_Relation.h"
|
|
#include "Config.h"
|
|
#include "Global.h"
|
|
void Source_Feed_Relation::from_json(const Psc::JSON* that_json) {
|
|
Get_J(key) Get_J(type)
|
|
settings.write([&](auto& value) {
|
|
value.from_base_json(that_json, true);
|
|
});
|
|
}
|
|
Psc::JSON Source_Feed_Relation::to_json() const {
|
|
auto ret = settings.read([](const auto& value) { return value.to_base_json(); });
|
|
ret.append({"key", key});
|
|
ret.append({"type", type});
|
|
return ret;
|
|
}
|
|
void Source_Feed_Relation_Config::from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) {
|
|
static_cast<void>(not_exist_use_default_value);
|
|
auto j_list = that_json->get("list");
|
|
for (const Psc::JSON& item : j_list->children) {
|
|
auto relation = create_source_feed_relation_from_type(item.get_string("type"));
|
|
relation->from_json(&item);
|
|
validate(*relation);
|
|
map.push_back(relation);
|
|
}
|
|
}
|
|
Psc::JSON Source_Feed_Relation_Config::to_json() const {
|
|
Psc::JSON ret = Psc::JSON::object();
|
|
Psc::JSON list = Psc::JSON::array();
|
|
for (const auto& relation : map.list())
|
|
list.append(relation->to_json());
|
|
ret.append(Psc::JSON("list", list));
|
|
return ret;
|
|
}
|
|
void Source_Feed_Relation_Config::set_need_refresh() {
|
|
for (const auto& source : Global::instance()->mode_acs.data_source_config.map.list())
|
|
source->need_refresh_data_feed_key_list = true;
|
|
}
|
|
bool Source_Feed_Relation_Config::source_exists(std::string_view key) const {
|
|
return Global::instance()->mode_acs.data_source_config.map.get(std::string(key)).has_value();
|
|
}
|
|
bool Source_Feed_Relation_Config::feed_exists(std::string_view key) const {
|
|
return Global::instance()->mode_acs.data_feed_config.map.get(std::string(key)).has_value();
|
|
}
|
|
bool Source_Feed_Relation_Config::source_has_dependency(std::string_view key) const {
|
|
for (const auto& relation : map.list()) {
|
|
if (relation->type == "First_Source_To_All_Feed_Relation")
|
|
continue;
|
|
if (relation->settings.member<&Source_Feed_Relation_Data::source_key>().read([](const auto& value) { return value; }) == key)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool Source_Feed_Relation_Config::feed_has_dependency(std::string_view key) const {
|
|
for (const auto& relation : map.list()) {
|
|
const auto value = relation->settings.read([](const auto& value) { return value; });
|
|
if (relation->type == "One_to_One_Relation" && value.feed_key == key)
|
|
return true;
|
|
if (relation->type == "Name_One_To_Many_Relation") {
|
|
const auto& prefix = value.feed_name.empty() ? value.source_key : value.feed_name;
|
|
if (key.starts_with(prefix))
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
void Source_Feed_Relation_Config::validate(const Source_Feed_Relation& relation, std::string_view current_key) const {
|
|
if (relation.key.empty())
|
|
throw std::invalid_argument("关系名称不能为空");
|
|
auto existing = map.get(relation.key);
|
|
if (existing.has_value() && relation.key != current_key)
|
|
throw std::invalid_argument("关系名称已存在: " + relation.key);
|
|
const auto value = relation.settings.read([](const auto& value) { return value; });
|
|
if (relation.type == "One_to_One_Relation") {
|
|
if (!source_exists(value.source_key))
|
|
throw std::invalid_argument("数据源不存在: " + value.source_key);
|
|
if (!feed_exists(value.feed_key))
|
|
throw std::invalid_argument("数据馈送不存在: " + value.feed_key);
|
|
for (const auto& item : map.list()) {
|
|
if (item->key == current_key || item->type != "One_to_One_Relation")
|
|
continue;
|
|
if (item->settings.member<&Source_Feed_Relation_Data::feed_key>().read([](const auto& value) { return value; }) == value.feed_key)
|
|
throw std::invalid_argument("数据馈送已存在一对一关系: " + value.feed_key);
|
|
}
|
|
return;
|
|
}
|
|
if (relation.type == "Name_One_To_Many_Relation") {
|
|
if (!source_exists(value.source_key))
|
|
throw std::invalid_argument("数据源不存在: " + value.source_key);
|
|
return;
|
|
}
|
|
if (relation.type == "First_Source_To_All_Feed_Relation") {
|
|
for (const auto& item : map.list()) {
|
|
if (item->key != current_key && item->type == "First_Source_To_All_Feed_Relation")
|
|
throw std::invalid_argument("默认关系只能存在一个");
|
|
}
|
|
return;
|
|
}
|
|
throw std::invalid_argument("未知关系类型: " + relation.type);
|
|
}
|