81 static void remove(
const std::string& path)
84 std::filesystem::remove_all(path);
85 }
catch (std::exception& ex) {
87 <<
"cannot remove user repository \"" << path <<
"\"" << ex.what() << std::endl;
97 void erase(
const std::string& path)
115 return std::string(strerror_r(
error, buffer, 1024));
120 "cannot set group ID " <<
id <<
" for the file \'" << file <<
"\': chown() failed with code " << code
121 <<
" , reason = \'" << why <<
'\'',
122 ((
long)
id)((
const char*)file)((
int)code)((std::string)why))
128 "class \"" << name <<
"\" is defined in files \"" << f1 <<
"\" and \"" << f2 <<
"\"",
129 ((
std::
string)name)((
std::
string)f1)((
std::
string)f2))
134CanNotOpenFile::fill(const
char* prefix, const
std::
string& name, const
std::
string& reason) noexcept
136 std::string result(prefix);
140 return (result +
"file name is empty");
142 result +=
"cannot load file \'" + name +
'\'';
144 if (!reason.empty()) {
145 result +=
" because:\n" + reason;
152FailedLoadFile::fill(
const std::string& what,
const std::string& name,
const std::string& reason)
noexcept
154 return (std::string(
"Failed to load ") + what +
" \"" + name +
"\" because:\n" + reason);
160 return (std::string(
"Failed to re-load file(s) ") + names +
" because:\n" + reason);
166 return (std::string(
"Failed to ") + op +
" file(s) because:\n" + reason);
172 const std::string& name,
173 const std::string& reason)
noexcept
175 return std::string(prefix) +
"(): failed to create new " + what +
" \'" + name +
"\' because:\n" +
reason;
181 return std::string(prefix) +
"(): failed to create user repository dir, mkdtemp(\'" + name +
188 const std::string& name,
189 const std::string& reason)
noexcept
191 return (std::string(prefix) +
"(): failed to write " + item +
" to \'" + name +
"\' because:\n" + reason);
197 return (std::string(
"Failed to make a backup file of \'") + name +
"\' because:\n" + reason);
203 return (std::string(
"Failed to set active ") + item +
" file \'" + name +
"\' because:\n" + reason);
209 std::ostringstream
s;
210 s <<
"Failed to move ";
212 s <<
"class " <<
c->get_name();
215 s <<
" to file \'" <<
file.get_full_file_name() <<
"\' because:\n" <<
reason;
222 return (std::string(
"Cannot add class \'") +
c.get_name() +
"\' because:\n" + reason);
228 std::ostringstream text;
229 text <<
"realpath(\'" << path <<
"\') has failed with code " << error_code <<
": \'" <<
strerror(error_code) <<
'\'';
233static const std::string&
236 static std::string s_dir;
237 static std::once_flag flag;
239 std::call_once(flag, []() {
241 if (!getenv(
"OKS_GIT_NO_VAR_DIR")) {
242 OksSystem::User myself;
244 s_dir =
"/var/run/user/";
245 s_dir.append(std::to_string(myself.
identity()));
247 if (std::filesystem::is_directory(s_dir) ==
false) {
248 TLOG_DEBUG(1) <<
"directory " << s_dir <<
" does not exist";
251 const std::filesystem::space_info si = std::filesystem::space(s_dir);
252 const double available =
static_cast<double>(si.available) /
static_cast<double>(si.capacity);
254 if (available < 0.5) {
255 TLOG_DEBUG(1) <<
"usage of " << s_dir <<
" is " <<
static_cast<int>((1.0 - available) * 100.0)
256 <<
"%, will use standard temporary path";
263 s_dir = std::filesystem::temp_directory_path().string();
264 }
catch (std::exception& ex) {
265 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot get temporary directory path: " << ex.what() << std::endl;
276 return "862f2957270";
282 static std::once_flag flag;
284 std::call_once(flag, []() {
285 if (
const char* s = getenv(
"TDAQ_DB_REPOSITORY")) {
288 if (!std::all_of(rep.begin(), rep.end(), [](
char c) { return std::isspace(c); })) {
289 const char* p = getenv(
"OKS_GIT_PROTOCOL");
299 if (token.find(p) == 0) {
309 <<
"cannot find OKS_GIT_PROTOCOL=\"" << p <<
"\" in TDAQ_DB_REPOSITORY=\"" << rep <<
'\"' << std::endl;
320 static std::once_flag flag;
322 std::call_once(flag, []() {
323 if (
const char* s = getenv(
"OKS_REPOSITORY_MAPPING_DIR")) {
340 if (
const char* s = getenv(
"TDAQ_DB_USER_REPOSITORY")) {
356 TLOG_DEBUG(1) <<
"Failed to set user-repository-root:\n\tcaused by: repository-root is not set";
372 TLOG_DEBUG(1) <<
"Failed to set user-repository-root = \'" << s <<
"\':\n\tcaused by: " << ex.
what();
375 for (std::string::size_type idx = s.size() - 1; idx > 0 && s[idx] ==
'/'; idx--) {
394 static std::string s_host_name;
395 static std::once_flag flag;
397 std::call_once(flag, []() {
400 if (s_host_name.empty())
401 s_host_name =
"unknown.host";
410 static std::string s_domain_name;
411 static std::once_flag flag;
413 std::call_once(flag, []() {
416 if (idx != std::string::npos)
419 if (s_domain_name.empty())
420 s_domain_name =
"unknown.domain";
423 return s_domain_name;
429 static std::string s_user_name;
430 static std::once_flag flag;
432 std::call_once(flag, []() {
436 if (s_user_name.empty())
437 s_user_name =
"unknown.user";
448 long file_length = 0;
452 f.seekg(0, std::ios::end);
455 file_length =
static_cast<std::streamoff
>(f.tellg());
457 file_length = f.tellg();
460 f.seekg(0, std::ios::beg);
468make_fname(
const char* f,
size_t f_len,
const std::string& file,
bool* p,
const OksFile*
const* fh)
470 const char _prefix[] =
"OksKernel::";
471 std::string fname(_prefix, (
sizeof(_prefix) - 1));
473 fname.append(f, f_len);
475 const char _x1[] =
"(file \'";
476 fname.append(_x1, (
sizeof(_x1) - 1));
478 fname.push_back(
'\'');
484 const char _true_str[] =
", true";
485 fname.append(_true_str, (
sizeof(_true_str) - 1));
487 const char _false_str[] =
", false";
488 fname.append(_false_str, (
sizeof(_false_str) - 1));
495 const char _x2[] =
", included by file \'";
496 fname.append(_x2, (
sizeof(_x2) - 1));
497 fname.append((*fh)->get_full_file_name());
498 fname.push_back(
'\'');
501 fname.push_back(
')');
513 std::cerr <<
"ERROR [" << msg <<
"]:\n";
520 std::cerr <<
"WARNING [" << msg <<
"]:\n";
527 std::string::size_type pos = 0;
528 std::string::size_type p_start = 0;
529 std::string::size_type p_end = 0;
531 while (((p_start = s.find(
"$(", pos)) != std::string::npos) &&
532 ((p_end = s.find(
")", p_start + 2)) != std::string::npos)) {
533 std::string var(s, p_start + 2, p_end - p_start - 2);
535 char*
env = getenv(var.c_str());
538 s.replace(p_start, p_end - p_start + 1,
env);
548 char resolved_name[PATH_MAX];
550 if (realpath(path.c_str(), resolved_name) != 0) {
551 path = resolved_name;
555 TLOG_DEBUG(3) <<
"realpath(\'" << path <<
"\') has failed with code " << errno <<
": \'" <<
strerror(errno)
566 "abcdefghijklmnoprstuvwxyz"
567 "ABCDEFGHIJKLMNOPRSTUVWXYZ";
572 static const size_t slen(
sizeof(
symbols) - 1);
573 static const size_t slen2(slen * slen);
575 char b[16], *buf = b;
581 if ((
size_t)
count >= slen) {
584 if ((
size_t)
count >= slen2) {
615 std::ostringstream s;
617 while (j++ < 1000000) {
623 std::ofstream f(s2.c_str(), std::ios::in);
629 std::string s3(file);
642 long size = pathconf(
".", _PC_PATH_MAX);
644 Oks::error_msg(
"OksKernel::OksKernel") <<
"pathconf(\".\", _PC_PATH_MAX) has failed with code " << errno <<
": \'"
645 <<
strerror(errno) <<
'\'' << std::endl;
653 <<
"getcwd() has failed with code " << errno <<
": \'" <<
strerror(errno) <<
'\'' << std::endl;
696 OSK_VERBOSE_REPORT(
"Enter OksKernel::OksKernel(" << sm <<
", " << vm <<
", " << tm <<
')')
698 struct __InitFromEnv__
702 } vars[] = { {
"OKS_KERNEL_VERBOSE",
p_verbose },
711 for (
unsigned int i = 0; i <
sizeof(vars) /
sizeof(__InitFromEnv__); ++i) {
712 if (
char* s = getenv(vars[i].name)) {
713 vars[i].value = (strcmp(s,
"no")) ?
true :
false;
718 const char* oks_db_root = getenv(
"OKS_DB_ROOT");
720 if (oks_db_root ==
nullptr || *oks_db_root == 0)
721 oks_db_root = getenv(
"DUNEDAQ_DB_PATH");
725 OSK_VERBOSE_REPORT(
"database root = \'" << oks_db_root <<
"\' (as defined by the OKS_DB_ROOT or DUNEDAQ_DB_PATH)");
729 if (oks_db_root ==
nullptr)
737 while (t.
next(token))
754 static std::once_flag flag;
756 std::call_once(flag, []() {
757 if (
char* s = getenv(
"OKS_KERNEL_THREADS_POOL_SIZE")) {
769 Oks::error_msg(
"OksKernel::OksKernel()") <<
" sysconf(_SC_NPROCESSORS_ONLN) has failed with code " << errno
770 <<
": \'" <<
strerror(errno) <<
'\'' << std::endl;
786 std::string param, val;
789 version = getenv(
"TDAQ_DB_VERSION");
793 if (
const char* value = strchr(
version,
':')) {
795 val.assign(value + 1);
798 <<
"bad version value \"" <<
version
799 <<
"\" expecting parameter:value format (check TDAQ_DB_VERSION variable)" << std::endl;
810 if (branch_name.empty())
811 if (
const char* var = getenv(
"TDAQ_DB_BRANCH"))
816 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot check out user repository: " << ex.
what() << std::endl;
825 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot read user repository version: " << ex.
what() << std::endl;
876 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot copy user repository: " << ex.
what() << std::endl;
890 const OksFile::Map* src_files[2] = { &src.p_schema_files, &src.p_data_files };
891 OksFile::Map* dst_files[2] = { &p_schema_files, &p_data_files };
893 for (
int i = 0; i < 2; ++i) {
894 for (
const auto& j : *src_files[i]) {
897 (*dst_files[i])[&f->p_full_name] = f;
908 for (
const auto& i : src.p_classes) {
917 p_classes[c->get_name().c_str()] = c;
919 const_cast<OksClass&
>(src_c).p_id = idx++;
920 c->p_id = src_c.p_id;
921 c_table[c->p_id] = c;
923 c->p_abstract = src_c.p_abstract;
924 c->p_to_be_deleted = src_c.p_to_be_deleted;
925 c->p_instance_size = src_c.p_instance_size;
926 c->p_file = (*p_schema_files.find(&src_c.p_file->p_full_name)).second;
927 c->p_objects = (src_c.p_objects ?
new OksObject::Map() : nullptr);
930 if (
const std::list<std::string*>* scls = src_c.p_super_classes) {
931 c->p_super_classes = new std::list<std::string*>();
933 for (const auto& j : *scls)
934 c->p_super_classes->push_back(new std::string(*j));
938 if (
const std::list<OksAttribute*>* attrs = src_c.p_attributes) {
939 c->p_attributes = new std::list<OksAttribute*>();
941 for (const auto& j : *attrs) {
942 OksAttribute* a = new OksAttribute(j->p_name, c);
944 a->p_range = j->p_range;
945 a->p_data_type = j->p_data_type;
946 a->p_multi_values = j->p_multi_values;
947 a->p_no_null = j->p_no_null;
948 a->p_init_value = j->p_init_value;
949 a->p_init_data = j->p_init_data;
950 a->p_format = j->p_format;
951 a->p_description = j->p_description;
953 if (j->p_enumerators)
954 a->p_enumerators = new std::vector<std::string>(*j->p_enumerators);
956 c->p_attributes->push_back(a);
961 if (
const std::list<OksRelationship*>* rels = src_c.p_relationships) {
962 c->p_relationships =
new std::list<OksRelationship*>();
964 for (
const auto& j : *rels) {
967 r->p_rclass = j->p_rclass;
968 r->p_low_cc = j->p_low_cc;
969 r->p_high_cc = j->p_high_cc;
970 r->p_composite = j->p_composite;
971 r->p_exclusive = j->p_exclusive;
972 r->p_dependent = j->p_dependent;
973 r->p_description = j->p_description;
975 c->p_relationships->push_back(r);
980 if (
const std::list<OksMethod*>* mets = src_c.p_methods) {
981 c->p_methods =
new std::list<OksMethod*>();
983 for (
const auto& j : *mets) {
986 if (
const std::list<OksMethodImplementation*>* impls = j->p_implementations) {
987 m->p_implementations =
new std::list<OksMethodImplementation*>();
989 for (
const auto& x : *impls)
990 m->p_implementations->push_back(
994 c->p_methods->push_back(m);
1001 for (
const auto& i : src.p_classes) {
1002 OksClass*
c = c_table[i.second->p_id];
1005 if (
const std::list<OksRelationship*>* rels = i.second->p_relationships) {
1006 for (
const auto& j : *rels)
1007 c->find_relationship(j->get_name())->p_class_type =
1008 (j->p_class_type ? c_table[j->p_class_type->p_id] :
nullptr);
1012 if (
const OksClass::FList* spcls = i.second->p_all_super_classes) {
1013 c->p_all_super_classes =
new OksClass::FList();
1015 for (
const auto& j : *spcls)
1016 c->p_all_super_classes->push_back(c_table[j->p_id]);
1019 if (
const OksClass::FList* sbcls = i.second->p_all_sub_classes) {
1020 c->p_all_sub_classes =
new OksClass::FList();
1022 for (
const auto& j : *sbcls)
1023 c->p_all_sub_classes->push_back(c_table[j->p_id]);
1027 c->p_data_info =
new OksDataInfo::Map();
1028 size_t instance_size = 0;
1031 if (
const std::list<OksAttribute*>* attrs = i.second->p_all_attributes) {
1032 c->p_all_attributes =
new std::list<OksAttribute*>();
1034 for (
const auto& j : *attrs) {
1035 OksAttribute* a = (c_table[j->p_class->p_id])->find_direct_attribute(j->get_name());
1036 c->p_all_attributes->push_back(a);
1037 (*
c->p_data_info)[a->get_name()] =
new OksDataInfo(instance_size++, a);
1042 if (
const std::list<OksRelationship*>* rels = i.second->p_all_relationships) {
1043 c->p_all_relationships =
new std::list<OksRelationship*>();
1045 for (
const auto& j : *rels) {
1046 OksRelationship*
r = (c_table[j->p_class->p_id])->find_direct_relationship(j->get_name());
1047 c->p_all_relationships->push_back(r);
1048 (*
c->p_data_info)[
r->get_name()] =
new OksDataInfo(instance_size++, r);
1053 if (
const std::list<OksMethod*>* mets = i.second->p_all_methods) {
1054 c->p_all_methods =
new std::list<OksMethod*>();
1056 for (
const auto& j : *mets)
1057 c->p_all_methods->push_back((c_table[j->p_class->p_id])->find_direct_method(j->get_name()));
1061 if (
const std::vector<OksClass*>* ih = i.second->p_inheritance_hierarchy) {
1062 c->p_inheritance_hierarchy =
new std::vector<OksClass*>();
1063 c->p_inheritance_hierarchy->reserve(ih->size());
1065 for (
const auto& j : *ih)
1066 c->p_inheritance_hierarchy->push_back(c_table[j->p_id]);
1072 if (!src.p_objects.empty()) {
1077 OksObject** o_table =
new OksObject*[src.p_objects.size()];
1082 for (OksObject::Set::const_iterator i = src.p_objects.begin(); i != src.p_objects.end(); ++i, ++idx) {
1083 OksObject* src_o(*i);
1084 src_o->p_user_data =
reinterpret_cast<void*
>(idx);
1086 OksClass*
c = c_table[src_o->uid.class_id->p_id];
1088 OksObject* o =
new OksObject(c,
1089 src_o->uid.object_id,
1092 src_o->p_duplicated_object_id_idx,
1093 (*p_data_files.find(&src_o->file->p_full_name)).second);
1096 (*
c->p_objects)[&o->uid.object_id] = o;
1097 p_objects.insert(o);
1099 if (
size_t num_of_attrs =
c->number_of_all_attributes()) {
1100 const OksData* src_data = src_o->data;
1101 OksData* dst_data = o->data;
1103 std::list<OksAttribute*>::const_iterator ia_dst =
c->all_attributes()->begin();
1104 std::list<OksAttribute*>::const_iterator ia_src = src_o->uid.class_id->all_attributes()->begin();
1106 for (
size_t j = 0; j < num_of_attrs; ++j) {
1107 *dst_data = *src_data;
1109 OksAttribute* a_dst(*ia_dst);
1113 if (a_dst->get_data_type() == OksData::class_type) {
1114 if (a_dst->get_is_multi_values() ==
false) {
1115 dst_data->data.CLASS = c_table[src_data->data.CLASS->p_id];
1117 OksData::List::iterator li_dst = dst_data->data.LIST->begin();
1118 OksData::List::iterator li_src = src_data->data.LIST->begin();
1120 while (li_dst != dst_data->data.LIST->end()) {
1121 (*li_dst)->data.CLASS = c_table[(*li_src)->data.CLASS->p_id];
1130 else if (a_dst->get_data_type() == OksData::enum_type) {
1131 OksAttribute* a_src(*ia_src);
1132 const std::string* p_enumerators_first(&((*(a_src->p_enumerators))[0]));
1134 if (a_dst->get_is_multi_values() ==
false) {
1135 unsigned long dx = src_data->data.ENUMERATION - p_enumerators_first;
1136 dst_data->data.ENUMERATION = &((*(a_dst->p_enumerators))[dx]);
1138 OksData::List::iterator li_dst = dst_data->data.LIST->begin();
1139 OksData::List::iterator li_src = src_data->data.LIST->begin();
1141 while (li_dst != dst_data->data.LIST->end()) {
1142 unsigned long dx = (*li_src)->data.ENUMERATION - p_enumerators_first;
1143 (*li_dst)->data.ENUMERATION = &((*(a_dst->p_enumerators))[dx]);
1161 for (
const auto& src_o : src.p_objects) {
1162 OksClass*
c = c_table[src_o->uid.class_id->p_id];
1163 OksObject* o(o_table[
reinterpret_cast<unsigned long>(src_o->p_user_data)]);
1165 if (
size_t num_of_rels =
c->number_of_all_relationships()) {
1166 const OksData* src_data(src_o->data +
c->number_of_all_attributes());
1167 OksData* dst_data(o->data +
c->number_of_all_attributes());
1169 for (
size_t j = 0; j < num_of_rels; ++j) {
1170 dst_data->type = src_data->type;
1171 switch (src_data->type) {
1172 case OksData::list_type:
1173 dst_data->data.LIST =
new OksData::List();
1174 for (
const auto& x : *src_data->data.LIST) {
1175 OksData*
d =
new OksData();
1177 if (x->type == OksData::object_type) {
1178 if (
const OksObject* o2 = x->data.OBJECT) {
1179 d->Set(o_table[
reinterpret_cast<unsigned long>(o2->p_user_data)]);
1181 d->Set((OksObject*)
nullptr);
1183 }
else if (x->type == OksData::uid_type) {
1184 d->Set(c_table[x->data.UID.class_id->p_id], *x->data.UID.object_id);
1185 }
else if (x->type == OksData::uid2_type) {
1186 d->Set(*x->data.UID2.class_id, *x->data.UID2.object_id);
1188 ers::error(kernel::InternalError(
ERS_HERE,
"unexpected data type in relationship list"));
1191 dst_data->data.LIST->push_back(d);
1195 case OksData::object_type:
1196 if (
const OksObject* o2 = src_data->data.OBJECT) {
1197 dst_data->data.OBJECT = o_table[
reinterpret_cast<unsigned long>(o2->p_user_data)];
1199 dst_data->data.OBJECT = 0;
1203 case OksData::uid_type:
1204 dst_data->data.UID.class_id = c_table[src_data->data.UID.class_id->p_id];
1205 dst_data->data.UID.object_id =
new OksString(*src_data->data.UID.object_id);
1208 case OksData::uid2_type:
1209 dst_data->data.UID2.class_id =
new OksString(*src_data->data.UID2.class_id);
1210 dst_data->data.UID2.object_id =
new OksString(*src_data->data.UID2.object_id);
1223 if (
const std::list<OksRCR*>* src_rcrs = src_o->p_rcr) {
1224 o->p_rcr =
new std::list<OksRCR*>();
1226 for (
const auto& j : *src_rcrs)
1227 o->p_rcr->push_back(
new OksRCR(
1228 o_table[
reinterpret_cast<unsigned long>(j->obj->p_user_data)],
1229 (c_table[j->relationship->p_class->p_id])->find_direct_relationship(j->relationship->get_name())));
1241 if (copy_repository && p_user_repository_root_inited) {
1242 OksFile::Map* files_map[2] = { &p_schema_files, &p_data_files };
1244 for (
int i = 0; i < 2; ++i) {
1245 std::vector<OksFile*> files;
1247 for (
auto& f : *files_map[i])
1248 files.push_back(
f.second);
1250 files_map[i]->clear();
1252 for (
auto& f : files) {
1253 std::string name = p_user_repository_root;
1254 name.push_back(
'/');
1255 name.append(
f->get_repository_name());
1257 (*files_map[i])[&
f->p_full_name] = f;
1280 std::cout <<
" * push " << (push_back ?
"back" :
"front") <<
" repository search directory \'" << s <<
"\'\n";
1285 TLOG_DEBUG(1) <<
"Cannot insert repository dir \'" << dir <<
"\':\n\tcaused by: " << ex;
1299 std::cout <<
" * remove repository search directory \'" << dir <<
"\'\n";
1352 std::cout << *
profiler << std::endl;
1363 s <<
"OKS KERNEL DUMP:\n" <<
"OKS VERSION: " << k.
GetVersion() << std::endl;
1366 s <<
" Loaded schema:\n";
1369 s <<
" " << i.second->get_full_file_name() << std::endl;
1372 s <<
" Loaded data:\n";
1375 s <<
" " << j.second->get_full_file_name() << std::endl;
1377 s <<
" No loaded data files\n";
1380 s <<
" The classes:\n";
1386 s <<
" No loaded schema files\n";
1388 s <<
"END OF OKS KERNEL DUMP.\n";
1396 static std::string suffix;
1397 static std::once_flag flag;
1399 std::call_once(flag, []() {
1400 std::ostringstream s;
1409 static std::mutex p_check_read_only_mutex;
1410 std::lock_guard scoped_lock(p_check_read_only_mutex);
1413 std::ofstream f(s.c_str(), std::ios::out);
1433 std::shared_ptr<std::ifstream> f(
new std::ifstream(full_path.c_str()));
1437 file_h =
new OksFile(xmls, short_path, full_path,
this);
1459 bool file_exists =
false;
1463 if (stat(file_name.c_str(), &buf) == 0) {
1465 Oks::warning_msg(fname) <<
" File \"" << file_name <<
"\" already exists\n";
1474 std::ofstream f(file_name.c_str());
1479 throw std::runtime_error(
"cannot open file in write mode");
1481 throw std::runtime_error(
"cannot create file");
1488 std::cout <<
"Creating new " << msg <<
" file \"" << file_name <<
"\"..." << std::endl;
1494 const char _s1_str[] =
" - \'";
1495 const char _s2_str[] =
"\' tested as ";
1497 return ((std::string(_s1_str,
sizeof(_s1_str) - 1) + name).append(_s2_str,
sizeof(_s2_str) - 1))
1498 .append(test, test_len);
1501#define TEST_PATH_TOKEN(path, file, msg) \
1502 std::string token(path); \
1503 token.push_back('/'); \
1504 token.append(file); \
1505 Oks::substitute_variables(token); \
1506 if (Oks::real_path(token, true)) { \
1507 TLOG_DEBUG(2) << fname << " returns \'" << token << "\' (filename relative to " << msg \
1508 << " database repository directory)"; \
1511 const char _test_name[] = "relative to database repository directory"; \
1512 tested_files.push_back(mk_name_and_test(token, _test_name, sizeof(_test_name) - 1)); \
1520 const char _fname[] =
"get_file_path";
1525 std::list<std::string> tested_files;
1528 bool is_absolute_path =
false;
1532 fname =
make_fname(_fname,
sizeof(_fname) - 1, s2,
nullptr, &file_h);
1536 is_absolute_path =
true;
1539 if (is_absolute_path || file_h == 0) {
1541 std::string s3 =
s_cwd;
1553 TLOG_DEBUG(2) << fname <<
" returns external \'" << s2 <<
"\' (an absolute filename or relative to CWD=\'"
1558 std::ostringstream text;
1560 <<
" file does not belong to oks git repository\n"
1561 "provide file repository name, or unset TDAQ_DB_REPOSITORY and try again with the DUNEDAQ_DB_PATH "
1562 "environment variable";
1563 throw std::runtime_error(text.str().c_str());
1565 TLOG_DEBUG(2) << fname <<
" returns \'" << s2 <<
"\' (an absolute filename or relative to CWD=\'" <<
s_cwd
1570 if (is_absolute_path) {
1571 const char _test_name[] =
"an absolute file name";
1572 tested_files.push_back(
mk_name_and_test(s2, _test_name,
sizeof(_test_name) - 1));
1574 const char _test_name[] =
"relative to current working directory";
1575 tested_files.push_back(
mk_name_and_test(s2, _test_name,
sizeof(_test_name) - 1));
1586 if (!is_absolute_path)
1592 if (file_h && !is_absolute_path) {
1594 std::string::size_type pos = s2.find_last_of(
'/');
1596 if (pos != std::string::npos) {
1602 TLOG_DEBUG(2) << fname <<
" returns \'" << s2 <<
"\' (filename relative to parent file)";
1605 const char _test_name[] =
"relative to parent file";
1606 tested_files.push_back(
mk_name_and_test(s2, _test_name,
sizeof(_test_name) - 1));
1612 TLOG_DEBUG(2) << fname <<
" throw exception (file was not found)";
1614 std::ostringstream text;
1615 text << fname <<
" found no readable file among " << tested_files.size() <<
" tested:\n";
1616 for (
auto& i : tested_files)
1617 text << i << std::endl;
1619 throw std::runtime_error(text.str().c_str());
1636 const char _fname[] =
"k_load_file";
1637 std::string fname =
make_fname(_fname,
sizeof(_fname) - 1, short_file_name, &bind, &parent_h);
1641 std::string full_file_name;
1645 }
catch (std::exception& e) {
1653 OksFile::Map::const_iterator i =
p_schema_files.find(&full_file_name);
1655 return i->second->check_parent(parent_h);
1659 return i->second->check_parent(parent_h);
1661 std::shared_ptr<std::ifstream> f(
new std::ifstream(full_file_name.c_str()));
1667 throw std::runtime_error(
"k_load_file(): file is empty");
1674 OksFile* file_h =
new OksFile(xmls, short_file_name, full_file_name,
this);
1689 throw std::runtime_error(
"k_load_file(): failed to parse header");
1692 k_load_data(file_h, format, xmls, file_length, bind, parent_h, pipeline);
1699 throw std::runtime_error(
"k_load_file(): cannot open file");
1703 }
catch (std::exception& e) {
1706 throw FailedLoadFile(
"file", full_file_name,
"caught unknown exception");
1713 for (std::list<std::string>::const_iterator i = f.p_list_of_include_files.begin();
1714 i != f.p_list_of_include_files.end();
1716 if (!(*i).empty()) {
1719 if ((*i)[0] ==
'/') {
1722 "inclusion of files with absolute pathname (like \"/foo/bar\") is not allowed by "
1723 "repository files; include files relative to repository root (like \"foo/bar\")");
1724 }
else if ((*i)[0] ==
'.') {
1728 "inclusion of files with file-related relative pathnames (like \"../foo/bar\" or \"./bar\") is not "
1729 "supported by repository files; include files relative to repository root (like \"foo/bar\")");
1730 }
else if ((*i).find(
'/') == std::string::npos) {
1733 "inclusion of files with file-related local pathnames (like \"bar\") is not supported "
1734 "by repository files; include files relative to repository root (like \"foo/bar\")");
1742 }
catch (std::exception& e) {
1755 std::shared_ptr<std::ifstream> f(
new std::ifstream(file_name.c_str()));
1758 throw std::runtime_error(
"get_includes(): cannot open file");
1762 OksFile fp(xmls, file_name, file_name,
this);
1776 }
catch (std::exception& e) {
1787 if (includes.find(file) != includes.end()) {
1788 if (file->p_included_by != parent) {
1790 file->p_included_by = parent;
1807 for (std::list<std::string>::const_iterator x = i->second->p_list_of_include_files.begin();
1808 x != i->second->p_list_of_include_files.end();
1813 igraph[i->second].insert(it->second);
1815 std::cerr <<
"cannot find schema " << *x <<
" included by " << i->second->get_full_file_name() << std::endl;
1821 for (std::list<std::string>::const_iterator x = i->second->p_list_of_include_files.begin();
1822 x != i->second->p_list_of_include_files.end();
1825 OksFile::Map::const_iterator it =
p_data_files.find(&f);
1827 igraph[i->second].insert(it->second);
1832 igraph[i->second].insert(it->second);
1834 std::cerr <<
"cannot find file " << *x <<
" included by " << i->second->get_full_file_name() << std::endl;
1848 std::list<OksFile*> to_be_closed[2];
1850 for (
int c = 0; c < 2; ++c) {
1851 for (OksFile::Map::iterator i = files[c]->begin(); i != files[c]->end(); ++i) {
1852 if (
OksFile* p =
const_cast<OksFile*
>(i->second->p_included_by)) {
1853 bool found_parent =
false;
1857 if (igraph.find(p) != igraph.end()) {
1858 OksFile::IMap::iterator j = igraph.find(p);
1864 TLOG_DEBUG(1) <<
"the parent of file " << i->second->get_full_file_name() <<
" is not valid";
1868 for (OksFile::IMap::iterator j = igraph.begin(); j != igraph.end(); ++j) {
1870 found_parent =
true;
1875 if (found_parent ==
false) {
1876 TLOG_DEBUG(1) <<
"the file " << i->second->get_full_file_name()
1877 <<
" is not included by any other file and will be closed";
1878 to_be_closed[c].push_back(i->second);
1886 for (std::list<OksFile*>::const_iterator i = to_be_closed[1].begin(); i != to_be_closed[1].end(); ++i) {
1887 num += (*i)->p_list_of_include_files.size();
1892 for (std::list<OksFile*>::const_iterator i = to_be_closed[0].begin(); i != to_be_closed[0].end(); ++i) {
1893 num += (*i)->p_list_of_include_files.size();
1899 TLOG_DEBUG(1) <<
"go into recursive call, number of potentially closed includes is " << num;
1907 TLOG_DEBUG(1) <<
"rebuild classes since number of schema files has been changed from " << num_of_schema_files
1916 bool found_include_changes(
false);
1919 std::shared_ptr<std::ifstream> file(
new std::ifstream(fp->
get_full_file_name().c_str()));
1921 if (!file->good()) {
1922 throw std::runtime_error(std::string(
"k_preload_includes(): cannot open file \"") + fp->
get_full_file_name() +
1928 std::set<std::string> included;
1934 included.insert(*i);
1940 file->seekg(0, std::ios::end);
1942 long file_length =
static_cast<std::streamoff
>(file->tellg());
1944 if (file_length == 0) {
1945 throw std::runtime_error(std::string(
"k_preload_includes(): file \"") + fp->
get_full_file_name() +
"\" is empty");
1948 file->seekg(0, std::ios::beg);
1959 throw std::runtime_error(std::string(
"k_preload_includes(): failed to read header of file \"") +
1965 throw std::runtime_error(std::string(
"k_preload_includes(): file \"") + fp->
get_full_file_name() +
1966 "\" is not valid oks file");
1974 found_include_changes =
true;
1979 std::set<std::string>::const_iterator x = included.find(*i);
1980 if (x != included.end()) {
1981 TLOG_DEBUG(3) <<
"include \'" << *i <<
"\' already exists, skip...";
1986 found_include_changes =
true;
1988 std::string full_file_name;
1992 }
catch (std::exception& e) {
1996 OksFile::Map::const_iterator j =
p_schema_files.find(&full_file_name);
1998 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is already loaded schema file \'" << j->first <<
'\'';
2004 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is already loaded data file \'" << j->first <<
'\'';
2009 if (f->p_oks_format ==
"schema") {
2010 std::string new_schema_full_file_name = f->get_full_file_name();
2013 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is a schema file, that was already loaded";
2016 if (allow_schema_extension) {
2017 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is new schema file, loading...";
2021 std::ostringstream text;
2022 text <<
"k_preload_includes(): include of new schema file (\'" << *i
2023 <<
"\') is not allowed on data reload";
2024 throw std::runtime_error(text.str().c_str());
2027 }
else if (f->p_oks_format ==
"data" || f->p_oks_format ==
"extended" || f->p_oks_format ==
"compact") {
2028 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is new data file, pre-loading...";
2031 new_files_h.insert(f);
2032 f->p_list_of_include_files.clear();
2034 found_include_changes =
true;
2035 f->p_included_by = fp;
2036 f->update_status_of_file();
2039 std::ostringstream text;
2040 text <<
"k_preload_includes(): failed to parse header of included \'" << full_file_name <<
"\' file";
2041 throw std::runtime_error(text.str().c_str());
2044 throw std::runtime_error(
"k_load_file(): cannot open file");
2051 }
catch (std::exception& e) {
2055 return found_include_changes;
2063 if (
const char* path = getenv(
"TDAQ_DB_USER_REPOSITORY_PATH"))
2067 std::string user_repo;
2069 if (
const char* user_repo_base = getenv(
"TDAQ_DB_USER_REPOSITORY_ROOT"))
2070 user_repo = user_repo_base;
2072 user_repo = get_temporary_dir();
2074 user_repo.push_back(
'/');
2075 if (
const char* user_repo_pattern = getenv(
"TDAQ_DB_USER_REPOSITORY_PATTERN"))
2076 user_repo.append(user_repo_pattern);
2078 user_repo.append(
"oks.XXXXXX");
2080 std::unique_ptr<char[]> dir_template(
new char[user_repo.size() + 1]);
2081 strcpy(dir_template.get(), user_repo.c_str());
2083 if (
char* tmp_dirname = mkdtemp(dir_template.get())) {
2095 OksFile::Map::const_iterator i = files.find(&at);
2096 if (i != files.end())
2103 for (
const auto& f : files) {
2104 if (s == f.second->get_short_file_name()) {
2140 const char _fname[] =
"k_load_schema";
2141 std::string fname =
make_fname(_fname,
sizeof(_fname) - 1, short_file_name,
nullptr, &parent_h);
2145 std::string full_file_name;
2149 }
catch (std::exception& e) {
2150 throw CanNotOpenFile(
"k_load_schema", short_file_name, e.what());
2165 std::shared_ptr<std::ifstream> f(
new std::ifstream(full_file_name.c_str()));
2168 throw std::runtime_error(
"k_load_schema(): cannot open file");
2173 fp =
new OksFile(xmls, short_file_name, full_file_name,
this);
2176 throw std::runtime_error(
"k_load_schema(): failed to read header of file");
2178 throw std::runtime_error(
"k_load_schema(): file is not oks schema file");
2191 }
catch (std::exception& e) {
2194 throw FailedLoadFile(
"schema file", full_file_name,
"caught unknown exception");
2209 std::cout << (parent_h ?
" * loading " :
"Loading ") << fp->
p_number_of_items <<
" classes from file \""
2212 std::cout <<
"(non-fully-qualified filename was \"" << fp->
get_short_file_name() <<
"\")\n";
2220 std::list<OksClass*> set;
2232 if (c->get_name().empty()) {
2233 throw std::runtime_error(
"k_load_schema(): failed to read a class");
2236 OksClass::Map::const_iterator ic =
p_classes.find(c->get_name().c_str());
2238 bool are_different = (*ic->second != *c);
2240 c->p_transient =
true;
2244 static bool ers_report = (getenv(
"OKS_KERNEL_ERS_REPORT_DUPLICATED_CLASSES") !=
nullptr);
2249 const char _fname[] =
"k_load_schema";
2252 <<
" Class \"" << c->get_name() <<
"\" was already loaded from file \'"
2253 << c->get_file()->get_full_file_name() <<
"\'\n";
2256 std::stringstream text;
2257 text << (are_different ?
"different " :
"") <<
"class \"" << c->get_name()
2258 <<
"\" was already loaded from file \'" << c->get_file()->get_full_file_name() <<
'\'';
2259 throw std::runtime_error(text.str().c_str());
2272 fp->
p_size = xmls->get_position();
2277 for (std::list<OksClass*>::iterator i2 = set.begin(); i2 != set.end(); ++i2)
2278 (*OksClass::create_notify_fn)(*i2);
2281 std::set<OksClass*> set2;
2283 for (std::list<OksClass*>::iterator i2 = set.begin(); i2 != set.end(); ++i2) {
2285 if (c->p_all_sub_classes && !c->p_all_sub_classes->empty()) {
2286 for (OksClass::FList::iterator i3 = c->p_all_sub_classes->begin(); i3 != c->p_all_sub_classes->end(); ++i3) {
2287 if (set2.find(*i3) == set2.end()) {
2299 }
catch (std::exception& e) {
2309 const char _fname[] =
"new_schema";
2310 std::string fname =
make_fname(_fname,
sizeof(_fname) - 1, s,
nullptr,
nullptr);
2317 std::string file_name(s);
2330 throw std::runtime_error(
"the file is already loaded");
2333 OksFile* file_h =
new OksFile(file_name,
"",
"",
"schema",
this);
2343 }
catch (std::exception& e) {
2346 throw CanNotCreateFile(
"new_schema",
"schema file", file_name,
"caught unknown exception");
2383 std::cout <<
"Making backup of schema file \"" << pf->
p_full_name <<
"\"...\n";
2405 const char _fname[] =
"k_save_schema";
2411 std::string tmp_file_name;
2426 size_t numberOfClasses = 0;
2429 numberOfClasses =
classes->size();
2432 if (i->second->p_file == fh)
2442 std::ofstream f(tmp_file_name.c_str());
2443 f.exceptions(std::ostream::failbit | std::ostream::badbit);
2446 std::ostringstream text;
2447 text <<
"cannot create temporal file \'" << tmp_file_name <<
"\' to save schema";
2448 throw std::runtime_error(text.str().c_str());
2451 std::cout <<
"Saving " << numberOfClasses <<
" classes to schema file \"" << pf->
p_full_name <<
"\"...\n";
2465 std::ostringstream errors;
2466 bool found_errors =
false;
2470 found_errors |= i.second->check_relationships(errors,
false);
2471 i.second->save(xmls);
2475 if (i.second->p_file == fh) {
2476 found_errors |= i.second->check_relationships(errors,
false);
2477 i.second->save(xmls);
2483 kernel::BindError ex(
ERS_HERE, errors.str());
2485 if (force ==
false) {
2486 throw std::runtime_error(ex.what());
2494 xmls.
put_last_tag(
"oks-schema",
sizeof(
"oks-schema") - 1);
2501 if (rename(tmp_file_name.c_str(), pf->
p_full_name.c_str())) {
2502 std::ostringstream text;
2503 text <<
"cannot rename \'" << tmp_file_name <<
"\' to \'" << pf->
p_full_name <<
'\'';
2504 throw std::runtime_error(text.str().c_str());
2507 tmp_file_name.erase(0);
2513 throw std::runtime_error(ex.
what());
2526 if (!tmp_file_name.empty()) {
2527 unlink(tmp_file_name.c_str());
2530 }
catch (std::exception& ex) {
2537 if (!tmp_file_name.empty()) {
2538 unlink(tmp_file_name.c_str());
2553 pf->
rename(short_name, long_name);
2560 const char _fname[] =
"save_as_schema";
2561 std::string fname =
make_fname(_fname,
sizeof(_fname) - 1, new_name,
nullptr, &pf);
2566 if (!new_name.length()) {
2567 throw std::runtime_error(
"the new filename is empty");
2586 }
catch (std::exception& ex) {
2605 TLOG_DEBUG(2) <<
"skip read-only schema file \'" << *(i->first) <<
'\'';
2646 std::cout << (pf->
p_included_by ?
" * c" :
"C") <<
"lose OKS schema \"" << pf->
p_full_name <<
"\"..." << std::endl;
2658 std::set<OksClass*> sorted;
2662 if (pf == c->p_file)
2664 c->p_to_be_deleted =
true;
2667 for (std::set<OksClass*>::iterator j = sorted.begin(); j != sorted.end(); ++j) {
2675 TLOG_DEBUG(4) <<
"exit for file " << (
void*)pf;
2687 i->second->p_to_be_deleted =
true;
2708 TLOG_DEBUG(4) <<
"enter for file " << (
void*)f;
2739 TLOG_DEBUG(4) <<
"exit for file " << (
void*)f;
2742std::list<OksClass*>*
2745 std::string fname(
"OksKernel::create_list_of_schema_classes(");
2747 fname.push_back(
'\'');
2752 std::list<OksClass*>* clist =
nullptr;
2755 for (OksClass::Map::const_iterator i =
p_classes.begin(); i !=
p_classes.end(); ++i) {
2756 if (pf == i->second->p_file) {
2757 if (!clist && !(clist =
new std::list<OksClass*>())) {
2761 clist->push_back(i->second);
2775 std::list<OksFile*>** ufs,
2776 std::list<OksFile*>** rfs,
2783 for (OksFile::Map::const_iterator i = files.begin(); i != files.end(); ++i) {
2788 *ufs =
new std::list<OksFile*>();
2790 (*ufs)->push_back(i->second);
2791 }
else if (fs == wr ) {
2793 *rfs =
new std::list<OksFile*>();
2795 (*rfs)->push_back(i->second);
2819 std::list<OksFile*>* files[] = {
nullptr,
nullptr,
nullptr,
nullptr };
2821 std::set<OksFile*>* sets[] = { &mfs, &rfs };
2826 for (
int i = 0; i < 4; ++i)
2827 if (std::list<OksFile*>* f = files[i]) {
2828 while (!f->empty()) {
2829 sets[i % 2]->insert(f->front());
2850 if (parents.insert(file).second ==
false) {
2851 text +=
"(ignoring circular dependency between included files...)\n";
2855 text += file->get_full_file_name();
2856 text +=
"\' includes:\n";
2865 std::set<const OksFile*> parents;
2868 bool has_no_parents(text.empty());
2871 text += file.get_full_file_name();
2872 text += (has_no_parents ?
"\' has problem:\n" :
"\' that has problem:\n");
2875 std::lock_guard lock(
p_mutex);
2882 std::lock_guard lock(
p_mutex);
2885 std::ostringstream s;
2888 s <<
"Found 1 error parsing OKS data:\n" << *
m_errors.begin();
2890 s <<
"Found " <<
m_errors.size() <<
" errors parsing OKS data:";
2892 for (std::list<std::string>::const_iterator i =
m_errors.begin(); i !=
m_errors.end(); ++i) {
2893 s <<
"\nERROR [" << j++ <<
"] ***: " << *i;
2921 m_fp->p_number_of_items = 0;
2925 m_fp->p_number_of_items++;
2933 }
catch (std::exception& ex) {
2956 for (OksFile::Map::const_iterator i = files.begin(); i != files.end(); ++i) {
2969 (*c)[o->
GetId()] = o;
2975 std::map<const OksClass*, map_str_t<OksObject*>*>::iterator i =
data.find(c);
2976 if (i !=
data.end()) {
2978 if (j != i->second->end()) {
2980 i->second->erase(j);
2981 if (i->second->empty()) {
3002 std::map<OksFile*, std::vector<std::string>> included;
3004 std::set<OksFile*>::const_iterator i;
3006 bool check_includes(
false);
3007 bool found_schema_files(
false);
3008 std::string file_names;
3012 for (std::set<OksFile*>::const_iterator fi = files_h.begin(); fi != files_h.end();) {
3014 found_schema_files =
true;
3017 <<
"file " << (
void*)(*fi) <<
" is not OKS data or schema file, skip..." << std::endl;
3018 files_h.erase(fi++);
3022 if (fi != files_h.begin())
3023 file_names.append(
", ");
3024 file_names.push_back(
'\"');
3025 file_names.append((*fi)->get_full_file_name());
3026 file_names.push_back(
'\"');
3034 if (found_schema_files) {
3035 throw std::runtime_error(
"Reload of modified schema files is not supported");
3040 if (files_h.empty())
3048 for (i = files_h.begin(); i != files_h.end(); ++i) {
3049 if ((*i)->is_locked()) {
3056 for (OksObject::Set::const_iterator oi =
p_objects.begin(); oi !=
p_objects.end(); ++oi) {
3057 if ((*oi)->file == *i)
3058 reload_objects.
put(*oi);
3065 std::set<OksFile*> new_files;
3067 for (i = files_h.begin(); i != files_h.end(); ++i) {
3078 if (!new_files.empty()) {
3079 TLOG_DEBUG(2) << new_files.size() <<
" new files will be loaded";
3082 for (i = new_files.begin(); i != new_files.end(); ++i) {
3091 std::set<OksFile*> files_to_be_closed;
3093 if (check_includes) {
3094 size_t num_of_closing_files = 0;
3101 std::map<std::string, OksFile*> good_files;
3104 if (files_to_be_closed.find(j->second) == files_to_be_closed.end()) {
3105 for (std::list<std::string>::iterator l = j->second->p_list_of_include_files.begin();
3106 l != j->second->p_list_of_include_files.end();
3117 if (i->second->p_included_by && files_to_be_closed.find(i->second) == files_to_be_closed.end()) {
3118 TLOG_DEBUG(3) <<
"check the file \'" << i->second->get_full_file_name() <<
"\' is included";
3119 const std::string& s = i->second->get_full_file_name();
3127 std::map<std::string, OksFile*>::const_iterator j = good_files.find(s);
3129 if (j != good_files.end()) {
3132 files_to_be_closed.insert(f2);
3134 for (OksObject::Set::const_iterator oi =
p_objects.begin(); oi !=
p_objects.end(); ++oi) {
3135 if ((*oi)->file == f2) {
3136 reload_objects.
put(*oi);
3140 if (files_h.erase(f2)) {
3142 <<
" since it will be closed";
3152 if (num_of_closing_files == files_to_be_closed.size()) {
3155 num_of_closing_files = files_to_be_closed.size();
3159 TLOG_DEBUG(2) <<
"no changes in the list of includes";
3166 cx != reload_objects.
data.end();
3169 if (c->p_all_relationships && !c->p_all_relationships->empty()) {
3170 const unsigned int atts_num(c->number_of_all_attributes());
3175 for (std::list<OksRelationship*>::iterator i = c->p_all_relationships->begin();
3176 i != c->p_all_relationships->end();
3179 if (r->get_is_composite() && r->get_is_exclusive()) {
3182 d->data.OBJECT->remove_RCR(
obj, r);
3185 for (OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
3209 for (i = files_h.begin(); i != files_h.end(); ++i) {
3210 std::shared_ptr<std::ifstream> f(
new std::ifstream((*i)->get_full_file_name().c_str()));
3214 OksFile fp(xmls, (*i)->get_short_file_name(), (*i)->get_full_file_name(),
this);
3219 std::cout <<
" * reading data file \"" << (*i)->get_full_file_name() <<
"\"..." << std::endl;
3224 ReadFileParams read_params(*i, *xmls, ((format ==
'X') ? 0 : &alias_table),
this, format, &reload_objects);
3236 (*i)->update_status_of_file();
3237 (*i)->p_is_updated =
false;
3248 cx != reload_objects.
data.end();
3251 oset.insert(ox->second);
3257 std::ostringstream text;
3258 text <<
"there are " << oset.size() <<
" removed objects:\n";
3260 for (OksObject::FSet::iterator x = oset.begin(); x != oset.end(); ++x) {
3261 text <<
" - object " << *x << std::endl;
3271 for (OksObject::FSet::const_iterator x2 = refs.begin(); x2 != refs.end(); ++x2) {
3272 TLOG_DEBUG(3) <<
"*** add object " << *x2 <<
" to the list of updated *** ";
3279 for (OksObject::FSet::iterator ox = oset.begin(); ox != oset.end(); ++ox) {
3283 TLOG_DEBUG(4) <<
"skip dangling object " << (
void*)o;
3287 TLOG_DEBUG(3) <<
"*** remove non-reloaded object " << o <<
" => " << (
void*)o <<
" ***";
3292 for (std::set<OksFile*>::const_iterator x = files_to_be_closed.begin(); x != files_to_be_closed.end(); ++x) {
3300 if (duplicated_objs_mode ==
true) {
3301 for (
auto& o : reload_objects.
created) {
3307 }
catch (std::exception& e) {
3328 TLOG_DEBUG(1) <<
"remove file " << (*j)->get_full_file_name();
3336 TLOG_DEBUG(1) <<
"restore file " << i->second->get_full_file_name();
3337 (*i->second) = (*j->second);
3358 const char _fname[] =
"k_load_data";
3359 std::string fname =
make_fname(_fname,
sizeof(_fname) - 1, short_file_name, &bind, &parent_h);
3363 std::string full_file_name;
3367 }
catch (std::exception& e) {
3378 Oks::warning_msg(fname) <<
" The file \'" << full_file_name <<
"\' was already loaded";
3384 std::shared_ptr<std::ifstream> f(
new std::ifstream(full_file_name.c_str()));
3387 throw std::runtime_error(
"k_load_data(): cannot open file");
3393 throw std::runtime_error(
"k_load_data(): file is empty");
3398 fp =
new OksFile(xmls, short_file_name, full_file_name,
this);
3401 throw std::runtime_error(
"k_load_data(): failed to read header of file");
3413 throw std::runtime_error(
"k_load_data(): file is not an oks data file");
3416 k_load_data(fp, format, xmls, file_length, bind, parent_h, pipeline);
3426 }
catch (std::exception& e) {
3434 std::shared_ptr<OksXmlInputStream> xmls,
3448 std::cout << (parent_h ?
" * r" :
"R") <<
"eading data file \"" << fp->
get_full_file_name() <<
"\" in "
3449 << (format ==
'n' ?
"normal" : (format ==
'X' ?
"extended" :
"compact")) <<
" format (" << file_length
3452 std::cout <<
"(non-fully-qualified filename was \"" << fp->
get_short_file_name() <<
"\")\n";
3465 m_pipeline = pipeline;
3467 m_pipeline = pipeline_guard.get();
3494 }
catch (std::exception& e) {
3502 const char _fname[] =
"new_data";
3503 std::string fname =
make_fname(_fname,
sizeof(_fname) - 1, s,
nullptr,
nullptr);
3510 std::string file_name(s);
3523 throw std::runtime_error(
"the file is already loaded");
3536 }
catch (std::exception& e) {
3575 k_save_data(pf, ignoreBadObjects, true_file_h,
nullptr, force_defaults);
3599 std::cout <<
"Making backup of data file \"" << pf->
p_full_name <<
"\"...\n";
3620 bool ignoreBadObjects,
3623 bool force_defaults)
3625 const char _fname[] =
"k_save_data";
3631 std::string tmp_file_name;
3640 size_t numberOfObjects = 0;
3643 numberOfObjects =
objects->size();
3645 if (!ignoreBadObjects) {
3648 for (OksObject::FSet::const_iterator i =
objects->begin(); i !=
objects->end(); ++i) {
3649 errors += (*i)->report_dangling_references();
3652 if (!errors.empty()) {
3653 std::ostringstream text;
3654 text <<
"the file contains objects with dangling references:\n" << errors;
3655 throw std::runtime_error(text.str().c_str());
3661 std::set<OksFile*> includes;
3666 bool found_bad_object =
false;
3669 if ((*i)->file == fh) {
3672 if ((*i)->is_consistent(includes,
"WARNING") ==
false) {
3673 found_bad_object =
true;
3675 if ((*i)->is_duplicated() ==
true) {
3677 Oks::error_msg(fname) <<
" The file contains duplicated object " << *i << std::endl;
3679 found_bad_object =
true;
3685 if (found_bad_object && ignoreBadObjects ==
false) {
3686 throw std::runtime_error(
"the file contains inconsistent/duplicated objects or misses includes");
3701 std::fstream f(pf->
p_full_name.c_str(), std::ios::in);
3707 std::fstream f2(pf->
p_full_name.c_str(), std::ios::out);
3710 std::ostringstream text;
3711 text <<
"cannot open file \'" << pf->
p_full_name <<
"\' for writing";
3712 throw std::runtime_error(text.str().c_str());
3722 std::ofstream f(tmp_file_name.c_str());
3724 f.exceptions(std::ostream::failbit | std::ostream::badbit);
3727 std::ostringstream text;
3728 text <<
"cannot create temporal file \'" << tmp_file_name <<
"\' to save data";
3729 throw std::runtime_error(text.str().c_str());
3733 std::cout <<
"Saving " << numberOfObjects <<
" objects "
3734 << (force_defaults ?
"with enforced default values " :
"") <<
"to data file \"" << pf->
p_full_name
3749 for (OksClass::Map::const_iterator i =
p_classes.begin(); i !=
p_classes.end() && f.good(); ++i) {
3752 for (OksObject::Map::const_iterator j = i->second->p_objects->begin(); j != i->second->p_objects->end();
3755 sorted[j->first] = j->second;
3759 for (OksObject::SMap::iterator j = sorted.begin(); j != sorted.end(); ++j) {
3760 j->second->put(xmls, force_defaults);
3767 file_len = f.tellp();
3776 long written_len = 0;
3778 std::shared_ptr<std::ifstream> f(
new std::ifstream(tmp_file_name.c_str()));
3781 f->seekg(0, std::ios::end);
3782 written_len =
static_cast<std::streamoff
>(f->tellg());
3785 if (written_len != file_len) {
3786 unlink(tmp_file_name.c_str());
3787 std::ostringstream text;
3788 text <<
"write error in file \'" << tmp_file_name <<
"\': " << written_len <<
" bytes been written instead of "
3790 throw std::runtime_error(text.str().c_str());
3797 if (
int code = stat(pf->
p_full_name.c_str(), &buf)) {
3798 std::ostringstream text;
3799 text <<
"cannot get information about file \'" << pf->
p_full_name <<
"\': stat() failed with code " << code
3800 <<
", reason = \'" <<
strerror(errno) <<
'\'';
3801 throw std::runtime_error(text.str().c_str());
3806 if (
int code = rename(tmp_file_name.c_str(), pf->
p_full_name.c_str())) {
3807 std::ostringstream text;
3808 text <<
"cannot rename file \'" << tmp_file_name <<
"\' to \'" << pf->
p_full_name
3809 <<
"\': rename() failed with code " << code <<
", reason = \'" <<
strerror(errno) <<
'\'';
3810 throw std::runtime_error(text.str().c_str());
3813 tmp_file_name.erase(0);
3819 throw std::runtime_error(ex.
what());
3828 if (
int code = stat(pf->
p_full_name.c_str(), &buf2)) {
3829 std::ostringstream text;
3830 text <<
"cannot get information about file \'" << pf->
p_full_name <<
"\': stat() failed with code " << code
3831 <<
", reason = \'" <<
strerror(errno) <<
'\'';
3832 throw std::runtime_error(text.str().c_str());
3837 if (buf.st_mode != buf2.st_mode) {
3838 if (
int code = chmod(pf->
p_full_name.c_str(), buf.st_mode) != 0) {
3839 std::ostringstream text;
3840 text <<
"cannot set protection mode for file \'" << pf->
p_full_name <<
"\': chmod() failed with code " << code
3841 <<
", reason = \'" <<
strerror(errno) <<
'\'';
3842 throw std::runtime_error(text.str().c_str());
3848 if (buf.st_gid != buf2.st_gid) {
3849 if (
int code = chown(pf->
p_full_name.c_str(), (gid_t)(-1), buf.st_gid) != 0) {
3863 if (!tmp_file_name.empty()) {
3864 unlink(tmp_file_name.c_str());
3867 }
catch (std::exception& e) {
3874 if (!tmp_file_name.empty()) {
3875 unlink(tmp_file_name.c_str());
3885 if (!tmp_file_name.empty()) {
3886 unlink(tmp_file_name.c_str());
3901 pf->
rename(short_name, long_name);
3908 const char _fname[] =
"save_as_data";
3909 std::string fname =
make_fname(_fname,
sizeof(_fname) - 1, new_name,
nullptr, &pf);
3914 if (!new_name.length()) {
3915 throw std::runtime_error(
"the new filename is empty");
3936 }
catch (std::exception& ex) {
3953 k_save_data(i->second,
false,
nullptr,
nullptr, force_defaults);
3955 TLOG_DEBUG(2) <<
"skip read-only data file \'" << *(i->first) <<
'\'';
3977 const char _fname[] =
"k_close_data";
3995 for (OksObject::Set::const_iterator i =
p_objects.begin(); i !=
p_objects.end(); ++i) {
4006 while (!olist->empty()) {
4047 for (OksClass::Map::const_iterator i =
p_classes.begin(); i !=
p_classes.end(); ++i) {
4048 if (i->second->p_objects) {
4049 delete i->second->p_objects;
4050 i->second->p_objects = 0;
4071 TLOG_DEBUG(4) <<
"enter for file " << (
void*)fp;
4102 TLOG_DEBUG(4) <<
"leave for file " << (
void*)fp;
4105std::list<OksObject*>*
4108 const char _fname[] =
"create_list_of_data_objects";
4114 std::list<OksObject*>* olist =
new std::list<OksObject*>();
4117 for (OksObject::Set::const_iterator i =
p_objects.begin(); i !=
p_objects.end(); ++i) {
4118 if ((*i)->file == fp)
4119 olist->push_back(*i);
4123 if (olist->empty()) {
4154 (*i)->bind_objects();
4159 const std::string error_text(strchr(ex.
what(),
'\n') + 1);
4182 for (OksClass::Map::const_iterator i = all_classes.begin(); i != all_classes.end(); ++i) {
4185 for (OksObject::Map::const_iterator j = objs->begin(); j != objs->end(); ++j) {
4187 unsigned short l1 = c->number_of_all_attributes();
4188 unsigned short l2 = l1 + c->number_of_all_relationships();
4195 if (rm_objs.find(d->data.OBJECT) != rm_objs.end()) {
4197 const OksClass* __c(d->data.OBJECT->GetClass());
4198 const OksString& __id(d->data.OBJECT->GetId());
4200 TLOG_DEBUG(5) <<
"set relationship of " << o <<
": " << *d;
4203 for (OksData::List::const_iterator li = d->data.LIST->begin(); li != d->data.LIST->end(); ++li) {
4206 if (rm_objs.find(lid->
data.
OBJECT) != rm_objs.end()) {
4210 lid->
Set(__c, __id);
4211 TLOG_DEBUG(5) <<
"set relationship of " << o <<
": " << *d;
4226 OksClass::Map::const_iterator i =
p_classes.find(name);
4227 return (i !=
p_classes.end() ? i->second : 0);
4233 TLOG_DEBUG(4) <<
"enter for class \"" << c->get_name() <<
'\"';
4245 c->p_file->p_is_updated =
true;
4256 (*OksClass::create_notify_fn)(c);
4262 TLOG_DEBUG(4) <<
"enter for class \"" << c->get_name() <<
'\"';
4265 (*OksClass::delete_notify_fn)(c);
4275 if (
size_t num_of_classes =
p_classes.size()) {
4278 num_of_classes *
sizeof(
OksClass*) /
sizeof(
wchar_t);
4280 OksClass::Map::iterator i =
p_classes.begin();
4281 unsigned long idx(0);
4284 i->second->registrate_class(skip_registered);
4291 if (!c->p_all_sub_classes)
4294 c->p_all_sub_classes->clear();
4302 for (OksClass::FList::const_iterator j = scl->begin(); j != scl->end(); ++j) {
4303 (*j)->p_all_sub_classes->push_back(c);
4311 if (!c->get_is_abstract()) {
4313 if (!spc->empty()) {
4314 wmemset(
reinterpret_cast<wchar_t*
>(table), 0, array_size);
4315 for (OksClass::FList::const_iterator j1 = spc->begin(); j1 != spc->end(); ++j1) {
4317 for (OksClass::FList::const_iterator j2 = sbc->begin(); j2 != sbc->end(); ++j2) {
4320 table[c2->
p_id] = c2;
4326 unsigned int count(0);
4327 for (
unsigned int x = 0; x < num_of_classes; ++x) {
4333 std::vector<OksClass*>* cih;
4334 if (!c->p_inheritance_hierarchy) {
4335 cih = c->p_inheritance_hierarchy =
new std::vector<OksClass*>();
4337 cih = c->p_inheritance_hierarchy;
4341 cih->reserve(count);
4343 for (
unsigned int x = 0; x < num_of_classes; ++x) {
4345 cih->push_back(table[x]);
4355 std::ostringstream s;
4358 if (std::vector<OksClass*>* cis = i->second->p_inheritance_hierarchy) {
4359 s <<
" - class \'" << i->second->get_name() <<
"\' shares IDs with " << cis->size() <<
" classes: ";
4361 for (std::vector<OksClass*>::const_iterator j = cis->begin(); j != cis->end(); ++j) {
4364 for (OksClass::Set::const_iterator j = sorted.begin(); j != sorted.end(); ++j) {
4365 if (j != sorted.begin())
4367 s <<
'\'' << (*j)->get_name() <<
'\'';
4373 TLOG_DEBUG(2) <<
"Schema inheritance hierarchy used to test objects with equal IDs:\n" << s.str();
4398 std::string fname(
"OksKernel::is_dangling(");
4401 fname +=
"?object?) returns true";
4404 fname += o->
GetId();
4405 fname +=
"\") returns false";
4420 bool not_found =
true;
4424 for (OksClass::Map::const_iterator i =
p_classes.begin(); i !=
p_classes.end(); ++i) {
4425 if (i->second == c) {
4434 std::string fname(
"OksKernel::is_dangling(");
4437 fname +=
"?class?) returns true";
4440 fname += c->get_name();
4441 fname +=
"\") returns false";
4453 for (std::vector<std::string>::const_iterator i = names_in.begin(); i != names_in.end(); ++i) {
4455 if (c != 0 && classes_out.find(c) == classes_out.end()) {
4456 classes_out.insert(c);
4458 for (OksClass::FList::const_iterator j = sc->begin(); j != sc->end(); ++j) {
4459 classes_out.insert(*j);
4491 "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
4499 op,
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
4509 std::ostringstream text;
4524 if (
int result = chdir(
p_dir)) {
4526 <<
"chdir (\'" <<
p_dir <<
"\') failed with code " << result <<
": " <<
strerror(errno) << std::endl;
4543 std::string cat2str()
const;
4544 std::string last_str()
const;
4546 void check_command_status(
int status);
4557 p_file_name = get_temporary_dir() +
'/' + command_name +
'.' + std::to_string(getpid()) +
':' +
4558 std::to_string(
reinterpret_cast<std::uintptr_t
>(k)) +
".txt";
4576 std::filebuf* buf = f.rdbuf();
4578 char c = buf->sbumpc();
4593 std::string lastline;
4596 f.seekg(-1, std::ios_base::end);
4597 if (f.peek() ==
'\n') {
4598 f.seekg(-1, std::ios_base::cur);
4599 for (
int i = f.tellg(); i >= 0; i--) {
4600 if (f.peek() ==
'\n') {
4604 f.seekg(i, std::ios_base::beg);
4608 getline(f, lastline);
4617 std::ostringstream text;
4620 }
else if (
int error_code = WEXITSTATUS(status)) {
4621 std::ostringstream text;
4622 text <<
p_command.substr(0,
p_command.find_first_of(
' ')) <<
" exit with error code " << error_code <<
", output:\n"
4633 file_h->
rename(new_name);
4637 file_h->
rename(new_name);
4650 std::string cmd(
"oks-checkout.sh");
4659 if (!param.empty()) {
4663 cmd.push_back(
'\"');
4665 cmd.push_back(
'\"');
4668 if (!branch_name.empty()) {
4670 cmd.append(branch_name);
4673 auto start_usage = std::chrono::steady_clock::now();
4677 log_timestamp() <<
"[OKS checkout] => " << cmd << std::endl;
4687 std::cout << cmd_out.
cat2str();
4689 <<
"[OKS checkout] => done in "
4690 << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start_usage).count() /
4692 <<
" ms" << std::endl;
4695 static std::string version_prefix(
"checkout oks version ");
4697 std::string::size_type pos =
version.find(version_prefix);
4725 std::string cmd(
"oks-copy.sh");
4734 cmd.append(destination);
4739 auto start_usage = std::chrono::steady_clock::now();
4751 std::cout << cmd_out.
cat2str();
4753 <<
"[OKS copy] => done in "
4754 << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start_usage).count() /
4756 <<
" ms" << std::endl;
4767 "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
4771 "update",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
4773 std::string cmd(
"oks-update.sh");
4782 cmd.append(
" --force");
4784 cmd.append(
" --merge");
4786 if (!param.empty()) {
4790 cmd.push_back(
'\"');
4792 cmd.push_back(
'\"');
4795 auto start_usage = std::chrono::steady_clock::now();
4807 static std::string version_prefix(
"update oks version ");
4809 std::string::size_type pos =
version.find(version_prefix);
4818 std::cout << cmd_out.
cat2str();
4820 <<
"[OKS update] => done in "
4821 << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start_usage).count() /
4823 <<
" ms" << std::endl;
4834 "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
4838 "commit",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
4840 std::string cmd(
"oks-commit.sh");
4848 if (comments.empty() || std::all_of(comments.begin(), comments.end(), [](
char c) { return std::isspace(c); }))
4851 const std::string log_file_name(get_temporary_dir() +
'/' +
"oks-commit-msg." + std::to_string(getpid()) +
':' +
4852 std::to_string(
reinterpret_cast<std::uintptr_t
>(
this)) +
".txt");
4855 std::ofstream f(log_file_name);
4857 f.exceptions(std::ostream::failbit | std::ostream::badbit);
4860 throw std::runtime_error(
"create message file failed");
4864 }
catch (
const std::exception& ex) {
4865 std::ostringstream ss;
4866 ss <<
"cannot write to file \'" << log_file_name <<
"\' to save commit message: " << ex.what();
4870 cmd.append(
" -f \'");
4871 cmd.append(log_file_name);
4872 cmd.push_back(
'\'');
4934 auto start_usage = std::chrono::steady_clock::now();
4943 int status = system(cmd.c_str());
4945 unlink(log_file_name.c_str());
4947 if (!credentials.empty())
4948 unsetenv(
"OKS_COMMIT_USER");
4956 std::cout << cmd_out.
cat2str();
4958 <<
"[OKS commit] => done in "
4959 << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start_usage).count() /
4961 <<
" ms" << std::endl;
4964 static std::string version_prefix(
"commit oks version ");
4966 std::string::size_type pos =
version.find(version_prefix);
4981 "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
4985 "tag",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
4987 std::string cmd(
"oks-tag.sh");
4995 if (tag.empty() || std::all_of(tag.begin(), tag.end(), [](
char c) { return std::isspace(c); }))
4998 cmd.append(
" -t \'");
5000 cmd.append(
"\' -c \'");
5002 cmd.push_back(
'\'');
5004 auto start_usage = std::chrono::steady_clock::now();
5016 std::cout << cmd_out.
cat2str();
5018 <<
"[OKS tag] => done in "
5019 << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start_usage).count() /
5021 <<
" ms" << std::endl;
5025std::list<std::string>
5032 "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5036 "diff",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5038 std::string cmd(
"oks-diff.sh");
5046 if (!sha1.empty() && !sha2.empty()) {
5047 cmd.append(
" --sha ");
5052 cmd.append(
" --unmerged");
5058 std::string output = cmd_out.
cat2str();
5062 std::cout << output <<
"[OKS get_diff] => done" << std::endl;
5065 std::istringstream s(output);
5070 const char* diff_pattern =
"git diff --name-only ";
5072 while (std::getline(s, line))
5073 if (line.find(diff_pattern) == 0) {
5078 if (found ==
false) {
5079 std::ostringstream text;
5080 text <<
"cannot find \"" << diff_pattern <<
"\" pattern in output of oks-diff.sh:\n" << output;
5084 std::list<std::string> result;
5086 while (std::getline(s, line))
5087 result.push_back(line);
5095 for (
const auto& x : ver.
m_files)
5096 if (loaded_files.find(x) != loaded_files.end())
5102std::vector<OksRepositoryVersion>
5105 std::string cmd(
"oks-log.sh");
5113 cmd.append(command_line);
5118 std::string output = cmd_out.
cat2str();
5120 std::istringstream s(output);
5125 while (std::getline(s, line))
5126 if (line.find(
"git log ") == 0) {
5131 if (found ==
false) {
5132 std::ostringstream text;
5133 text <<
"cannot find \"git log\" pattern in output of oks-log.sh:\n" << output;
5137 std::set<std::string> loaded_files;
5139 if (skip_irrelevant) {
5143 loaded_files.emplace(x.first->substr(len));
5146 loaded_files.emplace(x.first->substr(len));
5149 std::vector<OksRepositoryVersion> vec;
5154 while (std::getline(s, line)) {
5155 if (found ==
false) {
5158 std::string::size_type idx1 = 0;
5159 std::string::size_type idx2 = line.find(
'|');
5161 if (idx2 != std::string::npos) {
5164 idx2 = line.find(
'|', idx1);
5166 if (idx2 != std::string::npos) {
5167 ver.
m_user = line.substr(idx1, idx2 - idx1);
5169 idx2 = line.find(
'|', idx1);
5171 if (idx2 != std::string::npos) {
5172 ver.
m_date = std::stol(line.substr(idx1, idx2 - idx1));
5181 std::ostringstream text;
5182 text <<
"unexpected line \"" << line <<
"\" in output of oks-log.sh:\n" << output;
5189 if (skip_irrelevant &&
check_relevant(loaded_files, ver) ==
false)
5192 vec.emplace_back(ver);
5200 if (skip_irrelevant ==
false ||
check_relevant(loaded_files, ver))
5201 vec.emplace_back(ver);
5207std::vector<OksRepositoryVersion>
5210 std::string command_line;
5212 if (!since.empty() && !until.empty()) {
5213 command_line.push_back(
' ');
5214 command_line.append(since);
5215 command_line.append(
"..");
5216 command_line.append(until);
5217 }
else if (!since.empty()) {
5218 command_line.push_back(
' ');
5219 command_line.append(since);
5220 command_line.append(
"..origin/master");
5221 }
else if (!until.empty()) {
5222 command_line.append(
" ..");
5223 command_line.append(until);
5232 std::string
out(in);
5233 std::replace(
out.begin(),
out.end(),
' ',
'T');
5237std::vector<OksRepositoryVersion>
5240 std::string command_line;
5242 if (!since.empty()) {
5243 command_line.append(
" --since ");
5247 if (!until.empty()) {
5248 command_line.append(
" --until ");
5252 command_line.append(
" origin/master");
5264 "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5268 "status",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5270 std::string cmd(
"oks-version.sh");
5278 std::string output = cmd_out.
cat2str();
5280 static std::string version_prefix(
"oks version ");
5282 std::string::size_type pos =
version.find(version_prefix);
5287 std::ostringstream text;
5288 text <<
"cannot read oks version from oks-version.sh output: \"" << output <<
'\"';
5297 std::set<std::string>& added,
5298 std::set<std::string>& removed)
5304 "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5308 "status",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5310 std::string cmd(
"oks-status.sh");
5318 std::string output = cmd_out.
cat2str();
5322 std::cout << output <<
"[OKS get_status] => done" << std::endl;
5325 std::istringstream s(output);
5330 const char* diff_pattern =
"git status --porcelain";
5332 while (std::getline(s, line))
5333 if (line.find(diff_pattern) == 0) {
5338 if (found ==
false) {
5339 std::ostringstream text;
5340 text <<
"cannot find \"" << diff_pattern <<
"\" pattern in output of oks-status.sh:\n" << output;
5344 std::list<std::string> result;
5346 while (std::getline(s, line)) {
5347 if (line.find(
" D ") == 0)
5348 removed.insert(line.substr(3));
5349 else if (line.find(
" M ") == 0)
5350 updated.insert(line.substr(3));
5351 else if (line.find(
"?? ") == 0)
5352 added.insert(line.substr(3));
5354 std::ostringstream text;
5355 text <<
"unexpected output \"" << line <<
"\" in output of oks-status.sh:\n" << output;
5461 std::ostringstream
out;
5464 c.second->check_relationships(
out,
true);
5472 auto now(std::chrono::system_clock::now());
5473 auto time_since_epoch(now.time_since_epoch());
5474 auto seconds_since_epoch(std::chrono::duration_cast<std::chrono::seconds>(time_since_epoch));
5476 std::time_t now_t(std::chrono::system_clock::to_time_t(std::chrono::system_clock::time_point(seconds_since_epoch)));
5479 std::size_t len = std::strftime(buff, 128 - 16,
"%Y-%b-%d %H:%M:%S.", std::localtime(&now_t));
5482 (
int)(std::chrono::duration_cast<std::chrono::milliseconds>(time_since_epoch).count() -
5483 seconds_since_epoch.count() * 1000));
5485 std::ostream& s(severity <=
Warning ? std::cerr : std::cout);
5487 s << buff << (severity ==
Error ?
"ERROR " : severity ==
Warning ?
"WARNING " : severity ==
Debug ?
"DEBUG " :
"");
static const std::string & full_local_name()
fully qualified local host name
static const LocalHost * instance()
pointer to the singleton local host
uid_t identity() const
user-id
const std::string & name_safe() const
username - no exception
static std::string fill(const std::string &name, const std::string &reason) noexcept
static std::string fill(const char *prefix, const char *item, const std::string &name, const std::string &reason) noexcept
static std::string fill(const char *prefix, const std::string &name) noexcept
Failed to set active file.
static std::string fill(const char *item, const std::string &name, const std::string &reason) noexcept
static std::string fill(const OksClass *c, const OksObject *o, const OksFile &file, const std::string &reason) noexcept
static std::string fill(const char *prefix, const char *item, const std::string &name, const std::string &reason) noexcept
static std::string fill(const OksClass &c, const std::string &reason) noexcept
static std::string fill(const std::string &path, int error_code) noexcept
CannotResolvePath(const std::string &path, int error_code) noexcept
static std::string fill(const std::string &item, const std::string &name, const std::string &reason) noexcept
static std::string fill(const std::string &names, const std::string &reason) noexcept
static void remove(const std::string &path)
void erase(const std::string &path)
std::set< std::string > s_git_folders
void insert(const std::string &path)
std::mutex s_git_folders_mutex
bool get_is_abstract() const noexcept
std::set< OksClass *, SortByName > Set
std::list< OksClass *, boost::fast_pool_allocator< OksClass * > > FList
static NotifyFN create_notify_fn
static NotifyFN delete_notify_fn
static ChangeNotifyFN change_notify_fn
OksClass(const std::string &name, OksKernel *kernel, bool transient=false)
Create OKS class.
std::map< const char *, OksClass *, SortStr > Map
Provides interface to the OKS XML schema and data files.
const std::string & get_logical_name() const
void unlock()
Unlock OKS file.
OksFile(const std::string &, const std::string &, const std::string &, const std::string &, OksKernel *)
void get_all_include_files(const OksKernel *kernel, std::set< OksFile * > &out)
Get all include files.
void lock()
Lock OKS file.
void write(OksXmlOutputStream &)
bool is_locked() const
Return lock status of OKS file.
const std::string & get_type() const
const std::string & get_short_file_name() const
std::list< std::string > p_list_of_include_files
boost::posix_time::ptime p_creation_time
std::map< const std::string *, OksFile *, SortByName > Map
void update_status_of_file(bool update_local=true, bool update_repository=true)
Update status of file.
const std::string & get_oks_format() const
OksFile * check_parent(const OksFile *parent_h)
Set given parent, if this file is not yet included.
const OksFile * p_included_by
std::unordered_map< OksFile *, Set, oks::hash_file_ptr, oks::equal_file_ptr > IMap
std::unordered_set< OksFile *, oks::hash_file_ptr, oks::equal_file_ptr > Set
const std::string & get_full_file_name() const
void rename(const std::string &short_name, const std::string &full_name)
Provides interface to the OKS kernel.
bool p_allow_duplicated_classes
OksObject::notify_obj p_change_object_notify_fn
OksFile * p_active_schema
static const std::string & get_repository_mapping_dir()
Get OKS repository name.
std::mutex p_objects_mutex
const std::string & get_user_repository_root() const
Get user OKS repository root.
void k_save_schema(OksFile *, bool force=false, OksFile *=0, const OksClass::Map *=0)
OksFile * load_file(const std::string &name, bool bind=true)
Load OKS database file.
static std::string & get_host_name()
Get hostname of given process.
static std::string & get_user_name()
Get username of given process.
void restore_preload_file_info()
bool is_dangling(OksClass *class_ptr) const
Check pointer on oks class.
std::list< std::string > get_repository_versions_diff(const std::string &sha1, const std::string &sha2)
OksFile * load_data(const std::string &name, bool bind=true)
Load OKS data file.
bool p_allow_duplicated_objects
void k_set_active_data(OksFile *)
Set active OKS data file.
static bool check_read_only(OksFile *f)
Check if the OKS file is read-only.
void k_rename_repository_file(OksFile *file_h, const std::string &new_name)
static bool p_use_strict_repository_paths
void update_repository(const std::string &hash_val, RepositoryUpdateType update_type)
Update user repository files from origin by hash.
static std::mutex p_parallel_out_mutex
void remove_repository_dir(const std::string &dir)
Remove repository search directory.
void get_modified_files(std::set< OksFile * > &mfs, std::set< OksFile * > &rfs, const std::string &version)
Get modified data files.
const OksFile::Map & data_files() const
Get all data files.
std::string p_repository_version
void k_check_bind_classes_status() const noexcept
void save_as_data(const std::string &new_name, OksFile *file_h)
Save OKS data file under new name.
void create_lists_of_updated_data_files(std::list< OksFile * > **updated, std::list< OksFile * > **removed) const
Get modified data files.
OksFile * new_data(const std::string &name, const std::string &logical_name="", const std::string &type="")
Create OKS data file.
static std::string p_repository_root
std::list< OksObject * > * create_list_of_data_objects(OksFile *) const
Creates list of objects which belong to given file.
void set_active_schema(OksFile *file_h)
Set active OKS schema file.
void k_close_dangling_includes()
Close files which lost their parent.
OksFile * find_data_file(const std::string &s) const
Finds OKS data file.
std::time_t p_repository_checkout_ts
void k_rename_schema(OksFile *, const std::string &short_name, const std::string &long_name)
friend struct OksLoadObjectsJob
std::map< std::string, T > map_str_t
void registrate_all_classes(bool skip_registered=false)
The method rebuilds all classes taking into account inheritance.
void k_close_schema(OksFile *)
void set_user_repository_root(const std::string &path, const std::string &version="")
Set user OKS repository root.
std::string p_bind_objects_status
void add_data_file(OksFile *)
const OksObject::Set & objects() const
Get objects.
OksFile::Map p_schema_files
OksFile * create_file_info(const std::string &short_file_name, const std::string &file_name)
Creates OKS file descriptor.
OksFile * k_load_file(const std::string &name, bool bind, const OksFile *parent, OksPipeline *pipeline)
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...
std::string create_user_repository_dir()
OksKernel(bool silence_mode=false, bool verbose_mode=false, bool profiling_mode=false, bool allow_repository=true, const char *version=nullptr, std::string branch_name="")
Constructor to build OksKernel object.
void backup_schema(OksFile *pf, const char *suffix=".bak")
Backup OKS schema file.
std::string get_file_path(const std::string &path, const OksFile *parent_file=0, bool strict_paths=true) const
Calculates full path to file.
void reload_data(std::set< OksFile * > &files, bool allow_schema_extension=true)
Reload OKS data files.
void k_rename_data(OksFile *, const std::string &short_name, const std::string &long_name)
friend std::ostream & operator<<(std::ostream &, OksKernel &)
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...
std::list< std::string > p_repository_dirs
void k_close_data(OksFile *, bool)
void k_set_active_schema(OksFile *file_h)
Set active OKS schema file. Non thread-safe version of the set_active_schema() method;.
void create_lists_of_updated_schema_files(std::list< OksFile * > **updated, std::list< OksFile * > **removed) const
Get modified schema files.
void remove_user_repository_dir()
const OksClass::Map & classes() const
Get classes.
std::vector< OksRepositoryVersion > get_repository_versions(bool skip_irrelevant, const std::string &command_line)
Return repository versions.
OksFile * find_schema_file(const std::string &s) const
Finds OKS schema file.
std::vector< OksRepositoryVersion > get_repository_versions_by_date(bool skip_irrelevant=true, const std::string &since="", const std::string &until="")
Return repository versions between timestamps.
std::vector< OksFile * > p_preload_added_files
static std::string p_repository_mapping_dir
OksFile * find_file(const std::string &s, const OksFile::Map &files) const
void * p_delete_object_notify_param
std::time_t p_repository_update_ts
static int p_threads_pool_size
void k_load_includes(const OksFile &, OksPipeline *)
bool p_user_repository_root_created
void tag_repository(const std::string &tag)
Tag current state of repository.
void backup_data(OksFile *pf, const char *suffix=".bak")
Backup OKS data file.
void remove_schema_file(OksFile *)
void get_updated_repository_files(std::set< std::string > &updated, std::set< std::string > &added, std::set< std::string > &removed)
Get repository modified schema files.
void unset_repository_created()
Set repository created flag to false to avoid created repository removal in destructor;.
void k_copy_repository(const std::string &source, const std::string &destination)
void save_schema(OksFile *file_h, bool force=false, OksFile *true_file_h=0)
Save OKS schema file.
void set_profiling_mode(const bool b)
Set status of profiling mode. To switch 'On'/'Off' use the method's parameter:
std::string p_bind_classes_status
static unsigned long p_count
OksFile * k_load_schema(const std::string &, const OksFile *)
void close_all_data()
Close all OKS data files.
std::string read_repository_version()
Read and return current repository version.
bool test_parent(OksFile *file, OksFile::IMap::iterator &i)
std::string p_user_repository_root
static bool p_skip_string_range
void k_remove(OksClass *)
void save_data(OksFile *file_h, bool ignore_bad_objects=false, OksFile *true_file_h=nullptr, bool force_defaults=false)
Save OKS data file.
void set_test_duplicated_objects_via_inheritance_mode(const bool b)
Set status of test inherited duplicated objects mode. To switch 'On'/'Off' use the method's parameter...
void bind_objects()
Bind oks objects.
static const std::string & get_repository_root()
Get OKS repository root.
void * p_change_object_notify_param
void commit_repository(const std::string &comments, const std::string &credentials="")
Commit user modifications into repository.
void clear_preload_file_info()
const std::string & get_repository_version()
void save_as_schema(const std::string &name, OksFile *file_h)
Save OKS schema file under new name.
void close_data(OksFile *file_h, bool unbind_objects=true)
Close OKS data file.
static std::string get_tmp_file(const std::string &file_name)
Generates temporal file name.
static const char * get_cwd()
OksFile * k_load_data(const std::string &, bool, const OksFile *, OksPipeline *)
OksFile * new_schema(const std::string &name)
Create OKS schema file.
std::vector< OksRepositoryVersion > get_repository_versions_by_hash(bool skip_irrelevant=true, const std::string &sha1="", const std::string &sha2="")
Return repository versions between hash keys.
std::shared_mutex p_kernel_mutex
bool p_test_duplicated_objects_via_inheritance
void save_all_schema()
Save all OKS schema files.
OksObject::notify_obj p_create_object_notify_fn
std::map< const OksFile *, OksFile * > p_preload_file_info
std::list< OksClass * > * create_list_of_schema_classes(OksFile *) const
Creates list of classes which belong to given file.
void save_all_data(bool force_defaults=false)
Save all OKS data files.
void add_schema_file(OksFile *)
static const char * GetVersion()
Get OKS version. The method returns string containing CVS tag and date of OKS build.
OksClass * find_class(const std::string &class_name) const
Find class by name (C++ string).
void close_schema(OksFile *file_h)
Close OKS schema file.
void remove_data_file(OksFile *)
bool k_preload_includes(OksFile *file_h, std::set< OksFile * > &new_files, bool allow_schema_extension)
std::shared_mutex p_schema_mutex
void close_all_schema()
Close all OKS schema files.
static std::string & get_domain_name()
Get domain name of host.
void set_active_data(OksFile *file_h)
Set active OKS data file.
OksFile * load_schema(const std::string &name, const OksFile *parent=0)
Load OKS schema file.
void unbind_all_rels(const OksObject::FSet &rm_objs, OksObject::FSet &updated) const
Unbind all references on given oks objects. The method unbinds all relationships referencing given ob...
std::string insert_repository_dir(const std::string &dir, bool push_back=true)
Insert repository search directory.
void k_checkout_repository(const std::string ¶m, const std::string &val, const std::string &branch)
Check out repository files into local user directory.
const OksFile::Map & schema_files() const
Get all schema files.
OksFile::Map p_data_files
void get_all_classes(const std::vector< std::string > &names_in, ClassSet &classes_out) const
The method searches all classes including subclasses for given names.
void * p_create_object_notify_param
void get_includes(const std::string &file_name, std::set< std::string > &includes, bool use_repository_name=false)
Opens file and reads its shallow includes.
bool p_user_repository_root_inited
void k_save_data(OksFile *, bool=false, OksFile *=nullptr, const OksObject::FSet *=nullptr, bool force_defaults=false)
OksMethodImplementation(const std::string &language, const std::string &prototype, const std::string &body, OksMethod *p=nullptr)
OKS method implementation constructor.
OksMethod(const std::string &name, OksClass *p=nullptr)
OKS method constructor.
OksObject describes instance of OksClass.
struct dunedaq::oks::OksObject::OksUid uid
std::map< const std::string *, OksObject *, SortById > SMap
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
std::unordered_map< const std::string *, OksObject *, oks::hash_str, oks::equal_str > Map
static OksObject * read(const oks::ReadFileParams &)
void unbind_file(const OksFile *)
const OksClass * GetClass() const
void remove_RCR(OksObject *, const OksRelationship *) noexcept
const std::string & GetId() const
@ KernelCreateSchemaClassList
@ KernelCreateDataObjectList
OksRelationship(const std::string &name, OksClass *p=nullptr)
OKS relationship simple constructor.
OksString()
to deallocate memory when destroyed
void put_last_tag(const char *, size_t len)
static void substitute_variables(std::string &)
static std::ostream & warning_msg(const char *)
static bool real_path(std::string &, bool ignore_errors)
static std::ostream & error_msg(const char *)
Cannot commit, checkout or release files.
RepositoryOperationFailed(const char *op, const exception &reason) noexcept
static std::string fill(const char *op, const std::string &reason) noexcept
virtual const char * what() const noexcept
#define OSK_VERBOSE_REPORT(MSG)
#define OSK_PROFILING(FID, K)
#define TEST_PATH_TOKEN(path, file, msg)
#define TLOG_DEBUG(lvl,...)
std::string const reason(ers::Issue const &)
bool cmp_str8n(const char *s1, const char s2[9])
const std::string strerror(int error)
Convert C error number to string.
static void create_updated_lists(const OksFile::Map &files, std::list< OksFile * > **ufs, std::list< OksFile * > **rfs, OksFile::FileStatus wu, OksFile::FileStatus wr)
bool cmp_str7n(const char *s1, const char s2[8])
std::string make_fname(const char *f, size_t f_len, const std::string &file, bool *p, const OksFile *const *fh)
static std::mutex s_get_cwd_mutex
static bool check_relevant(const std::set< std::string > &loaded_files, const OksRepositoryVersion &ver)
std::ostream & log_timestamp(__LogSeverity__ severity=Log)
static std::string replace_datetime_spaces(const std::string &in)
static GitFoldersHolder s_git_folders
static long get_file_length(std::ifstream &f)
ERS_DECLARE_ISSUE(kernel, SetGroupIdFailed, "cannot set group ID "<< id<< " for the file \'"<< file<< "\': chown() failed with code "<< code<< " , reason = \'"<< why<< '\'',((long) id)((const char *) file)((int) code)((std::string) why)) ERS_DECLARE_ISSUE(kernel
std::unordered_set< const OksClass *, oks::hash_class_ptr, oks::equal_class_ptr > ClassSet
static void test_file_existence(const std::string &file_name, bool silence, const std::string &fname, const char *msg)
std::string mk_name_and_test(const std::string &name, const char *test, size_t test_len)
static bool _find_file(const OksFile::Map &files, const OksFile *f)
bool cmp_str6n(const char *s1, const char s2[6])
bool cmp_str4n(const char *s1, const char s2[4])
FELIX Initialization std::string initerror FELIX queue timed out
FELIX Initialization std::string initerror FELIX queue timed std::string queuename Unexpected chunk size
CIB Buffer std::string descriptor Message from std::string descriptor CIB process error
void warning(const Issue &issue)
void error(const Issue &issue)
void check_command_status(int status)
std::string last_str() const
const char * p_command_name
CommandOutput(const char *command_name, const OksKernel *k, std::string &cmd)
std::string cat2str() const
const std::string & file_name() const
void add_parents(std::string &text, const OksFile *file, std::set< const OksFile * > &parents)
std::string m_error_string
std::list< std::string > m_errors
void add_error(const OksFile &file, std::exception &ex)
The struct OksAliasTable is used to support aliases.
Struct OKS data information.
union dunedaq::oks::OksData::Data data
enum dunedaq::oks::OksData::Type type
std::shared_ptr< OksXmlInputStream > m_xmls
OksLoadObjectsJob(OksKernel *kernel, OksFile *fp, std::shared_ptr< OksXmlInputStream > xmls, char format)
OksLoadObjectsJob(const OksLoadObjectsJob &)
OksLoadObjectsJob & operator=(const OksLoadObjectsJob &)
const OksClass * class_id
std::string m_commit_hash
std::vector< std::string > m_files
std::vector< OksObject * > created
std::map< const OksClass *, map_str_t< OksObject * > * > data
OksObject * pop(const OksClass *c, const std::string &id)
std::map< std::string, T > map_str_t
const char * p_user_repository_root
const char * p_repository_root
ReposDirs(const char *op, const char *cwd, OksKernel *kernel)
static std::mutex p_mutex