59 s <<
"Failed to read \'" <<
what <<
"\' of object " << o <<
'\n' << reason;
67 s <<
"Failed to create object " << o <<
'\n' << reason;
75 s <<
"Failed to save object " << o <<
'\n' << reason;
83 s <<
"Failed to rename object " << o <<
'\n' << reason;
91 s <<
"Failed to destroy object " << o <<
'\n' << reason;
99 s <<
"Failed to set " << (is_rel ?
"relationship" :
"attribute") <<
" \'" << name <<
"\' of object " <<
obj <<
'\n'
107 std::ostringstream s;
108 s <<
"Failed to get " << (is_rel ?
"relationship" :
"attribute") <<
" \'" << name <<
"\' of object " <<
obj <<
'\n'
116 std::ostringstream s;
117 s <<
"Object " <<
obj <<
" cannot be linked with " << p1 <<
" via exclusive relationship \'" << name
118 <<
"\' since it is already referenced by object " << p2;
125 std::ostringstream s;
126 s <<
"Failed to init object " <<
obj <<
" because " << why <<
'\n' << reason;
133 const std::string& why,
134 const std::string& reason)
137 std::ostringstream s;
138 s <<
"Failed to bind relationship";
144 s <<
" of object " <<
obj <<
" because:\n" << why;
161 for (
unsigned long i = 0; i < 0xFFFFFFFF; ++i) {
162 sprintf(unique_id.get(),
"%s^%lu",
uid.
object_id.c_str(), i);
163 std::string id(unique_id.get());
175 for (std::vector<OksClass*>::const_iterator j = cs->begin(); j != cs->end(); ++j) {
177 if (__builtin_expect((o !=
nullptr), 0)) {
181 "has ID equal with \'"
183 <<
"\' object and their classes belong to the same inheritance hierarchy "
184 "(the OKS kernel is configured in the \"test-duplicated-objects-within-inheritance-hierarchy\" mode for "
185 "compatibility with config and DAL tools)";
197 const OksKernel* kernel(c->get_kernel());
201 if (__builtin_expect((c->get_is_abstract()), 0)) {
202 std::ostringstream text;
203 text <<
"the class \'" << c->get_name() <<
"\' is abstract";
209 if (__builtin_expect((!object_id.empty()), 1)) {
216 if (__builtin_expect((o !=
nullptr), 0)) {
220 std::cerr <<
"WARNING [OksObject constructor]:\n"
221 " Cannot create object "
227 " Skip above problem since OKS kernel is configured in \'ignore-duplicated-objects\' mode\n"
228 <<
" Create duplicated object with ID = \'" <<
uid.
object_id <<
"\'\n";
280 if (c->p_all_attributes) {
281 if (skip_init ==
false) {
282 for (
const auto& i : *c->p_all_attributes)
283 data[count++] = i->p_init_data;
285 for (
const auto& i : *c->p_all_attributes)
286 data[count++] = i->p_empty_init_data;
290 if (c->p_all_relationships) {
291 for (
const auto& i : *c->p_all_relationships) {
295 d.data.OBJECT =
nullptr;
307 if (__builtin_expect((c->p_indices !=
nullptr), 0)) {
308 for (
auto& i : *c->p_indices)
309 i.second->insert(
this);
313 c->p_kernel->define(
this);
323#define READ_OBJ_HEADER(F1, S1, F2, S2) \
325 OksXmlAttribute attr(read_params.s); \
326 if (oks::cmp_str1(attr.name(), ">") || oks::cmp_str1(attr.name(), "/")) { \
328 } else if (F1(attr.name(), S1)) { \
329 std::shared_lock lock(read_params.oks_kernel->p_schema_mutex); \
330 c = read_params.oks_kernel->find_class(attr.value()); \
331 if (__builtin_expect((c == nullptr), 0)) { \
332 std::ostringstream text; \
333 text << "cannot find class \"" << attr.value() << "\" (line " << read_params.s.get_line_no() << ", char " \
334 << read_params.s.get_line_pos() << ')'; \
335 throw std::runtime_error(text.str().c_str()); \
337 } else if (F2(attr.name(), S2)) \
338 id.assign(attr.value(), attr.value_len()); \
340 read_params.s.throw_unexpected_attribute(attr.name()); \
372 }
catch (std::exception& e) {
382 if (read_params.
format !=
'c') {
389 }
catch (std::exception& e) {
399 }
catch (std::exception& ex) {
406 o->read_body(read_params,
true);
413 if (c ==
nullptr &&
id.empty()) {
425 obj->create_notify();
428 TLOG_DEBUG(3) <<
"*** create object " <<
obj <<
" while reload data ***";
442 const char* type_str;
494 type_str =
"unknown";
502 " convert value from wrong type \""
503 << (num == -1 ?
"single" :
"multi") <<
"-value " << type_str <<
"\" to \""
506 <<
" converted value: " << d << std::endl;
517 " mismatch between relationship \""
518 << r.get_name() <<
"\" cardinality and its value (save data file with new schema)." << std::endl;
524 std::ostringstream s;
525 s <<
"Unknown attribute type \"" << atype <<
'\"';
534 int32_t num =
static_cast<int32_t
>(strtol(params.
s.
m_cvt_char->
m_buf, &__sanity, 0));
535 if (*__sanity != 0 || errno == ERANGE)
550 bool was_updated =
false;
557 file = read_params.
f;
563 if (__builtin_expect((read_params.
format !=
'c'), 1)) {
564 OksDataInfo::Map::iterator info_i;
569 std::list<const OksAttribute*>* read_attributes =
nullptr;
570 std::list<const OksRelationship*>* read_relationships =
nullptr;
572 if (__builtin_expect((check_re_read), 0)) {
573 if (c->p_all_attributes && !c->p_all_attributes->empty()) {
574 read_attributes =
new std::list<const OksAttribute*>();
575 for (
auto& i : *c->p_all_attributes)
576 read_attributes->push_back(i);
579 if (c->p_all_relationships && !c->p_all_relationships->empty()) {
580 read_relationships =
new std::list<const OksRelationship*>();
581 for (
auto& i : *c->p_all_relationships)
582 read_relationships->push_back(i);
584 }
else if (__builtin_expect((c !=
nullptr), 1)) {
585 if (__builtin_expect((re_read ==
true), 0)) {
586 OksData* d_end =
data + c->number_of_all_attributes() + c->number_of_all_relationships();
622 bool attr_is_closed(
false);
628 bool name_was_read(
false);
639 attr_is_closed =
true;
645 name_was_read =
true;
646 if (__builtin_expect((c !=
nullptr), 1)) {
648 info_i = c->p_data_info->find(i_name);
649 if (__builtin_expect((info_i == c->p_data_info->end() || info_i->second->attribute ==
nullptr), 0)) {
650 if (non_silent_mode) {
651 std::string msg = std::string(
"Read object \"") +
GetId() +
'@' + c->get_name() +
'\"';
654 <<
" skip attribute \"" << attr.
value() <<
"\", which is not defined in the schema\n";
657 info = info_i->second;
664 if (attr.
value()[0] != 0 &&
670 num =
static_cast<int32_t
>(strtol(attr.
value(), &__sanity, 0));
671 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
681 if (__builtin_expect((!name_was_read), 0)) {
690 }
catch (std::exception& e) {
695 if (__builtin_expect((a !=
nullptr), 1)) {
699 if (__builtin_expect((check_re_read), 0)) {
701 read_attributes->remove(a);
720 if (read_params.
format !=
'n')
721 d2.
read(read_params, &a2);
725 if (non_silent_mode) {
729 if (read_params.
format !=
'n')
730 dx->
read(read_params, a);
738 if (read_params.
format !=
'n')
739 d2.
read(read_params, &a2, num);
741 if (attr_is_closed ==
false)
742 d2.
read(&a2, read_params);
747 if (non_silent_mode) {
751 if (read_params.
format !=
'n')
752 dx->
read(read_params, a, num);
754 if (attr_is_closed ==
false)
755 dx->
read(a, read_params);
767 }
catch (std::exception& e) {
771 if (__builtin_expect((check_re_read), 0)) {
783 if (read_params.
format !=
'n')
786 if (read_params.
format !=
'n')
787 OksData(read_params, &a2, num);
793 }
catch (std::exception& e) {
800 if (read_params.
format !=
'n')
805 std::string s(
"\'/attr\' is expected instead of \'");
808 throw std::runtime_error(s.c_str());
812 }
catch (std::exception& e) {
840 if (__builtin_expect((c !=
nullptr), 1)) {
842 info_i = c->p_data_info->find(i_name);
843 if (__builtin_expect((info_i == c->p_data_info->end() || info_i->second->relationship ==
nullptr),
845 if (non_silent_mode) {
846 std::string msg = std::string(
"Read object \"") +
GetId() +
'@' + c->get_name() +
'\"';
849 <<
" skip relationship \"" << attr.
value() <<
"\", which is not defined in the schema\n";
852 info = info_i->second;
857 }
else if (read_params.
format ==
'n') {
860 if (__builtin_expect((value.
m_class ==
nullptr && attr.
value_len() > 0), 0)) {
870 num =
static_cast<int32_t
>(strtol(attr.
value(), &__sanity, 0));
871 if (__builtin_expect((*__sanity != 0 || errno == ERANGE), 0))
882 }
catch (std::exception& e) {
891 if (__builtin_expect((r !=
nullptr), 1)) {
897 if (__builtin_expect((check_re_read), 0)) {
899 read_relationships->remove(r);
910 if (read_params.
format ==
'n')
911 d2.
read(&dummy, value);
913 d2.
read(read_params, &dummy);
916 if (read_params.
format ==
'n')
919 dx->
read(read_params, r);
926 if (read_params.
format ==
'n')
927 d2.
read(&dummy, read_params);
929 d2.
read(read_params, &dummy, num);
932 if (read_params.
format ==
'n')
933 dx->
read(r, read_params);
935 dx->
read(read_params, r, num);
940 }
catch (std::exception& e) {
956 if (read_params.
format !=
'n')
959 if (read_params.
format ==
'n')
966 }
catch (std::exception& e) {
973 if (read_params.
format !=
'n')
978 std::string s(
"\'/rel\' is expected instead of \'");
981 throw std::runtime_error(s.c_str());
985 }
catch (std::exception& e) {
995 }
catch (std::exception& e) {
1001 if (__builtin_expect((check_re_read), 0)) {
1002 if (read_attributes) {
1003 if (!read_attributes->empty()) {
1004 for (
auto i = read_attributes->begin(); i != read_attributes->end(); i = read_attributes->erase(i)) {
1005 OksData d = (*i)->p_init_data;
1014 this, std::string(
"cannot reset default value of attribute \"") + (*i)->get_name() +
'\"', ex);
1019 delete read_attributes;
1022 if (read_relationships) {
1023 if (!read_relationships->empty()) {
1024 for (
auto i = read_relationships->begin(); i != read_relationships->end(); i = read_relationships->erase(i)) {
1029 if (d2 && *d2 != d) {
1035 this, std::string(
"cannot reset value of relationship \"") + (*i)->get_name() +
'\"', ex);
1040 delete read_relationships;
1047 throw std::runtime_error(
" ***** Can't read objects of undefined class *****\n"
1048 " ***** from file saved in non-extended format. *****\n"
1049 " ***** Fix the problem first. Processing terminated. *****\n");
1052 if (c->p_all_attributes) {
1053 for (
const auto& i : *c->p_all_attributes) {
1054 if (check_re_read) {
1057 if (i->get_is_multi_values()) {
1058 d.read(read_params, i,
__get_num(read_params));
1060 d.read(read_params, i);
1063 if (d !=
data[count]) {
1068 if (i->get_is_multi_values()) {
1079 if (c->p_all_relationships) {
1080 for (
const auto& i : *c->p_all_relationships) {
1081 if (check_re_read) {
1085 d.read(read_params, i,
__get_num(read_params));
1087 d.read(read_params, i);
1090 if (d !=
data[count]) {
1112 std::ostringstream s;
1113 s <<
"Failed to read obj close tag (\'/" << read_params.
object_tag <<
"\' is expected)";
1114 throw std::runtime_error(s.str().c_str());
1118 }
catch (std::exception& e) {
1157 if (!c->p_kernel->get_active_data()) {
1158 Oks::error_msg(
"OksObject::OksObject(const OksClass*, const char *)")
1159 <<
" Can not create new object since there is no active data file\n";
1186 Oks::error_msg(
"OksObject::OksObject(const OksObject&, const char *)")
1187 <<
" Can not create new object since there is no active data file\n";
1202 int count = c->p_instance_size;
1203 int num_of_attr = c->p_all_attributes->size();
1206 while (j < num_of_attr) {
1212 std::list<OksRelationship*>::iterator i = c->p_all_relationships->begin();
1216 const char* relationshipName = r->get_name().c_str();
1258 memcpy(
static_cast<void*
>(&
data[
offset]),
static_cast<const void*
>(d),
sizeof(
OksData));
1262 const std::string&
id,
1265 int32_t duplicated_object_id_idx,
1278 if (
size_t data_size = c->p_instance_size *
sizeof(
OksData*)) {
1279 bzero(data, data_size);
1293 std::unique_ptr<std::ostringstream> error_text;
1297 for (OksClass::Map::const_iterator i = classes.begin(); i != classes.end(); ++i) {
1299 if (c->p_all_relationships ==
nullptr || c->p_all_relationships->empty())
1303 for (OksObject::Map::const_iterator j = objects->begin(); j != objects->end(); ++j) {
1304 size_t offset = c->number_of_all_attributes();
1305 for (std::list<OksRelationship*>::iterator k = c->p_all_relationships->begin();
1306 k != c->p_all_relationships->end();
1314 for (
const auto& l : *d->data.LIST) {
1323 if (!error_text.get()) {
1324 error_text.reset(
new std::ostringstream());
1325 *error_text <<
"since it is referenced by:";
1327 *error_text <<
"\n * object " << ref <<
" via relationship \"" << (*k)->get_name() <<
'\"';
1334 if (error_text.get()) {
1363 static std::mutex s_mutex;
1364 static std::set<OksObject*, std::less<OksObject*>> oset;
1368 std::lock_guard lock(s_mutex);
1375 if (c->p_all_relationships && !c->p_all_relationships->empty()) {
1376 OksData* di =
data + c->number_of_all_attributes();
1378 for (std::list<OksRelationship*>::iterator i = c->p_all_relationships->begin();
1379 i != c->p_all_relationships->end();
1383 if (r->get_is_composite() ==
false || k->
p_close_all ==
true)
1394 bool delete_obj(r->get_is_dependent() && !o->
p_rcr);
1397 std::lock_guard lock(s_mutex);
1398 delete_obj = (oset.find(o) == oset.end());
1403 d->data.OBJECT =
nullptr;
1407 for (
const auto& i2 : *d->data.LIST) {
1414 bool delete_obj(r->get_is_dependent() && !o->
p_rcr);
1417 std::lock_guard lock(s_mutex);
1418 delete_obj = (oset.find(o) == oset.end());
1423 i2->
data.OBJECT =
nullptr;
1433 for (
const auto& i : *c->p_indices)
1434 i.second->remove_obj(
this);
1437 int count = c->p_instance_size;
1453 for (std::list<OksRCR*>::const_iterator i =
p_rcr->begin(); i !=
p_rcr->end(); ++i) {
1461 std::lock_guard lock(s_mutex);
1495 }
catch (std::exception& ex) {
1501 if (c->get_object(new_id)) {
1507 std::set<OksFile*> updated_files;
1508 std::list<OksObject*> updated_objects;
1510 updated_files.insert(
file);
1511 updated_objects.push_back(
this);
1515 for (OksClass::Map::const_iterator i = classes.begin(); i != classes.end(); ++i) {
1518 size_t d_end = c->p_instance_size;
1519 size_t d_begin = c->p_all_attributes->size();
1520 if (objs && (d_end != d_begin)) {
1521 for (OksObject::Map::const_iterator j = objs->begin(); j != objs->end(); ++j) {
1526 for (
size_t k = d_begin; k != d_end && o; ++k) {
1527 const OksData& d = o->data[k];
1529 updated_objects.push_back(o);
1530 updated_files.insert(o->file);
1534 for (OksData::List::const_iterator l = list.begin(); l != list.end(); ++l) {
1537 updated_objects.push_back(o);
1538 updated_files.insert(o->file);
1551 for (std::set<OksFile*>::const_iterator i = updated_files.begin(); i != updated_files.end(); ++i) {
1566 for (std::set<OksFile*>::const_iterator i = updated_files.begin(); i != updated_files.end(); ++i) {
1567 (*i)->set_updated();
1571 for (std::list<OksObject*>::const_iterator i = updated_objects.begin(); i != updated_objects.end(); ++i) {
1572 (*i)->change_notify();
1583 if (o1 ==
nullptr || o2 ==
nullptr)
1599 while (count < uid.class_id->p_instance_size) {
1631 s <<
"Object " << &o << std::endl;
1638 const std::list<OksAttribute*>* alist = c->all_attributes();
1640 if (alist && !alist->empty()) {
1641 s <<
" Attributes are:\n";
1643 for (std::list<OksAttribute*>::const_iterator i = alist->begin(); i != alist->end(); ++i) {
1645 s.setf(((*i)->get_format() ==
OksAttribute::Hex ? std::ios::hex : std::ios::oct), std::ios::basefield);
1646 s.setf(std::ios::showbase);
1649 s <<
" " << (*i)->get_name() <<
": " << *di++ << std::endl;
1652 s.setf(std::ios::dec, std::ios::basefield);
1653 s.unsetf(std::ios::showbase);
1657 s <<
" There are no attributes\n";
1663 const std::list<OksRelationship*>* rlist = c->all_relationships();
1665 if (rlist && !rlist->empty()) {
1666 s <<
" Relationships are:\n";
1668 for (std::list<OksRelationship*>::const_iterator i = rlist->begin(); i != rlist->end(); ++i)
1669 s <<
" " << (*i)->get_name() <<
": " << *di++ << std::endl;
1671 s <<
" There are no relationships\n";
1686 if (d.data.OBJECT && kernel.
is_dangling(d.data.OBJECT)) {
1687 d.data.OBJECT =
nullptr;
1690 return (d.data.OBJECT !=
nullptr);
1693 for (OksData::List::iterator i = d.data.LIST->begin(); i != d.data.LIST->end();) {
1697 i = d.data.LIST->erase(i);
1705 return (!d.data.LIST->empty());
1716 const std::string* class_name =
nullptr;
1717 const std::string* object_id =
nullptr;
1720 class_name = &d.data.OBJECT->GetClass()->get_name();
1721 object_id = &d.data.OBJECT->GetId();
1723 class_name = &d.data.UID.class_id->get_name();
1724 object_id = d.data.UID.object_id;
1726 class_name = d.data.UID2.class_id;
1727 object_id = d.data.UID2.object_id;
1752 for (
const auto& a : *alist) {
1759 (a->get_init_value().empty() ==
false &&
1760 (a->get_is_multi_values() ==
true || a->is_number() ==
false || a->get_init_value().size() > 1 ||
1761 a->get_init_value()[0] !=
'0'))) {
1769 std::ios::basefield);
1773 if (a->get_is_multi_values() ==
false) {
1777 if (d.data.LIST->empty()) {
1785 for (
const auto& x : *d.data.LIST) {
1799 xmls.
get_stream().setf(std::ios::dec, std::ios::basefield);
1800 xmls.
get_stream().unsetf(std::ios::showbase);
1807 for (
const auto& r : *rlist) {
1824 for (
const auto& x : *rel_data.
data.
LIST) {
1842 }
catch (std::ios_base::failure& ex) {
1844 }
catch (std::exception& ex) {
1857 std::ostringstream text;
1858 text <<
"object " <<
this <<
" has no attribute \"" << name <<
'\"';
1874 Oks::warning_msg(
"OksObject::SetAttributeValue(const OksDataInfo *, OksData *)")
1875 <<
" * ODI attribute name: \'" << a->
get_name()
1877 " * ODI data offset: \'"
1880 " * OKS data (new): \'"
1881 << *d <<
"\' type: " << (int)d->type
1883 " * OKS data (old): \'"
1889 " Convert attribute \""
1890 << a->
get_name() <<
"\" value since the OksData::type is invalid\n";
1935 std::ostringstream text;
1936 text <<
"object " <<
this <<
" has no attribute \"" << name <<
'\"';
1949 std::ostringstream text;
1950 text <<
"object " <<
this <<
" has no relationship \"" << name <<
'\"';
1965 "set to (null) is not allowed since the relationship has non-zero low cardinality constraint");
1975 const OksClass* rel_class_type = r->p_class_type;
1977 if (class_type != rel_class_type) {
1980 if (super_classes && !super_classes->empty()) {
1981 for (
const auto& i : *super_classes) {
1982 if (rel_class_type == i)
1987 std::ostringstream text;
1988 text <<
"set to an object of class \"" << class_type->get_name()
1989 <<
"\" is not allowed since the relationship's class type is \"" << r->get_type() <<
"\" and the class \""
1990 << class_type->get_name() <<
"\" has no such superclass";
2003 std::ostringstream text;
2004 text <<
"OKS data type is invalid: must be "
2006 <<
"; new: \'" << *d <<
"\'; old:" <<
data[
offset] <<
'\'';
2019 if (add_obj != rm_obj) {
2021 added_objs.insert(add_obj);
2023 removed_objs.insert(rm_obj);
2028 if (skip_non_null_check ==
false)
2032 if (d->data.LIST->empty()) {
2038 "set to empty list is not allowed since the relationship has non-zero low cardinality constraint");
2042 for (
const auto& i : *d->data.LIST) {
2056 added_objs.insert(o2);
2062 this,
true, r->get_name(),
"the OKS data type is invalid (must be a list of objects or an object)");
2072 removed_objs.insert(i->data.OBJECT);
2079 for (
const auto& i : removed_objs) {
2080 if (added_objs.find(i) == added_objs.end()) {
2081 TLOG_DEBUG(4) <<
"object " << i <<
" was removed from relationship";
2082 i->remove_RCR(
this, r);
2088 for (OksObject::FSet::const_iterator i = added_objs.begin(); i != added_objs.end(); ++i) {
2090 if (removed_objs.find(add_obj) == removed_objs.end()) {
2091 TLOG_DEBUG(4) <<
"object " << add_obj <<
" was added to relationship";
2098 for (OksObject::FSet::const_iterator j = added_objs.begin(); j != i; ++j) {
2099 if (removed_objs.find(*j) == removed_objs.end()) {
2100 (*j)->remove_RCR(
this, r);
2104 for (OksObject::FSet::const_iterator j = removed_objs.begin(); j != removed_objs.end(); ++j) {
2105 if (added_objs.find(*j) == added_objs.end()) {
2107 (*j)->add_RCR(
this, r);
2130 std::ostringstream text;
2131 text <<
"object " <<
this <<
" has no relationship \"" << name <<
'\"';
2145 std::ostringstream text;
2146 text <<
"cannot set value " <<
object <<
" since the relationship has \'many\' high cardinality constraint";
2159 d.data.OBJECT->remove_RCR(
this, r);
2164 object->add_RCR(
this, r);
2169 d.data.OBJECT->add_RCR(
this, r);
2188 std::ostringstream text;
2189 text <<
"object " <<
this <<
" has no relationship \"" << name <<
'\"';
2200 return ((d2->
data.
OBJECT == d->data.OBJECT) ?
true :
false);
2203 : d->type ==
OksData::uid2_type ? *(
static_cast<std::string*
>(d->data.UID2.object_id))
2204 : *(
static_cast<std::string*
>(d->data.UID.object_id));
2208 ? *(
static_cast<std::string*
>(d2->
data.
UID2.object_id))
2209 : *(
static_cast<std::string*
>(d2->
data.
UID.object_id));
2211 if (object_id != object_id2)
2222 if (pclass_id && pclass_id2)
2223 return (pclass_id == pclass_id2 ?
true :
false);
2225 const std::string& class_id =
2226 (pclass_id ? pclass_id->
get_name() : *(
static_cast<std::string*
>(d->data.UID2.class_id)));
2228 const std::string& class_id2 =
2229 (pclass_id2 ? pclass_id2->
get_name() : *(
static_cast<std::string*
>(d2->
data.
UID2.class_id)));
2231 return (class_id == class_id2 ?
true :
false);
2247 std::ostringstream text;
2248 text <<
"cannot add value " <<
object <<
" since the relationship has no \'many\' high cardinality constraint";
2253 object->add_RCR(
this, r);
2271 std::ostringstream text;
2272 text <<
"object " <<
this <<
" has no relationship \"" << name <<
'\"';
2289 std::ostringstream text;
2290 text <<
"cannot remove object " <<
object <<
" since the relationship has no \'many\' high cardinality constraint";
2298 for (OksData::List::iterator i = list->begin(); i != list->end();) {
2302 object->remove_RCR(
this, r);
2311 std::ostringstream text;
2312 text <<
"cannot remove object " <<
object <<
" since the relationship\'s value has no such object";
2322 std::ostringstream text;
2323 text <<
"object " <<
this <<
" has no relationship \"" << name <<
'\"';
2336 std::ostringstream text;
2337 text <<
"object " <<
this <<
" has no relationship \"" << name <<
'\"';
2346 if (object_id.empty() || class_id.empty()) {
2365 }
else if (r->get_type() != class_id) {
2366 std::ostringstream text;
2367 text <<
"cannot set value \"" << object_id <<
'@' << class_id <<
"\" since the class \"" << class_id
2368 <<
"\" is not defined and it is impossible to check its validity for given type of relationship";
2373 std::ostringstream text;
2374 text <<
"cannot set object \"" << object_id <<
'@' << class_id
2375 <<
"\" since the relationship has \'many\' high cardinality constraint";
2382 o = c->get_object(object_id);
2405 std::ostringstream text;
2406 text <<
"object " <<
this <<
" has no relationship \"" << name <<
'\"';
2413 if (class_id.empty() || object_id.empty()) {
2417 const std::string& r_class_type = r->get_type();
2424 }
else if (r_class_type != class_id) {
2425 std::ostringstream text;
2426 text <<
"cannot add value \"" << object_id <<
'@' << class_id <<
"\" since the class \"" << class_id
2427 <<
"\" is not defined and it is impossible to check its validity for given type of relationship";
2432 std::ostringstream text;
2433 text <<
"cannot add object \"" << object_id <<
'@' << class_id
2434 <<
"\" since the relationship has no \'many\' high cardinality constraint";
2441 o = c->get_object(object_id);
2458 std::ostringstream text;
2459 text <<
"object " <<
this <<
" has no relationship \"" << name <<
'\"';
2466 if (object_id.empty() || class_id.empty()) {
2471 std::ostringstream text;
2472 text <<
"cannot remove object \"" << object_id <<
'@' << class_id
2473 <<
"\" since the relationship has no \'many\' high cardinality constraint";
2478 OksData d(class_id, object_id);
2481 for (OksData::List::iterator j = list->begin(); j != list->end();) {
2493 std::ostringstream text;
2494 text <<
"cannot remove object \"" << object_id <<
'@' << class_id
2495 <<
"\" since the relationship\'s value has no such object";
2502 if (r->get_is_composite() ==
false)
2505 TLOG_DEBUG(4) <<
"object " <<
this <<
" adds RCR to object " << o <<
" throught relationship \"" << r->get_name()
2509 p_rcr =
new std::list<OksRCR*>();
2511 for (
const auto& i : *
p_rcr) {
2512 if (i->relationship == r) {
2514 TLOG_DEBUG(4) <<
"[this=" <<
this <<
", o=" << o <<
", r=\"" << r->get_name()
2515 <<
"\"]: such RCR was already set.";
2517 }
else if (r->get_is_exclusive()) {
2530 TLOG_DEBUG(4) <<
"object " <<
this <<
" removes RCR from object " << o <<
" through " << r->get_name();
2532 if (r->get_is_composite() ==
false || !
p_rcr)
2535 for (std::list<OksRCR*>::iterator i =
p_rcr->begin(); i !=
p_rcr->end(); ++i) {
2545 if (
p_rcr->empty()) {
2558 if (d->data.UID.class_id && !d->data.UID.object_id->empty()) {
2559 c = d->data.UID.class_id;
2560 o = c->get_object(d->data.UID.object_id);
2566 if (d->data.UID2.class_id->empty() || d->data.UID2.object_id->empty()) {
2571 c = info.k->find_class(*d->data.UID2.class_id);
2574 o = c->get_object(d->data.UID2.object_id);
2576 std::ostringstream text;
2577 text <<
"Class of object " << *d <<
" is not defined";
2582 if (c != info.r->p_class_type) {
2584 for (OksClass::FList::const_iterator i = slist->begin(); i != slist->end(); ++i) {
2585 if (info.r->p_class_type == *i) {
2592 std::ostringstream text;
2593 text <<
"The relationship has class type \"" << info.r->get_type() <<
"\" and the referenced object " << *d
2594 <<
" is not of that class or derived one";
2602 std::ostringstream text;
2603 text <<
"Cannot find object " << *d;
2611 std::ostringstream text;
2612 text <<
"Failed to set relationship value " << o;
2632 std::ostringstream&
add();
2639 (*p_warnings) <<
'\n';
2650 add() <<
" * object " << d <<
" via relationship \"" << r->get_name() <<
'\"';
2656 add() <<
" * relationship \"" << r->get_name() <<
"\" has non-zero low cardinality constraint, but it is empty";
2664 if (c->p_all_relationships->empty())
2668 info.k = c->p_kernel;
2675 for (
auto& i : (*c->p_all_relationships)) {
2679 if (i->get_low_cardinality_constraint() ==
OksRelationship::One && d->data.OBJECT ==
nullptr) {
2683 if (d->data.UID.object_id ==
nullptr) {
2699 if (d->data.LIST->empty()) {
2704 for (
const auto& i2 : *d->data.LIST) {
2719 if (i->get_low_cardinality_constraint() ==
OksRelationship::One && d->data.UID2.object_id ==
nullptr) {
2737 std::ostringstream text;
2740 text <<
"There " << s1 <<
" " << warnings.
p_warnings_count <<
" unresolved reference" << s2 <<
" from object "
2755 for (
size_t i = 0; i < num_of_rels; ++i) {
2762 if (o && o->
file == f) {
2764 std::cout <<
"- unbind_file(\'" << f->get_full_file_name() <<
"\') in " <<
this <<
": replace " << *d;
2769 std::cout <<
" by " << *d << std::endl;
2772 for (
const auto& j : *d->data.LIST) {
2776 if (o && o->
file == f) {
2778 std::cout <<
"+ unbind_file(\'" << f->get_full_file_name() <<
"\') in " <<
this <<
": replace " << *j;
2783 std::cout <<
" by " << *j << std::endl;
2841 const std::set<OksFile*>& includes,
2842 const std::string& name,
2843 const char* msg)
const
2846 if (includes.find(o2->
get_file()) == includes.end()) {
2847 if (
GetClass()->get_kernel()->get_silence_mode() ==
false) {
2849 <<
": no files inclusion path between referenced objects:\n"
2853 " has reference to object "
2859 for (std::set<OksFile*>::const_iterator j = includes.begin(); j != includes.end(); ++j) {
2860 std::cerr <<
" * \'" << (*j)->get_full_file_name() <<
"\'\n";
2875 std::ostringstream text;
2877 if (result.empty()) {
2878 text <<
" * object " <<
obj <<
" has dangling references:\n";
2881 text <<
" - object " << d <<
" referenced via \'" << r.get_name() <<
"\'\n";
2883 result += text.str();
2902 for (OksData::List::const_iterator li = d->data.LIST->begin(); li != d->data.LIST->end(); ++li) {
2924 bool return_value =
true;
2935 for (OksData::List::const_iterator li = d->data.LIST->begin(); li != d->data.LIST->end(); ++li) {
2937 if (
OksObject* o2 = (*li)->data.OBJECT) {
2944 if (d->IsConsistent(odi.
relationship,
this,
"ERROR") ==
false) {
2945 return_value =
false;
2955 if (
GetClass()->get_kernel()->get_silence_mode() ==
false) {
2956 std::cerr <<
"ERROR: the schema file is not included for object " <<
this
2960 <<
"\" containg above object\n"
2961 " cannot be loaded or edited without inclusion of additional files.\n"
2962 " The file shall explicitly or implicitly (i.e. via other included files) include schema file\n"
2971 return return_value;
2990_references(
const OksObject*
obj,
unsigned long recursion_depth, RefData& data);
2997 std::pair<OksObject::FSet::iterator, bool> ret = data.tested_objs.insert(
const_cast<OksObject*
>(o));
2999 if (ret.second ==
true) {
3000 if (data.classes ==
nullptr || data.classes->find(
const_cast<OksClass*
>(o->
GetClass())) != data.classes->end()) {
3001 data.refs.insert(
const_cast<OksObject*
>(o));
3014 if (recursion_depth == 0)
3017 size_t l1 =
obj->GetClass()->number_of_all_attributes();
3018 size_t l2 = l1 +
obj->GetClass()->number_of_all_relationships();
3029 for (OksData::List::const_iterator li = d->data.LIST->begin(); li != d->data.LIST->end(); ++li) {
3057 TLOG_DEBUG(2) <<
"OksObject::references(" <<
this <<
", " << recursion_depth <<
") returns " << refs.size()
3064 bool any_name = (name ==
"*");
3070 for (OksClass::Map::const_iterator i = all_classes.begin(); i != all_classes.end(); ++i) {
3072 if (any_name || c->find_relationship(name) !=
nullptr) {
3074 for (OksObject::Map::const_iterator j = objs->begin(); j != objs->end(); ++j) {
3076 unsigned short l1, l2;
3079 l1 = c->number_of_all_attributes();
3080 l2 = l1 + c->number_of_all_relationships();
3082 l1 = c->data_info(name)->offset;
3091 if (
this == d->data.OBJECT) {
3094 result->push_back(o);
3099 for (OksData::List::const_iterator li = d->data.LIST->begin(); li != d->data.LIST->end(); ++li) {
3105 result->push_back(o);
static std::string fill(const OksObject *obj, const std::string &name, const OksObject *p1, const OksObject *p2)
Failed move item to file.
static std::string fill(const OksObject *o, const std::string &reason)
static std::string fill(const OksObject *o, const std::string &reason)
static std::string fill(const OksObject *o, const std::string &what, const std::string &reason)
static std::string fill(const OksObject *o, const std::string &reason)
static std::string fill(const OksObject *o, const std::string &reason)
std::string fill(const OksObject *obj, const OksRelationship *rel, const std::string &why, const std::string &reason)
const OksRelationship * p_rel
static std::string fill(const OksObject *obj, bool is_rel, const std::string &name, const std::string &reason)
static std::string fill(const OksObject *obj, const std::string &why, const std::string &reason)
static std::string fill(const OksObject *obj, bool is_rel, const std::string &name, const std::string &reason)
static const char * s8_int_type
static const char * u32_int_type
static const char * u8_int_type
static const char * time_type
static const char * s64_int_type
bool get_is_multi_values() const noexcept
static const char * bool_type
const std::string & get_type() const noexcept
Get attribute string type.
const std::string & get_name() const noexcept
out stream operator
static const char * class_type
static const char * string_type
static const char * enum_type
static const char * s32_int_type
static const char * s16_int_type
OksData::Type get_data_type() const noexcept
static const char * u64_int_type
static const char * double_type
const std::string & get_init_value() const noexcept
const std::string * get_enum_value(const char *s, size_t length) const
Returns pointer on internal enumerator data equal to given string, if such string is defined in attri...
static const char * u16_int_type
static const char * date_type
static const char * float_type
static OksData::Type get_data_type(const std::string &type) noexcept
Converts string to attribute OKS data type.
std::list< OksClass *, boost::fast_pool_allocator< OksClass * > > FList
const std::list< OksAttribute * > * all_attributes() const noexcept
size_t number_of_all_relationships() const noexcept
std::mutex p_unique_id_mutex
OksKernel * get_kernel() const noexcept
OksIndex::Map * p_indices
const std::string & get_name() const noexcept
size_t number_of_all_attributes() const noexcept
OksClass(const std::string &name, OksKernel *kernel, bool transient=false)
Create OKS class.
std::vector< OksClass * > * p_inheritance_hierarchy
OksObject * get_object(const std::string &id) const noexcept
Get object by ID.
OksDataInfo::Map * p_data_info
OksFile * get_file() const noexcept
friend std::ostream & operator<<(std::ostream &, const OksClass &)
Stream operator.
std::map< const char *, OksClass *, SortStr > Map
const std::list< OksRelationship * > * all_relationships() const noexcept
Provides interface to the OKS XML schema and data files.
void lock()
Lock OKS file.
const std::string & get_full_file_name() const
OksObject * remove_obj(OksObject *)
Provides interface to the OKS kernel.
OksObject::notify_obj p_change_object_notify_fn
OksFile * get_active_data() const
Get active OKS data file.
bool is_dangling(OksClass *class_ptr) const
Check pointer on oks class.
static std::mutex p_parallel_out_mutex
bool get_verbose_mode() const
Get status of verbose mode. The method returns true, if the verbose mode is switched 'On'.
bool get_test_duplicated_objects_via_inheritance_mode() const
Get status of test inherited duplicated objects mode. The method returns true, if the mode is switche...
OksObject::notify_obj p_delete_object_notify_fn
bool get_allow_duplicated_objects_mode() const
Get status of duplicated objects mode. The method returns true, if the duplicated objects mode is swi...
const OksClass::Map & classes() const
Get classes.
void * p_delete_object_notify_param
void undefine(OksObject *o)
std::mutex p_objects_refs_mutex
void * p_change_object_notify_param
OksObject::notify_obj p_create_object_notify_fn
OksClass * find_class(const std::string &class_name) const
Find class by name (C++ string).
bool get_silence_mode() const
Get status of silence mode. The method returns true, if the silence mode is switched 'On'....
std::shared_mutex p_schema_mutex
void * p_create_object_notify_param
OksObject describes instance of OksClass.
struct dunedaq::oks::OksObject::OksUid uid
static void destroy(OksObject *obj, bool fast=false)
Destroy OKS object.
void AddRelationshipValue(const std::string &name, OksObject *object)
Add object value to multi-value relationship by name.
void RemoveRelationshipValue(const std::string &name, OksObject *object)
Remove object value from multi-value relationship by name.
void __report_type_cvt_warning(const oks::ReadFileParams &, const OksAttribute &, const OksData &, const OksData::Type, int32_t) const
void check_file_lock(const OksAttribute *, const OksRelationship *)
void put(OksXmlOutputStream &, bool force_defaults) const
OksData * GetRelationshipValue(const std::string &) const
Get value of relationship by name.
std::unordered_set< OksObject *, oks::hash_obj_ptr, oks::equal_obj_ptr > FSet
void(*) notify_obj(OksObject *, void *)
static const char class2_xml_attribute[]
friend std::ostream & operator<<(std::ostream &out, const OksObject &obj)
Detailed stream operator.
static const char relationship_xml_tag[]
void references(OksObject::FSet &refs, unsigned long recursion_depth, bool add_self=false, oks::ClassSet *classes=0) const
OksFile * get_file() const
void init1(const OksFile *=0)
static const char attribute_xml_tag[]
static const char obj2_xml_tag[]
static void put_object_attributes(OksXmlOutputStream &, const OksData &)
void __report_cardinality_cvt_warning(const oks::ReadFileParams &, const OksRelationship &) const
static const char value_xml_attribute[]
std::string report_dangling_references() const
void SetRelationshipValue(const std::string &name, OksData *data, bool skip_non_null_check=false)
Set value of relationship by name.
void read_body(const oks::ReadFileParams &, bool)
int32_t __get_num(const oks::ReadFileParams ¶ms)
void add_RCR(OksObject *, const OksRelationship *)
void check_class_type(const OksRelationship *, const OksClass *)
static const char id_xml_attribute[]
void set_file(OksFile *file, bool update_owner=true)
Move object to different file.
static const char obj_xml_tag[]
std::unordered_map< const std::string *, OksObject *, oks::hash_str, oks::equal_str > Map
static OksObject * read(const oks::ReadFileParams &)
FList * get_all_rels(const std::string &name="*") const
Return objects referencing this one via relationship with given name.
void * GetTransientData() const
Get transient user data associated with given object. Return data set using SetTransientData() method...
std::list< OksObject *, boost::fast_pool_allocator< OksObject * > > FList
void check_non_null(const OksRelationship *, const OksObject *)
void unbind_file(const OksFile *)
OksObject(const OksClass *oks_class, const char *object_id=0, bool skip_init=false)
OKS object constructor.
static const char id2_xml_attribute[]
static const char num_xml_attribute[]
const OksClass * GetClass() const
static bool are_equal_fast(const OksObject *o1, const OksObject *o2)
The fast equal method.
static const char class_xml_attribute[]
static void bind(OksData *, const BindInfo &)
static const char name_xml_attribute[]
void set_id(const std::string &id)
Set object ID.
void remove_RCR(OksObject *, const OksRelationship *) noexcept
static const char type_xml_attribute[]
notify_obj get_change_notify() const
std::list< OksRCR * > * p_rcr
static const char data_xml_tag[]
void init2(bool skip_init=false)
bool is_consistent(const std::set< OksFile * > &, const char *msg) const
void SetAttributeValue(const std::string &name, OksData *data)
Set value of attribute by name.
bool check_links_and_report(const OksObject *, const std::set< OksFile * > &, const std::string &, const char *) const
bool operator==(const OksObject &) const
The equality operator.
void SetTransientData(void *d) const
Set transient user data associated with given object. Such data are not stored on file and only exist...
static const char ref_xml_tag[]
const std::string & GetId() const
int32_t p_duplicated_object_id_idx
OksData * GetAttributeValue(const std::string &name) const
Get value of attribute by name.
@ ObjectNormalConstructor
@ ObjectStreamConstructor
const std::string & get_name() const noexcept
OksString()
to deallocate memory when destroyed
void put_last_tag(const char *, size_t len)
void put_attribute(const char *, size_t len, const char *)
void put_start_tag(const char *, size_t len)
std::ostream & get_stream() const
static std::ostream & warning_msg(const char *)
static std::ostream & error_msg(const char *)
virtual const char * what() const noexcept
#define OSK_PROFILING(FID, K)
#define TLOG_DEBUG(lvl,...)
bool cmp_str1(const char *s1, const char s2[2])
bool cmp_str4(const char *s1, const char s2[5])
bool cmp_str9(const char *s1, const char s2[10])
static void _references(const OksObject *obj, unsigned long recursion_depth, RefData &data)
static void insert2refs(const OksObject *o, unsigned long recursion_depth, RefData &data)
static void test_dangling_references(const OksObject *obj, const OksData &d, const OksRelationship &r, std::string &result)
void validate_not_empty(const std::string &value, const char *name)
bool cmp_str2(const char *s1, const char s2[3])
std::unordered_set< const OksClass *, oks::hash_class_ptr, oks::equal_class_ptr > ClassSet
bool cmp_str5(const char *s1, const char s2[6])
static bool trim_dangling(OksData &d, const OksKernel &kernel)
static void __throw_unknown_type(const oks::ReadFileParams ¶ms, const char *atype)
bool cmp_str3(const char *s1, const char s2[4])
static bool cmp_data(OksData *d, OksData *d2)
#define READ_OBJ_HEADER(F1, S1, F2, S2)
std::ostringstream & add()
std::ostringstream * p_warnings
void add(const OksData &d, const OksRelationship *r)
unsigned int p_warnings_count
Struct OKS data information.
const OksAttribute * attribute
const OksRelationship * relationship
void sort(bool ascending=true)
void SetNullValue(const OksAttribute *a)
void cvt(OksData *to, const OksAttribute *attr) const
Convert data to new type.
union dunedaq::oks::OksData::Data data
void SetValue(const char *s, const OksAttribute *a)
void read(const oks::ReadFileParams &, const OksAttribute *, int32_t)
private methods which can be used by OksObject class only
void SetValues(const char *, const OksAttribute *a)
enum dunedaq::oks::OksData::Type type
void ConvertTo(OksData *, const OksRelationship *) const
void check_range(const OksAttribute *a) const
Check range of data.
void set_init_value(const OksAttribute *attr, bool skip_init)
Set value defined by initial value of attribute.
std::list< OksData *, boost::fast_pool_allocator< OksData * > > List
const OksClass * class_id
The struct OksRCR describes Reverse Composite Relationship (i.e. back reference from child to composi...
OksRCR(OksObject *o, const OksRelationship *r)
const OksRelationship * relationship
ReloadObjects * reload_objects
OksObject::FSet tested_objs
RefData(OksObject::FSet &r, oks::ClassSet *cs)
std::vector< OksObject * > created
OksObject * pop(const OksClass *c, const std::string &id)
struct dunedaq::oks::OksData::Data::@266171337063116272021017117226020166361213322350 UID
const std::string * ENUMERATION
struct dunedaq::oks::OksData::Data::@226266061051241020017305361066131172152317024337 UID2