87 std::filesystem::remove_all(path);
89 catch (std::exception &ex)
91 Oks::error_msg(
"OksKernel::~OksKernel") <<
"cannot remove user repository \"" << path <<
"\"" << ex.what() << std::endl;
123 return std::string(strerror_r(
error, buffer, 1024));
130 "cannot set group ID " <<
id <<
" for the file \'" << file <<
"\': chown() failed with code " << code <<
" , reason = \'" << why <<
'\'',
140 "Found unresolved reference(s):\n" << which,
147 "class \"" << name <<
"\" is defined in files \"" << f1 <<
"\" and \"" << f2 <<
"\"",
156 "internal error: " << text,
161 CanNotOpenFile::fill(
const char * prefix,
const std::string& name,
const std::string& reason)
noexcept
163 std::string result(prefix);
166 if(name.empty())
return (result +
"file name is empty");
168 result +=
"cannot load file \'" + name +
'\'' ;
170 if(!reason.empty()) {
171 result +=
" because:\n" + reason;
178 FailedLoadFile::fill(
const std::string& what,
const std::string& name,
const std::string& reason)
noexcept
180 return (std::string(
"Failed to load ") + what +
" \"" + name +
"\" because:\n" + reason);
186 return (std::string(
"Failed to re-load file(s) ") + names +
" because:\n" + reason);
192 return (std::string(
"Failed to ") + op +
" file(s) because:\n" + reason);
196 CanNotCreateFile::fill(
const char * prefix,
const char * what,
const std::string& name,
const std::string& reason)
noexcept
198 return std::string(prefix) +
"(): failed to create new " + what +
" \'" + name +
"\' because:\n" +
reason;
204 return std::string(prefix) +
"(): failed to create user repository dir, mkdtemp(\'" + name +
"\') failed: " +
strerror(errno);
208 CanNotWriteToFile::fill(
const char * prefix,
const char * item,
const std::string& name,
const std::string& reason)
noexcept
210 return (std::string(prefix) +
"(): failed to write " + item +
" to \'" + name +
"\' because:\n" + reason);
216 return (std::string(
"Failed to make a backup file of \'") + name +
"\' because:\n" + reason);
222 return (std::string(
"Failed to set active ") + item +
" file \'" + name +
"\' because:\n" + reason);
228 std::ostringstream
s;
229 s <<
"Failed to move ";
230 if(c)
s <<
"class " <<
c->get_name();
231 else s <<
"object " << o;
232 s <<
" to file \'" <<
file.get_full_file_name() <<
"\' because:\n" <<
reason;
239 return (std::string(
"Cannot add class \'") +
c.get_name() +
"\' because:\n" + reason);
245 std::ostringstream text;
246 text <<
"realpath(\'" << path <<
"\') has failed with code " << error_code <<
": \'" <<
strerror(error_code) <<
'\'';
251 static const std::string&
254 static std::string s_dir;
255 static std::once_flag flag;
257 std::call_once(flag, []()
261 if (!getenv(
"OKS_GIT_NO_VAR_DIR"))
263 OksSystem::User myself;
265 s_dir =
"/var/run/user/";
266 s_dir.append(std::to_string(myself.
identity()));
268 if (std::filesystem::is_directory(s_dir) ==
false)
270 TLOG_DEBUG(1) <<
"directory " << s_dir <<
" does not exist";
275 const std::filesystem::space_info si = std::filesystem::space(s_dir);
276 const double available =
static_cast<double>(si.available) /
static_cast<double>(si.capacity);
280 TLOG_DEBUG(1) <<
"usage of " << s_dir <<
" is " <<
static_cast<int>((1.0 - available) * 100.0) <<
"%, will use standard temporary path";
287 s_dir = std::filesystem::temp_directory_path().string();
289 catch (std::exception& ex)
291 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot get temporary directory path: " << ex.what() << std::endl;
304 return "862f2957270";
311 static std::once_flag flag;
313 std::call_once(flag, []()
315 if (
const char * s = getenv(
"TDAQ_DB_REPOSITORY"))
319 if (!std::all_of(rep.begin(), rep.end(), [](
char c) { return std::isspace(c); }))
321 const char * p = getenv(
"OKS_GIT_PROTOCOL");
333 if (token.find(p) == 0)
345 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot find OKS_GIT_PROTOCOL=\"" << p <<
"\" in TDAQ_DB_REPOSITORY=\"" << rep <<
'\"' << std::endl;
357 static std::once_flag flag;
359 std::call_once(flag, []()
361 if (
const char * s = getenv(
"OKS_REPOSITORY_MAPPING_DIR"))
381 if(
const char * s = getenv(
"TDAQ_DB_USER_REPOSITORY")) {
397 TLOG_DEBUG( 1) <<
"Failed to set user-repository-root:\n\tcaused by: repository-root is not set" ;
414 TLOG_DEBUG( 1) <<
"Failed to set user-repository-root = \'" << s <<
"\':\n\tcaused by: " << ex.
what() ;
417 for(std::string::size_type idx = s.size()-1; idx > 0 && s[idx] ==
'/' ; idx--) {
436 static std::string s_host_name;
437 static std::once_flag flag;
439 std::call_once(flag, []()
443 if (s_host_name.empty())
444 s_host_name =
"unknown.host";
454 static std::string s_domain_name;
455 static std::once_flag flag;
457 std::call_once(flag, []()
461 if (idx != std::string::npos)
464 if (s_domain_name.empty())
465 s_domain_name =
"unknown.domain";
469 return s_domain_name;
475 static std::string s_user_name;
476 static std::once_flag flag;
478 std::call_once(flag, []()
483 if (s_user_name.empty())
484 s_user_name =
"unknown.user";
497 long file_length = 0;
501 f.seekg(0, std::ios::end);
504 file_length =
static_cast<std::streamoff
>(f.tellg());
506 file_length = f.tellg();
509 f.seekg(0, std::ios::beg);
517make_fname(
const char * f,
size_t f_len,
const std::string& file,
bool * p,
const OksFile *
const * fh)
519 const char _prefix [] =
"OksKernel::";
520 std::string fname(_prefix, (
sizeof(_prefix)-1));
522 fname.append(f, f_len);
524 const char _x1 [] =
"(file \'";
525 fname.append(_x1, (
sizeof(_x1)-1));
527 fname.push_back(
'\'');
533 const char _true_str [] =
", true";
534 fname.append(_true_str, (
sizeof(_true_str)-1));
537 const char _false_str [] =
", false";
538 fname.append(_false_str, (
sizeof(_false_str)-1));
545 const char _x2 [] =
", included by file \'";
546 fname.append(_x2, (
sizeof(_x2)-1));
547 fname.append((*fh)->get_full_file_name());
548 fname.push_back(
'\'');
551 fname.push_back(
')');
563 std::cerr <<
"ERROR [" << msg <<
"]:\n";
return std::cerr;
570 std::cerr <<
"WARNING [" << msg <<
"]:\n";
return std::cerr;
577 std::string::size_type pos = 0;
578 std::string::size_type p_start = 0;
579 std::string::size_type p_end = 0;
582 ((p_start = s.find(
"$(", pos)) != std::string::npos) &&
583 ((p_end = s.find(
")", p_start + 2)) != std::string::npos)
585 std::string var(s, p_start + 2, p_end - p_start - 2);
587 char *
env = getenv(var.c_str());
590 s.replace(p_start, p_end - p_start + 1,
env);
601 char resolved_name[PATH_MAX];
603 if(realpath(path.c_str(), resolved_name) != 0) {
604 path = resolved_name;
609 TLOG_DEBUG( 3) <<
"realpath(\'" << path <<
"\') has failed with code " << errno <<
": \'" <<
strerror(errno) <<
'\'' ;
621 "abcdefghijklmnoprstuvwxyz"
622 "ABCDEFGHIJKLMNOPRSTUVWXYZ";
628 static const size_t slen(
sizeof(
symbols)-1);
629 static const size_t slen2(slen*slen);
631 char b[16], *buf = b;
637 if((
size_t)
count >= slen) {
640 if((
size_t)
count >= slen2) {
674 std::ostringstream s;
676 while(j++ < 1000000) {
682 std::ofstream f(s2.c_str(), std::ios::in);
687 std::string s3(file);
701 long size = pathconf(
".", _PC_PATH_MAX);
704 Oks::error_msg(
"OksKernel::OksKernel") <<
"pathconf(\".\", _PC_PATH_MAX) has failed with code " << errno <<
": \'" <<
strerror(errno) <<
'\'' << std::endl;
715 Oks::error_msg(
"OksKernel::OksKernel") <<
"getcwd() has failed with code " << errno <<
": \'" <<
strerror(errno) <<
'\'' << std::endl;
759 OSK_VERBOSE_REPORT(
"Enter OksKernel::OksKernel(" << sm <<
", " << vm <<
", " << tm <<
')')
761 struct __InitFromEnv__ {
775 for(
unsigned int i = 0; i <
sizeof(vars) /
sizeof(__InitFromEnv__); ++i) {
776 if(
char * s = getenv(vars[i].name)) {
777 vars[i].value = (strcmp(s,
"no")) ?
true :
false;
782 const char * oks_db_root = getenv(
"OKS_DB_ROOT");
784 if (oks_db_root ==
nullptr || *oks_db_root == 0)
785 oks_db_root = getenv(
"DUNEDAQ_DB_PATH");
789 OSK_VERBOSE_REPORT(
"database root = \'" << oks_db_root <<
"\' (as defined by the OKS_DB_ROOT or DUNEDAQ_DB_PATH)");
794 if (oks_db_root ==
nullptr)
803 while (t.
next(token))
823 static std::once_flag flag;
825 std::call_once(flag, []()
827 if (
char * s = getenv(
"OKS_KERNEL_THREADS_POOL_SIZE"))
843 Oks::error_msg(
"OksKernel::OksKernel()") <<
" sysconf(_SC_NPROCESSORS_ONLN) has failed with code " << errno <<
": \'" <<
strerror(errno) <<
'\'' << std::endl;
863 std::string param, val;
866 version = getenv(
"TDAQ_DB_VERSION");
872 if(
const char * value = strchr(
version,
':'))
878 Oks::error_msg(
"OksKernel::OksKernel") <<
"bad version value \"" <<
version <<
"\" expecting parameter:value format (check TDAQ_DB_VERSION variable)" << std::endl;
890 if (branch_name.empty())
891 if (
const char *var = getenv(
"TDAQ_DB_BRANCH"))
898 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot check out user repository: " << ex.
what() << std::endl;
912 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot read user repository version: " << ex.
what() << std::endl;
967 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot copy user repository: " << ex.
what() << std::endl;
983 const OksFile::Map * src_files[2] = { &src.p_schema_files, &src.p_data_files };
984 OksFile::Map * dst_files[2] = { &p_schema_files, &p_data_files };
986 for (
int i = 0; i < 2; ++i)
988 for (
const auto& j : *src_files[i])
992 (*dst_files[i])[&f->p_full_name] = f;
1003 for(
const auto& i : src.p_classes) {
1005 OksClass * c =
new OksClass (src_c.p_name, src_c.p_description, src_c.p_abstract,
nullptr, src_c.p_transient);
1008 p_classes[c->get_name().c_str()] = c;
1010 const_cast<OksClass&
>(src_c).p_id = idx++;
1011 c->p_id = src_c.p_id;
1012 c_table[c->p_id] = c;
1014 c->p_abstract = src_c.p_abstract;
1015 c->p_to_be_deleted = src_c.p_to_be_deleted;
1016 c->p_instance_size = src_c.p_instance_size;
1017 c->p_file = (*p_schema_files.find(&src_c.p_file->p_full_name)).second;
1018 c->p_objects = (src_c.p_objects ?
new OksObject::Map() : nullptr);
1022 if (
const std::list<std::string *> * scls = src_c.p_super_classes)
1024 c->p_super_classes = new std::list<std::string *>();
1026 for (const auto& j : *scls)
1027 c->p_super_classes->push_back(new std::string(*j));
1032 if (
const std::list<OksAttribute *> * attrs = src_c.p_attributes)
1034 c->p_attributes = new std::list<OksAttribute *>();
1036 for (const auto& j : *attrs)
1038 OksAttribute * a = new OksAttribute(j->p_name, c);
1040 a->p_range = j->p_range;
1041 a->p_data_type = j->p_data_type;
1042 a->p_multi_values = j->p_multi_values;
1043 a->p_no_null = j->p_no_null;
1044 a->p_init_value = j->p_init_value;
1045 a->p_init_data = j->p_init_data;
1046 a->p_format = j->p_format;
1047 a->p_description = j->p_description;
1049 if (j->p_enumerators)
1050 a->p_enumerators = new std::vector<std::string>(*j->p_enumerators);
1052 c->p_attributes->push_back(a);
1058 if (
const std::list<OksRelationship *> * rels = src_c.p_relationships)
1060 c->p_relationships =
new std::list<OksRelationship *>();
1062 for (
const auto& j : *rels)
1064 OksRelationship * r =
new OksRelationship(j->p_name, c);
1066 r->p_rclass = j->p_rclass;
1067 r->p_low_cc = j->p_low_cc;
1068 r->p_high_cc = j->p_high_cc;
1069 r->p_composite = j->p_composite;
1070 r->p_exclusive = j->p_exclusive;
1071 r->p_dependent = j->p_dependent;
1072 r->p_description = j->p_description;
1074 c->p_relationships->push_back(r);
1080 if (
const std::list<OksMethod *> * mets = src_c.p_methods)
1082 c->p_methods =
new std::list<OksMethod *>();
1084 for (
const auto& j : *mets)
1088 if (
const std::list<OksMethodImplementation *> * impls = j->p_implementations)
1090 m->p_implementations =
new std::list<OksMethodImplementation *>();
1092 for (
const auto& x : *impls)
1093 m->p_implementations->push_back(
new OksMethodImplementation(x->get_language(), x->get_prototype(), x->get_body(), m));
1096 c->p_methods->push_back(m);
1104 for (
const auto& i : src.p_classes)
1106 OksClass *
c = c_table[i.second->p_id];
1109 if (
const std::list<OksRelationship *> * rels = i.second->p_relationships)
1111 for (
const auto& j : *rels)
1112 c->find_relationship(j->get_name())->p_class_type = (j->p_class_type ? c_table[j->p_class_type->p_id] :
nullptr);
1116 if (
const OksClass::FList * spcls = i.second->p_all_super_classes)
1118 c->p_all_super_classes =
new OksClass::FList();
1120 for (
const auto& j : *spcls)
1121 c->p_all_super_classes->push_back(c_table[j->p_id]);
1124 if (
const OksClass::FList * sbcls = i.second->p_all_sub_classes)
1126 c->p_all_sub_classes =
new OksClass::FList();
1128 for (
const auto& j : *sbcls)
1129 c->p_all_sub_classes->push_back(c_table[j->p_id]);
1133 c->p_data_info =
new OksDataInfo::Map();
1134 size_t instance_size = 0;
1137 if (
const std::list<OksAttribute *> * attrs = i.second->p_all_attributes)
1139 c->p_all_attributes =
new std::list<OksAttribute *>();
1141 for (
const auto& j : *attrs)
1143 OksAttribute * a = (c_table[j->p_class->p_id])->find_direct_attribute(j->get_name());
1144 c->p_all_attributes->push_back(a);
1145 (*
c->p_data_info)[a->get_name()] =
new OksDataInfo(instance_size++, a);
1150 if (
const std::list<OksRelationship *> * rels = i.second->p_all_relationships)
1152 c->p_all_relationships =
new std::list<OksRelationship *>();
1154 for (
const auto& j : *rels)
1156 OksRelationship *
r = (c_table[j->p_class->p_id])->find_direct_relationship(j->get_name());
1157 c->p_all_relationships->push_back(r);
1158 (*
c->p_data_info)[
r->get_name()] =
new OksDataInfo(instance_size++, r);
1163 if (
const std::list<OksMethod *> * mets = i.second->p_all_methods)
1165 c->p_all_methods =
new std::list<OksMethod *>();
1167 for (
const auto& j : *mets)
1168 c->p_all_methods->push_back((c_table[j->p_class->p_id])->find_direct_method(j->get_name()));
1172 if (
const std::vector<OksClass *> * ih = i.second->p_inheritance_hierarchy)
1174 c->p_inheritance_hierarchy =
new std::vector<OksClass *>();
1175 c->p_inheritance_hierarchy->reserve(ih->size());
1177 for (
const auto& j : *ih)
1178 c->p_inheritance_hierarchy->push_back(c_table[j->p_id]);
1185 if(!src.p_objects.empty()) {
1190 OksObject ** o_table =
new OksObject * [src.p_objects.size()];
1195 for(OksObject::Set::const_iterator i = src.p_objects.begin(); i != src.p_objects.end(); ++i, ++idx) {
1196 OksObject * src_o(*i);
1197 src_o->p_user_data =
reinterpret_cast<void *
>(idx);
1199 OksClass *
c = c_table[src_o->uid.class_id->p_id];
1201 OksObject * o =
new OksObject(
1203 src_o->uid.object_id,
1206 src_o->p_duplicated_object_id_idx,
1207 (*p_data_files.find(&src_o->file->p_full_name)).second
1211 (*
c->p_objects)[&o->uid.object_id] = o;
1212 p_objects.insert(o);
1214 if(
size_t num_of_attrs =
c->number_of_all_attributes()) {
1215 const OksData * src_data = src_o->data;
1216 OksData * dst_data = o->data;
1218 std::list<OksAttribute *>::const_iterator ia_dst =
c->all_attributes()->begin();
1219 std::list<OksAttribute *>::const_iterator ia_src = src_o->uid.class_id->all_attributes()->begin();
1221 for(
size_t j = 0; j < num_of_attrs; ++j) {
1222 *dst_data = *src_data;
1224 OksAttribute * a_dst(*ia_dst);
1228 if(a_dst->get_data_type() == OksData::class_type) {
1229 if(a_dst->get_is_multi_values() ==
false) {
1230 dst_data->data.CLASS = c_table[src_data->data.CLASS->p_id];
1233 OksData::List::iterator li_dst = dst_data->data.LIST->begin();
1234 OksData::List::iterator li_src = src_data->data.LIST->begin();
1236 while(li_dst != dst_data->data.LIST->end()) {
1237 (*li_dst)->data.CLASS = c_table[(*li_src)->data.CLASS->p_id];
1246 else if(a_dst->get_data_type() == OksData::enum_type) {
1247 OksAttribute * a_src(*ia_src);
1248 const std::string * p_enumerators_first(&((*(a_src->p_enumerators))[0]));
1250 if(a_dst->get_is_multi_values() ==
false) {
1251 unsigned long dx = src_data->data.ENUMERATION - p_enumerators_first;
1252 dst_data->data.ENUMERATION = &((*(a_dst->p_enumerators))[dx]);
1255 OksData::List::iterator li_dst = dst_data->data.LIST->begin();
1256 OksData::List::iterator li_src = src_data->data.LIST->begin();
1258 while(li_dst != dst_data->data.LIST->end()) {
1259 unsigned long dx = (*li_src)->data.ENUMERATION - p_enumerators_first;
1260 (*li_dst)->data.ENUMERATION = &((*(a_dst->p_enumerators))[dx]);
1279 for(
const auto& src_o : src.p_objects) {
1280 OksClass *
c = c_table[src_o->uid.class_id->p_id];
1281 OksObject * o(o_table[
reinterpret_cast<unsigned long>(src_o->p_user_data)]);
1283 if(
size_t num_of_rels =
c->number_of_all_relationships()) {
1284 const OksData * src_data(src_o->data +
c->number_of_all_attributes());
1285 OksData * dst_data(o->data +
c->number_of_all_attributes());
1287 for(
size_t j = 0; j < num_of_rels; ++j) {
1288 dst_data->type = src_data->type;
1289 switch(src_data->type) {
1290 case OksData::list_type:
1291 dst_data->data.LIST =
new OksData::List();
1292 for(
const auto& x : *src_data->data.LIST) {
1293 OksData *
d =
new OksData();
1295 if(x->type == OksData::object_type)
1297 if(
const OksObject * o2 = x->data.OBJECT)
1299 d->Set(o_table[
reinterpret_cast<unsigned long>(o2->p_user_data)]);
1303 d->Set((OksObject *)
nullptr);
1306 else if(x->type == OksData::uid_type)
1308 d->Set(c_table[x->data.UID.class_id->p_id], *x->data.UID.object_id);
1310 else if(x->type == OksData::uid2_type)
1312 d->Set(*x->data.UID2.class_id, *x->data.UID2.object_id);
1316 ers::error(kernel::InternalError(
ERS_HERE,
"unexpected data type in relationship list"));
1319 dst_data->data.LIST->push_back(d);
1323 case OksData::object_type:
1324 if(
const OksObject * o2 = src_data->data.OBJECT) {
1325 dst_data->data.OBJECT = o_table[
reinterpret_cast<unsigned long>(o2->p_user_data)];
1328 dst_data->data.OBJECT = 0;
1332 case OksData::uid_type:
1333 dst_data->data.UID.class_id = c_table[src_data->data.UID.class_id->p_id];
1334 dst_data->data.UID.object_id =
new OksString(*src_data->data.UID.object_id);
1337 case OksData::uid2_type:
1338 dst_data->data.UID2.class_id =
new OksString(*src_data->data.UID2.class_id);
1339 dst_data->data.UID2.object_id =
new OksString(*src_data->data.UID2.object_id);
1352 if (
const std::list<OksRCR *> * src_rcrs = src_o->p_rcr)
1354 o->p_rcr =
new std::list<OksRCR *>();
1356 for (
const auto& j : *src_rcrs)
1357 o->p_rcr->push_back(
1359 o_table[
reinterpret_cast<unsigned long>(j->obj->p_user_data)],
1360 (c_table[j->relationship->p_class->p_id])->find_direct_relationship(j->relationship->get_name())
1376 if (copy_repository && p_user_repository_root_inited)
1378 OksFile::Map * files_map[2] = { &p_schema_files, &p_data_files };
1380 for (
int i = 0; i < 2; ++i)
1382 std::vector<OksFile *> files;
1384 for (
auto& f : *files_map[i])
1385 files.push_back(
f.second);
1387 files_map[i]->clear();
1389 for (
auto& f : files)
1391 std::string name = p_user_repository_root;
1392 name.push_back(
'/');
1393 name.append(
f->get_repository_name());
1395 (*files_map[i])[&
f->p_full_name] = f;
1416 std::cout <<
" * push " << (push_back ?
"back" :
"front") <<
" repository search directory \'" << s <<
"\'\n";
1422 TLOG_DEBUG( 1) <<
"Cannot insert repository dir \'" << dir <<
"\':\n\tcaused by: " << ex ;
1436 std::cout <<
" * remove repository search directory \'" << dir <<
"\'\n";
1501 s <<
"OKS KERNEL DUMP:\n" <<
"OKS VERSION: " << k.
GetVersion() << std::endl;
1505 s <<
" Loaded schema:\n";
1508 s <<
" " << i.second->get_full_file_name() << std::endl;
1512 s <<
" Loaded data:\n";
1515 s <<
" " << j.second->get_full_file_name() << std::endl;
1518 s <<
" No loaded data files\n";
1522 s <<
" The classes:\n";
1529 s <<
" No loaded schema files\n";
1531 s <<
"END OF OKS KERNEL DUMP.\n";
1539 static std::string suffix;
1540 static std::once_flag flag;
1542 std::call_once(flag, []()
1544 std::ostringstream s;
1554 static std::mutex p_check_read_only_mutex;
1555 std::lock_guard scoped_lock(p_check_read_only_mutex);
1558 std::ofstream f(s.c_str(), std::ios::out);
1578 std::shared_ptr<std::ifstream> f(
new std::ifstream(full_path.c_str()));
1582 file_h =
new OksFile(xmls, short_path, full_path,
this);
1604 bool file_exists =
false;
1608 if(stat(file_name.c_str(), &buf) == 0) {
1610 Oks::warning_msg(fname) <<
" File \"" << file_name <<
"\" already exists\n";
1620 std::ofstream f(file_name.c_str());
1625 throw std::runtime_error(
"cannot open file in write mode");
1628 throw std::runtime_error(
"cannot create file");
1635 std::cout <<
"Creating new " << msg <<
" file \"" << file_name <<
"\"..." << std::endl;
1642 const char _s1_str[] =
" - \'";
1643 const char _s2_str[] =
"\' tested as ";
1645 return ((std::string(_s1_str,
sizeof(_s1_str)-1) + name).append(_s2_str,
sizeof(_s2_str)-1)).append(test, test_len);
1649#define TEST_PATH_TOKEN(path, file, msg) \
1650std::string token(path); \
1651token.push_back('/'); \
1652token.append(file); \
1653Oks::substitute_variables(token); \
1654if(Oks::real_path(token, true)) { \
1655 TLOG_DEBUG(2) << fname << " returns \'" << token << "\' (filename relative to " << msg << " database repository directory)"; \
1659 const char _test_name[] = "relative to database repository directory"; \
1660 tested_files.push_back(mk_name_and_test(token, _test_name, sizeof(_test_name)-1)); \
1669 const char _fname[] =
"get_file_path";
1674 std::list<std::string> tested_files;
1677 bool is_absolute_path =
false;
1681 fname =
make_fname(_fname,
sizeof(_fname) - 1, s2,
nullptr, &file_h);
1685 is_absolute_path =
true;
1688 if (is_absolute_path || file_h == 0)
1692 std::string s3 =
s_cwd;
1709 TLOG_DEBUG(2) << fname <<
" returns external \'" << s2 <<
"\' (an absolute filename or relative to CWD=\'" <<
s_cwd <<
"\')";
1713 std::ostringstream text;
1714 text << fname <<
" file does not belong to oks git repository\n"
1715 "provide file repository name, or unset TDAQ_DB_REPOSITORY and try again with the DUNEDAQ_DB_PATH environment variable";
1716 throw std::runtime_error(text.str().c_str());
1720 TLOG_DEBUG(2) << fname <<
" returns \'" << s2 <<
"\' (an absolute filename or relative to CWD=\'" <<
s_cwd <<
"\')";
1726 if (is_absolute_path)
1728 const char _test_name[] =
"an absolute file name";
1729 tested_files.push_back(
mk_name_and_test(s2, _test_name,
sizeof(_test_name) - 1));
1733 const char _test_name[] =
"relative to current working directory";
1734 tested_files.push_back(
mk_name_and_test(s2, _test_name,
sizeof(_test_name) - 1));
1747 if (!is_absolute_path)
1754 if (file_h && !is_absolute_path)
1757 std::string::size_type pos = s2.find_last_of(
'/');
1759 if (pos != std::string::npos)
1767 TLOG_DEBUG(2) << fname <<
" returns \'" << s2 <<
"\' (filename relative to parent file)";
1772 const char _test_name[] =
"relative to parent file";
1773 tested_files.push_back(
mk_name_and_test(s2, _test_name,
sizeof(_test_name) - 1));
1779 TLOG_DEBUG(2) << fname <<
" throw exception (file was not found)";
1781 std::ostringstream text;
1782 text << fname <<
" found no readable file among " << tested_files.size() <<
" tested:\n";
1783 for (
auto & i : tested_files)
1784 text << i << std::endl;
1786 throw std::runtime_error(text.str().c_str());
1805 const char _fname[] =
"k_load_file";
1806 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, short_file_name, &bind, &parent_h);
1810 std::string full_file_name;
1815 catch (std::exception & e) {
1823 OksFile::Map::const_iterator i =
p_schema_files.find(&full_file_name);
1824 if(i !=
p_schema_files.end())
return i->second->check_parent(parent_h);
1827 if(i !=
p_data_files.end())
return i->second->check_parent(parent_h);
1829 std::shared_ptr<std::ifstream> f(
new std::ifstream(full_file_name.c_str()));
1835 throw std::runtime_error(
"k_load_file(): file is empty");
1842 OksFile * file_h =
new OksFile(xmls, short_file_name, full_file_name,
this);
1858 throw std::runtime_error(
"k_load_file(): failed to parse header");
1861 k_load_data(file_h, format, xmls, file_length, bind, parent_h, pipeline);
1869 throw std::runtime_error(
"k_load_file(): cannot open file");
1875 catch (std::exception & e) {
1879 throw FailedLoadFile(
"file", full_file_name,
"caught unknown exception");
1887 for(std::list<std::string>::const_iterator i = f.p_list_of_include_files.begin(); i != f.p_list_of_include_files.end(); ++i) {
1891 if((*i)[0] ==
'/') {
1892 throw FailedLoadFile(
"include", *i,
"inclusion of files with absolute pathname (like \"/foo/bar\") is not allowed by repository files; include files relative to repository root (like \"foo/bar\")");
1894 else if((*i)[0] ==
'.') {
1895 throw FailedLoadFile(
"include", *i,
"inclusion of files with file-related relative pathnames (like \"../foo/bar\" or \"./bar\") is not supported by repository files; include files relative to repository root (like \"foo/bar\")");
1897 else if((*i).find(
'/') == std::string::npos) {
1898 throw FailedLoadFile(
"include", *i,
"inclusion of files with file-related local pathnames (like \"bar\") is not supported by repository files; include files relative to repository root (like \"foo/bar\")");
1908 catch (std::exception & e) {
1922 std::shared_ptr<std::ifstream> f(
new std::ifstream(file_name.c_str()));
1925 throw std::runtime_error(
"get_includes(): cannot open file");
1929 OksFile fp(xmls, file_name, file_name,
this);
1942 catch (std::exception & e) {
1953 if(includes.find(file) != includes.end()) {
1954 if(file->p_included_by != parent) {
1956 file->p_included_by = parent;
1973 for(std::list<std::string>::const_iterator x = i->second->p_list_of_include_files.begin(); x != i->second->p_list_of_include_files.end(); ++x) {
1977 igraph[i->second].insert(it->second);
1980 std::cerr <<
"cannot find schema " << *x <<
" included by " << i->second->get_full_file_name() << std::endl;
1986 for(std::list<std::string>::const_iterator x = i->second->p_list_of_include_files.begin(); x != i->second->p_list_of_include_files.end(); ++x) {
1988 OksFile::Map::const_iterator it =
p_data_files.find(&f);
1990 igraph[i->second].insert(it->second);
1996 igraph[i->second].insert(it->second);
1999 std::cerr <<
"cannot find file " << *x <<
" included by " << i->second->get_full_file_name() << std::endl;
2015 std::list<OksFile *> to_be_closed[2];
2017 for(
int c = 0; c < 2; ++c) {
2018 for(OksFile::Map::iterator i = files[c]->begin(); i != files[c]->end(); ++i) {
2019 if(
OksFile * p =
const_cast<OksFile *
>(i->second->p_included_by)) {
2020 bool found_parent =
false;
2024 if(igraph.find(p) != igraph.end()) {
2025 OksFile::IMap::iterator j = igraph.find(p);
2031 TLOG_DEBUG( 1 ) <<
"the parent of file " << i->second->get_full_file_name() <<
" is not valid" ;
2036 for(OksFile::IMap::iterator j = igraph.begin(); j != igraph.end(); ++j) {
2038 found_parent =
true;
2043 if(found_parent ==
false) {
2044 TLOG_DEBUG( 1 ) <<
"the file " << i->second->get_full_file_name() <<
" is not included by any other file and will be closed" ;
2045 to_be_closed[c].push_back(i->second);
2053 for(std::list<OksFile *>::const_iterator i = to_be_closed[1].begin(); i != to_be_closed[1].end(); ++i) {
2054 num += (*i)->p_list_of_include_files.size();
2059 for(std::list<OksFile *>::const_iterator i = to_be_closed[0].begin(); i != to_be_closed[0].end(); ++i) {
2060 num += (*i)->p_list_of_include_files.size();
2066 TLOG_DEBUG( 1 ) <<
"go into recursive call, number of potentially closed includes is " << num ;
2075 TLOG_DEBUG( 1 ) <<
"rebuild classes since number of schema files has been changed from " << num_of_schema_files <<
" to " <<
schema_files().size() ;
2084 bool found_include_changes(
false);
2087 std::shared_ptr<std::ifstream> file(
new std::ifstream(fp->
get_full_file_name().c_str()));
2090 throw std::runtime_error(std::string(
"k_preload_includes(): cannot open file \"") + fp->
get_full_file_name() +
'\"');
2095 std::set<std::string> included;
2099 included.insert(*i);
2105 file->seekg(0, std::ios::end);
2107 long file_length =
static_cast<std::streamoff
>(file->tellg());
2109 if(file_length == 0) {
2110 throw std::runtime_error(std::string(
"k_preload_includes(): file \"") + fp->
get_full_file_name() +
"\" is empty");
2113 file->seekg(0, std::ios::beg);
2124 throw std::runtime_error(std::string(
"k_preload_includes(): failed to read header of file \"") + fp->
get_full_file_name() +
'\"');
2131 throw std::runtime_error(std::string(
"k_preload_includes(): file \"") + fp->
get_full_file_name() +
"\" is not valid oks file");
2141 std::set<std::string>::const_iterator x = included.find(*i);
2142 if(x != included.end()) {
2143 TLOG_DEBUG(3) <<
"include \'" << *i <<
"\' already exists, skip...";
2148 found_include_changes =
true;
2150 std::string full_file_name;
2155 catch (std::exception & e) {
2159 OksFile::Map::const_iterator j =
p_schema_files.find(&full_file_name);
2161 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is already loaded schema file \'" << j->first <<
'\'';
2167 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is already loaded data file \'" << j->first <<
'\'';
2172 if(f->p_oks_format ==
"schema") {
2173 std::string new_schema_full_file_name = f->get_full_file_name();
2176 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is a schema file, that was already loaded";
2180 if(allow_schema_extension) {
2181 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is new schema file, loading...";
2186 std::ostringstream text;
2187 text <<
"k_preload_includes(): include of new schema file (\'" << *i <<
"\') is not allowed on data reload";
2188 throw std::runtime_error(text.str().c_str());
2192 else if(f->p_oks_format ==
"data" || f->p_oks_format ==
"extended" || f->p_oks_format ==
"compact") {
2193 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is new data file, pre-loading...";
2196 new_files_h.insert(f);
2197 f->p_list_of_include_files.clear();
2198 if(
k_preload_includes(f, new_files_h, allow_schema_extension)) found_include_changes =
true;
2199 f->p_included_by = fp;
2200 f->update_status_of_file();
2204 std::ostringstream text;
2205 text <<
"k_preload_includes(): failed to parse header of included \'" << full_file_name <<
"\' file";
2206 throw std::runtime_error(text.str().c_str());
2210 throw std::runtime_error(
"k_load_file(): cannot open file");
2219 catch (std::exception & e) {
2223 return found_include_changes;
2232 if (
const char * path = getenv(
"TDAQ_DB_USER_REPOSITORY_PATH"))
2236 std::string user_repo;
2238 if (
const char * user_repo_base = getenv(
"TDAQ_DB_USER_REPOSITORY_ROOT"))
2239 user_repo = user_repo_base;
2241 user_repo = get_temporary_dir();
2243 user_repo.push_back(
'/');
2244 if (
const char * user_repo_pattern = getenv(
"TDAQ_DB_USER_REPOSITORY_PATTERN"))
2245 user_repo.append(user_repo_pattern);
2247 user_repo.append(
"oks.XXXXXX");
2249 std::unique_ptr<char[]> dir_template(
new char[user_repo.size() + 1]);
2250 strcpy(dir_template.get(), user_repo.c_str());
2252 if (
char * tmp_dirname = mkdtemp(dir_template.get()))
2266 OksFile::Map::const_iterator i = files.find(&at);
2267 if(i != files.end())
return (*i).second;
2274 for(
const auto& f : files)
2276 if (s == f.second->get_short_file_name())
2313 const char _fname[] =
"k_load_schema";
2314 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, short_file_name,
nullptr, &parent_h);
2318 std::string full_file_name;
2323 catch (std::exception & e) {
2324 throw CanNotOpenFile(
"k_load_schema", short_file_name, e.what());
2339 std::shared_ptr<std::ifstream> f(
new std::ifstream(full_file_name.c_str()));
2342 throw std::runtime_error(
"k_load_schema(): cannot open file");
2347 fp =
new OksFile(xmls, short_file_name, full_file_name,
this);
2350 throw std::runtime_error(
"k_load_schema(): failed to read header of file");
2353 throw std::runtime_error(
"k_load_schema(): file is not oks schema file");
2369 catch (std::exception & e) {
2373 throw FailedLoadFile(
"schema file", full_file_name,
"caught unknown exception");
2391 std::cout <<
"(non-fully-qualified filename was \"" << fp->
get_short_file_name() <<
"\")\n";
2399 std::list<OksClass *>
set;
2412 if(c->get_name().empty()) {
2413 throw std::runtime_error(
"k_load_schema(): failed to read a class");
2416 OksClass::Map::const_iterator ic =
p_classes.find(c->get_name().c_str());
2418 bool are_different = (*ic->second != *c);
2420 c->p_transient =
true;
2424 static bool ers_report = (getenv(
"OKS_KERNEL_ERS_REPORT_DUPLICATED_CLASSES") !=
nullptr);
2429 const char _fname[] =
"k_load_schema";
2432 <<
" Class \"" << c->get_name() <<
"\" was already loaded from file \'" << c->get_file()->get_full_file_name() <<
"\'\n";
2436 std::stringstream text;
2437 text << (are_different ?
"different " :
"") <<
"class \"" << c->get_name() <<
"\" was already loaded from file \'" << c->get_file()->get_full_file_name() <<
'\'';
2438 throw std::runtime_error(text.str().c_str());
2451 fp->
p_size = xmls->get_position();
2456 for(std::list<OksClass *>::iterator i2 =
set.begin(); i2 !=
set.end(); ++i2)
2457 (*OksClass::create_notify_fn)(*i2);
2460 std::set<OksClass *> set2;
2462 for(std::list<OksClass *>::iterator i2 =
set.begin(); i2 !=
set.end(); ++i2) {
2464 if(c->p_all_sub_classes && !c->p_all_sub_classes->empty()) {
2465 for(OksClass::FList::iterator i3 = c->p_all_sub_classes->begin(); i3 != c->p_all_sub_classes->end(); ++i3) {
2466 if(set2.find(*i3) == set2.end()) {
2480 catch (std::exception & e) {
2492 const char _fname[] =
"new_schema";
2493 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, s,
nullptr,
nullptr);
2500 std::string file_name(s);
2513 throw std::runtime_error(
"the file is already loaded");
2516 OksFile * file_h =
new OksFile(file_name,
"",
"",
"schema",
this);
2527 catch (std::exception & e) {
2531 throw CanNotCreateFile(
"new_schema",
"schema file", file_name,
"caught unknown exception");
2577 std::cout <<
"Making backup of schema file \"" << pf->
p_full_name <<
"\"...\n";
2600 const char _fname[] =
"k_save_schema";
2606 std::string tmp_file_name;
2621 size_t numberOfClasses = 0;
2624 numberOfClasses =
classes->size();
2628 if(i->second->p_file == fh) numberOfClasses++;
2638 std::ofstream f(tmp_file_name.c_str());
2639 f.exceptions ( std::ostream::failbit | std::ostream::badbit );
2642 std::ostringstream text;
2643 text <<
"cannot create temporal file \'" << tmp_file_name <<
"\' to save schema";
2644 throw std::runtime_error(text.str().c_str());
2648 std::cout <<
"Saving " << numberOfClasses <<
" classes to schema file \"" << pf->
p_full_name <<
"\"...\n";
2665 std::ostringstream errors;
2666 bool found_errors =
false;
2672 found_errors |= i.second->check_relationships(errors,
false);
2673 i.second->save(xmls);
2680 if (i.second->p_file == fh)
2682 found_errors |= i.second->check_relationships(errors,
false);
2683 i.second->save(xmls);
2690 kernel::BindError ex(
ERS_HERE, errors.str());
2694 throw std::runtime_error(ex.what());
2704 xmls.
put_last_tag(
"oks-schema",
sizeof(
"oks-schema")-1);
2712 if(rename(tmp_file_name.c_str(), pf->
p_full_name.c_str())) {
2713 std::ostringstream text;
2714 text <<
"cannot rename \'" << tmp_file_name <<
"\' to \'" << pf->
p_full_name <<
'\'';
2715 throw std::runtime_error(text.str().c_str());
2718 tmp_file_name.erase(0);
2725 throw std::runtime_error(ex.
what());
2734 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
2737 catch (std::exception & ex) {
2739 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
2754 pf->
rename(short_name, long_name);
2762 const char _fname[] =
"save_as_schema";
2763 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, new_name,
nullptr, &pf);
2768 if(!new_name.length()) {
2769 throw std::runtime_error(
"the new filename is empty");
2791 catch (std::exception & ex) {
2811 TLOG_DEBUG(2) <<
"skip read-only schema file \'" << *(i->first) <<
'\'';
2856 std::cout << (pf->
p_included_by ?
" * c" :
"C") <<
"lose OKS schema \"" << pf->
p_full_name <<
"\"..." << std::endl;
2868 std::set<OksClass *> sorted;
2872 if(pf == c->p_file) sorted.insert(c);
2873 c->p_to_be_deleted =
true;
2876 for(std::set<OksClass *>::iterator j = sorted.begin(); j != sorted.end(); ++j) {
2884 TLOG_DEBUG(4) <<
"exit for file " << (
void *)pf;
2896 i->second->p_to_be_deleted =
true;
2917 TLOG_DEBUG(4) <<
"enter for file " << (
void *)f;
2951 TLOG_DEBUG(4) <<
"exit for file " << (
void *)f;
2954std::list<OksClass *> *
2957 std::string fname(
"OksKernel::create_list_of_schema_classes(");
2959 fname.push_back(
'\'');
2964 std::list<OksClass *> * clist =
nullptr;
2967 for(OksClass::Map::const_iterator i =
p_classes.begin(); i !=
p_classes.end(); ++i) {
2968 if(pf == i->second->p_file) {
2969 if(!clist && !(clist =
new std::list<OksClass *>())) {
2973 clist->push_back(i->second);
2991 for(OksFile::Map::const_iterator i = files.begin(); i != files.end(); ++i) {
2995 if(*ufs == 0) { *ufs =
new std::list<OksFile *>(); }
2996 (*ufs)->push_back(i->second);
2998 else if(fs == wr ) {
2999 if(*rfs == 0) { *rfs =
new std::list<OksFile *>(); }
3000 (*rfs)->push_back(i->second);
3024 std::list<OksFile *> * files[] =
3025 {
nullptr,
nullptr,
nullptr,
nullptr };
3027 std::set<OksFile *> * sets[] =
3033 for (
int i = 0; i < 4; ++i)
3034 if (std::list<OksFile *> * f = files[i])
3038 sets[i % 2]->insert(f->front());
3060 if(parents.insert(file).second ==
false) {
3061 text +=
"(ignoring circular dependency between included files...)\n";
3066 text += file->get_full_file_name();
3067 text +=
"\' includes:\n";
3075 std::set<const OksFile *> parents;
3078 bool has_no_parents(text.empty());
3081 text += file.get_full_file_name();
3082 text += (has_no_parents ?
"\' has problem:\n" :
"\' that has problem:\n");
3085 std::lock_guard lock(
p_mutex);
3091 std::lock_guard lock(
p_mutex);
3094 std::ostringstream s;
3097 s <<
"Found 1 error parsing OKS data:\n" << *
m_errors.begin();
3100 s <<
"Found " <<
m_errors.size() <<
" errors parsing OKS data:";
3102 for(std::list<std::string>::const_iterator i =
m_errors.begin(); i !=
m_errors.end(); ++i) {
3103 s <<
"\nERROR [" << j++ <<
"] ***: " << *i;
3133 m_fp->p_number_of_items = 0;
3137 m_fp->p_number_of_items++;
3147 catch (std::exception& ex) {
3174 for(OksFile::Map::const_iterator i = files.begin(); i != files.end(); ++i) {
3175 if(i->second == f)
return true;
3185 (*c)[o->
GetId()] = o;
3191 std::map< const OksClass *, map_str_t<OksObject *> * >::iterator i =
data.find(c);
3192 if(i !=
data.end()) {
3194 if(j != i->second->end()) {
3196 i->second->erase(j);
3197 if(i->second->empty()) {
3218 std::map<OksFile *, std::vector<std::string> > included;
3220 std::set<OksFile *>::const_iterator i;
3222 bool check_includes(
false);
3223 bool found_schema_files(
false);
3224 std::string file_names;
3228 for(std::set<OksFile *>::const_iterator fi = files_h.begin(); fi != files_h.end();) {
3230 found_schema_files =
true;
3233 Oks::error_msg(
"OksKernel::reload_data") <<
"file " << (
void *)(*fi) <<
" is not OKS data or schema file, skip..." << std::endl;
3234 files_h.erase(fi++);
3238 if(fi != files_h.begin()) file_names.append(
", ");
3239 file_names.push_back(
'\"');
3240 file_names.append((*fi)->get_full_file_name());
3241 file_names.push_back(
'\"');
3249 if(found_schema_files) {
3250 throw std::runtime_error(
"Reload of modified schema files is not supported");
3255 if(files_h.empty())
return;
3263 for(i = files_h.begin(); i != files_h.end(); ++i) {
3264 if((*i)->is_locked()) {
3269 for(OksObject::Set::const_iterator oi =
p_objects.begin(); oi !=
p_objects.end(); ++oi) {
3270 if((*oi)->file == *i) reload_objects.
put(*oi);
3278 std::set<OksFile *> new_files;
3280 for(i = files_h.begin(); i != files_h.end(); ++i) {
3292 if(!new_files.empty()) {
3293 TLOG_DEBUG(2) << new_files.size() <<
" new files will be loaded";
3296 for(i = new_files.begin(); i != new_files.end(); ++i) {
3305 std::set<OksFile *> files_to_be_closed;
3307 if(check_includes) {
3308 size_t num_of_closing_files = 0;
3315 std::map<std::string, OksFile *> good_files;
3318 if(files_to_be_closed.find(j->second) == files_to_be_closed.end()) {
3319 for(std::list<std::string>::iterator l = j->second->p_list_of_include_files.begin(); l != j->second->p_list_of_include_files.end(); ++l) {
3330 if(i->second->p_included_by && files_to_be_closed.find(i->second) == files_to_be_closed.end()) {
3331 TLOG_DEBUG(3) <<
"check the file \'" << i->second->get_full_file_name() <<
"\' is included";
3332 const std::string& s = i->second->get_full_file_name();
3340 std::map<std::string, OksFile *>::const_iterator j = good_files.find(s);
3342 if(j != good_files.end()) {
3346 files_to_be_closed.insert(f2);
3348 for(OksObject::Set::const_iterator oi =
p_objects.begin(); oi !=
p_objects.end(); ++oi) {
3349 if((*oi)->file == f2) {
3350 reload_objects.
put(*oi);
3354 if (files_h.erase(f2)) {
3366 if(num_of_closing_files == files_to_be_closed.size()) {
3370 num_of_closing_files = files_to_be_closed.size();
3375 TLOG_DEBUG(2) <<
"no changes in the list of includes";
3383 if(c->p_all_relationships && !c->p_all_relationships->empty()) {
3384 const unsigned int atts_num(c->number_of_all_attributes());
3389 for(std::list<OksRelationship *>::iterator i = c->p_all_relationships->begin(); i != c->p_all_relationships->end(); ++i, ++d) {
3391 if(r->get_is_composite() && r->get_is_exclusive()) {
3394 d->data.OBJECT->remove_RCR(
obj, r);
3398 for(OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
3422 for(i = files_h.begin(); i != files_h.end(); ++i) {
3423 std::shared_ptr<std::ifstream> f(
new std::ifstream((*i)->get_full_file_name().c_str()));
3427 OksFile fp(xmls, (*i)->get_short_file_name(), (*i)->get_full_file_name(),
this);
3432 std::cout <<
" * reading data file \"" << (*i)->get_full_file_name() <<
"\"..." << std::endl;
3437 ReadFileParams read_params( *i, *xmls, ((format ==
'X') ? 0 : &alias_table),
this, format, &reload_objects );
3448 (*i)->update_status_of_file();
3449 (*i)->p_is_updated =
false;
3462 oset.insert(ox->second);
3468 std::ostringstream text;
3469 text <<
"there are " << oset.size() <<
" removed objects:\n";
3471 for(OksObject::FSet::iterator x = oset.begin(); x != oset.end(); ++x) {
3472 text <<
" - object " << *x << std::endl;
3482 for(OksObject::FSet::const_iterator x2 = refs.begin(); x2 != refs.end(); ++x2) {
3483 TLOG_DEBUG(3) <<
"*** add object " << *x2 <<
" to the list of updated *** ";
3490 for(OksObject::FSet::iterator ox = oset.begin(); ox != oset.end(); ++ox) {
3494 TLOG_DEBUG(4) <<
"skip dangling object " << (
void *)o;
3498 TLOG_DEBUG(3) <<
"*** remove non-reloaded object " << o <<
" => " << (
void *)o <<
" ***";
3504 for(std::set<OksFile *>::const_iterator x = files_to_be_closed.begin(); x != files_to_be_closed.end(); ++x) {
3513 if (duplicated_objs_mode ==
true)
3515 for (
auto& o : reload_objects.
created)
3524 catch (std::exception & e) {
3544 TLOG_DEBUG( 1 ) <<
"remove file " << (*j)->get_full_file_name() ;
3552 TLOG_DEBUG( 1 ) <<
"restore file " << i->second->get_full_file_name() ;
3553 (*i->second) = (*j->second);
3576 const char _fname[] =
"k_load_data";
3577 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, short_file_name, &bind, &parent_h);
3581 std::string full_file_name;
3586 catch (std::exception & e) {
3597 Oks::warning_msg(fname) <<
" The file \'" << full_file_name <<
"\' was already loaded";
3603 std::shared_ptr<std::ifstream> f(
new std::ifstream(full_file_name.c_str()));
3606 throw std::runtime_error(
"k_load_data(): cannot open file");
3612 throw std::runtime_error(
"k_load_data(): file is empty");
3617 fp =
new OksFile(xmls, short_file_name, full_file_name,
this);
3620 throw std::runtime_error(
"k_load_data(): failed to read header of file");
3632 throw std::runtime_error(
"k_load_data(): file is not an oks data file");
3635 k_load_data(fp, format, xmls, file_length, bind, parent_h, pipeline);
3648 catch (std::exception & e) {
3665 std::cout << (parent_h ?
" * r" :
"R") <<
"eading data file \"" << fp->
get_full_file_name()
3666 <<
"\" in " << (format ==
'n' ?
"normal" : (format ==
'X' ?
"extended" :
"compact")) <<
" format (" << file_length <<
" bytes)...\n";
3668 std::cout <<
"(non-fully-qualified filename was \"" << fp->
get_short_file_name() <<
"\")\n";
3681 m_pipeline = pipeline;
3684 m_pipeline = pipeline_guard.get();
3716 catch (std::exception& e) {
3725 const char _fname[] =
"new_data";
3726 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, s,
nullptr,
nullptr);
3733 std::string file_name(s);
3746 throw std::runtime_error(
"the file is already loaded");
3761 catch (std::exception & e) {
3802 k_save_data(pf, ignoreBadObjects, true_file_h,
nullptr, force_defaults);
3832 std::cout <<
"Making backup of data file \"" << pf->
p_full_name <<
"\"...\n";
3856 const char _fname[] =
"k_save_data";
3862 std::string tmp_file_name;
3870 size_t numberOfObjects = 0;
3873 numberOfObjects =
objects->size();
3875 if(!ignoreBadObjects) {
3878 for(OksObject::FSet::const_iterator i =
objects->begin(); i !=
objects->end(); ++i) {
3879 errors += (*i)->report_dangling_references();
3882 if(!errors.empty()) {
3883 std::ostringstream text;
3884 text <<
"the file contains objects with dangling references:\n" << errors;
3885 throw std::runtime_error(text.str().c_str());
3892 std::set<OksFile *> includes;
3897 bool found_bad_object =
false;
3900 if((*i)->file == fh) {
3903 if((*i)->is_consistent(includes,
"WARNING") ==
false) {
3904 found_bad_object =
true;
3906 if((*i)->is_duplicated() ==
true) {
3908 Oks::error_msg(fname) <<
" The file contains duplicated object " << *i << std::endl;
3910 found_bad_object =
true;
3916 if(found_bad_object && ignoreBadObjects ==
false) {
3917 throw std::runtime_error(
"the file contains inconsistent/duplicated objects or misses includes");
3934 std::fstream f(pf->
p_full_name.c_str(), std::ios::in);
3940 std::fstream f2(pf->
p_full_name.c_str(), std::ios::out);
3943 std::ostringstream text;
3944 text <<
"cannot open file \'" << pf->
p_full_name <<
"\' for writing";
3945 throw std::runtime_error(text.str().c_str());
3956 std::ofstream f(tmp_file_name.c_str());
3958 f.exceptions ( std::ostream::failbit | std::ostream::badbit );
3961 std::ostringstream text;
3962 text <<
"cannot create temporal file \'" << tmp_file_name <<
"\' to save data";
3963 throw std::runtime_error(text.str().c_str());
3968 std::cout <<
"Saving " << numberOfObjects <<
" objects " << (force_defaults ?
"with enforced default values " :
"") <<
"to data file \"" << pf->
p_full_name <<
"\"...\n";
3983 for(OksClass::Map::const_iterator i =
p_classes.begin(); i !=
p_classes.end() && f.good(); ++i) {
3986 for(OksObject::Map::const_iterator j = i->second->p_objects->begin(); j != i->second->p_objects->end(); ++j) {
3988 sorted[j->first] = j->second;
3992 for(OksObject::SMap::iterator j = sorted.begin(); j != sorted.end(); ++j) {
3993 j->second->put(xmls, force_defaults);
4000 file_len = f.tellp();
4010 long written_len = 0;
4012 std::shared_ptr<std::ifstream> f(
new std::ifstream(tmp_file_name.c_str()));
4015 f->seekg(0, std::ios::end);
4016 written_len =
static_cast<std::streamoff
>(f->tellg());
4019 if(written_len != file_len) {
4020 unlink(tmp_file_name.c_str());
4021 std::ostringstream text;
4022 text <<
"write error in file \'" << tmp_file_name <<
"\': " << written_len <<
" bytes been written instead of " << file_len;
4023 throw std::runtime_error(text.str().c_str());
4031 if(
int code = stat(pf->
p_full_name.c_str(), &buf)) {
4032 std::ostringstream text;
4033 text <<
"cannot get information about file \'" << pf->
p_full_name <<
"\': stat() failed with code " << code <<
", reason = \'" <<
strerror(errno) <<
'\'';
4034 throw std::runtime_error(text.str().c_str());
4040 if(
int code = rename(tmp_file_name.c_str(), pf->
p_full_name.c_str())) {
4041 std::ostringstream text;
4042 text <<
"cannot rename file \'" << tmp_file_name <<
"\' to \'" << pf->
p_full_name <<
"\': rename() failed with code " << code <<
", reason = \'" <<
strerror(errno) <<
'\'';
4043 throw std::runtime_error(text.str().c_str());
4046 tmp_file_name.erase(0);
4054 throw std::runtime_error(ex.
what());
4064 if(
int code = stat(pf->
p_full_name.c_str(), &buf2)) {
4065 std::ostringstream text;
4066 text <<
"cannot get information about file \'" << pf->
p_full_name <<
"\': stat() failed with code " << code <<
", reason = \'" <<
strerror(errno) <<
'\'';
4067 throw std::runtime_error(text.str().c_str());
4073 if(buf.st_mode != buf2.st_mode) {
4074 if(
int code = chmod(pf->
p_full_name.c_str(), buf.st_mode) != 0) {
4075 std::ostringstream text;
4076 text <<
"cannot set protection mode for file \'" << pf->
p_full_name <<
"\': chmod() failed with code " << code <<
", reason = \'" <<
strerror(errno) <<
'\'';
4077 throw std::runtime_error(text.str().c_str());
4083 if(buf.st_gid != buf2.st_gid) {
4084 if(
int code = chown(pf->
p_full_name.c_str(), (gid_t)(-1), buf.st_gid) != 0) {
4093 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
4096 catch (std::exception & e) {
4098 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
4103 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
4118 pf->
rename(short_name, long_name);
4125 const char _fname[] =
"save_as_data";
4126 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, new_name,
nullptr, &pf);
4131 if(!new_name.length()) {
4132 throw std::runtime_error(
"the new filename is empty");
4156 catch (std::exception & ex) {
4174 k_save_data(i->second,
false,
nullptr,
nullptr, force_defaults);
4177 TLOG_DEBUG(2) <<
"skip read-only data file \'" << *(i->first) <<
'\'';
4199 const char _fname[] =
"k_close_data";
4218 for(OksObject::Set::const_iterator i =
p_objects.begin(); i !=
p_objects.end(); ++i) {
4228 while(!olist->empty()) {
4268 for(OksClass::Map::const_iterator i =
p_classes.begin(); i !=
p_classes.end(); ++i) {
4269 if(i->second->p_objects) {
4270 delete i->second->p_objects;
4271 i->second->p_objects = 0;
4292 TLOG_DEBUG(4) <<
"enter for file " << (
void *)fp;
4327 TLOG_DEBUG(4) <<
"leave for file " << (
void *)fp;
4331std::list<OksObject *> *
4334 const char _fname[] =
"create_list_of_data_objects";
4341 std::list<OksObject *> * olist =
new std::list<OksObject *>();
4344 for(OksObject::Set::const_iterator i =
p_objects.begin(); i !=
p_objects.end(); ++i) {
4345 if((*i)->file == fp) olist->push_back(*i);
4349 if(olist->empty()) {
4382 (*i)->bind_objects();
4389 const std::string error_text(strchr(ex.
what(),
'\n')+1);
4412 for(OksClass::Map::const_iterator i = all_classes.begin(); i != all_classes.end(); ++i) {
4415 for(OksObject::Map::const_iterator j = objs->begin(); j != objs->end(); ++j) {
4417 unsigned short l1 = c->number_of_all_attributes();
4418 unsigned short l2 = l1 + c->number_of_all_relationships();
4425 if(rm_objs.find(d->data.OBJECT) != rm_objs.end()) {
4427 const OksClass * __c(d->data.OBJECT->GetClass());
4428 const OksString& __id(d->data.OBJECT->GetId());
4430 TLOG_DEBUG(5) <<
"set relationship of " << o <<
": " << *d;
4434 for(OksData::List::const_iterator li = d->data.LIST->begin(); li != d->data.LIST->end(); ++li) {
4437 if(rm_objs.find(lid->
data.
OBJECT) != rm_objs.end()) {
4442 TLOG_DEBUG(5) <<
"set relationship of " << o <<
": " << *d;
4458 OksClass::Map::const_iterator i =
p_classes.find(name);
4459 return (i !=
p_classes.end() ? i->second : 0);
4466 TLOG_DEBUG(4) <<
"enter for class \"" << c->get_name() <<
'\"';
4478 c->p_file->p_is_updated =
true;
4495 TLOG_DEBUG(4) <<
"enter for class \"" << c->get_name() <<
'\"';
4508 if(
size_t num_of_classes =
p_classes.size()) {
4510 size_t array_size = num_of_classes *
sizeof(
OksClass*) /
sizeof(
wchar_t);
4512 OksClass::Map::iterator i =
p_classes.begin();
4513 unsigned long idx(0);
4515 for(; i !=
p_classes.end(); ++i) i->second->registrate_class(skip_registered);
4522 if(!c->p_all_sub_classes) c->p_all_sub_classes =
new OksClass::FList();
4523 else c->p_all_sub_classes->clear();
4531 for(OksClass::FList::const_iterator j = scl->begin(); j != scl->end(); ++j) {
4532 (*j)->p_all_sub_classes->push_back(c);
4540 if(!c->get_is_abstract()) {
4543 wmemset(
reinterpret_cast<wchar_t *
>(table), 0, array_size);
4544 for(OksClass::FList::const_iterator j1 = spc->begin(); j1 != spc->end(); ++j1) {
4546 for(OksClass::FList::const_iterator j2 = sbc->begin(); j2 != sbc->end(); ++j2) {
4549 table[c2->
p_id] = c2;
4555 unsigned int count(0);
4556 for(
unsigned int x = 0; x < num_of_classes; ++x) {
4557 if(table[x]) count++;
4561 std::vector<OksClass *> * cih;
4562 if(!c->p_inheritance_hierarchy) {
4563 cih = c->p_inheritance_hierarchy =
new std::vector<OksClass *>();
4566 cih = c->p_inheritance_hierarchy;
4570 cih->reserve(count);
4572 for(
unsigned int x = 0; x < num_of_classes; ++x) {
4573 if(table[x]) cih->push_back(table[x]);
4583 std::ostringstream s;
4586 if(std::vector<OksClass *> * cis = i->second->p_inheritance_hierarchy) {
4587 s <<
" - class \'" << i->second->get_name() <<
"\' shares IDs with " << cis->size() <<
" classes: ";
4589 for(std::vector<OksClass *>::const_iterator j = cis->begin(); j != cis->end(); ++j) {
4592 for(OksClass::Set::const_iterator j = sorted.begin(); j != sorted.end(); ++j) {
4593 if(j != sorted.begin()) s <<
", ";
4594 s <<
'\'' << (*j)->get_name() <<
'\'';
4600 TLOG_DEBUG(2) <<
"Schema inheritance hierarchy used to test objects with equal IDs:\n" << s.str();
4625 std::string fname(
"OksKernel::is_dangling(");
4628 fname +=
"?object?) returns true";
4631 fname += o->
GetId();
4632 fname +=
"\") returns false";
4648 bool not_found =
true;
4652 for(OksClass::Map::const_iterator i =
p_classes.begin(); i !=
p_classes.end(); ++i) {
4653 if(i->second == c) {
4662 std::string fname(
"OksKernel::is_dangling(");
4665 fname +=
"?class?) returns true";
4668 fname += c->get_name();
4669 fname +=
"\") returns false";
4682 for(std::vector<std::string>::const_iterator i = names_in.begin(); i != names_in.end(); ++i) {
4684 if(c != 0 && classes_out.find(c) == classes_out.end()) {
4685 classes_out.insert(c);
4687 for(OksClass::FList::const_iterator j = sc->begin(); j != sc->end(); ++j) {
4688 classes_out.insert(*j);
4729 throw RepositoryOperationFailed(op,
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
4740 std::ostringstream text;
4756 if(
int result = chdir(
p_dir)) {
4758 <<
"chdir (\'" <<
p_dir <<
"\') failed with code " << result <<
": " <<
strerror(errno) << std::endl;
4776 std::string cat2str()
const;
4777 std::string last_str()
const;
4779 void check_command_status(
int status);
4790 p_file_name = get_temporary_dir() +
'/' + command_name +
'.' + std::to_string(getpid()) +
':' + std::to_string(
reinterpret_cast<std::uintptr_t
>(k)) +
".txt";
4808 std::filebuf * buf = f.rdbuf();
4810 char c = buf->sbumpc();
4823 std::string lastline;
4827 f.seekg(-1, std::ios_base::end);
4828 if (f.peek() ==
'\n')
4830 f.seekg(-1, std::ios_base::cur);
4831 for (
int i = f.tellg(); i >= 0; i--)
4833 if (f.peek() ==
'\n')
4838 f.seekg(i, std::ios_base::beg);
4842 getline(f, lastline);
4853 std::ostringstream text;
4857 else if (
int error_code = WEXITSTATUS(status))
4859 std::ostringstream text;
4860 text <<
p_command.substr(0,
p_command.find_first_of(
' ')) <<
" exit with error code " << error_code <<
", output:\n" <<
cat2str();
4872 file_h->
rename(new_name);
4878 file_h->
rename(new_name);
4892 std::string cmd(
"oks-checkout.sh");
4904 cmd.push_back(
'\"');
4906 cmd.push_back(
'\"');
4909 if (!branch_name.empty())
4912 cmd.append(branch_name);
4915 auto start_usage = std::chrono::steady_clock::now();
4920 log_timestamp() <<
"[OKS checkout] => " << cmd << std::endl;
4931 std::cout << cmd_out.
cat2str();
4932 log_timestamp() <<
"[OKS checkout] => done in " << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now()-start_usage).count() / 1000. <<
" ms" << std::endl;
4935 static std::string version_prefix(
"checkout oks version ");
4937 std::string::size_type pos =
version.find(version_prefix);
4966 std::string cmd(
"oks-copy.sh");
4975 cmd.append(destination);
4980 auto start_usage = std::chrono::steady_clock::now();
4992 std::cout << cmd_out.
cat2str();
4993 log_timestamp() <<
"[OKS copy] => done in " << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now()-start_usage).count() / 1000. <<
" ms" << std::endl;
5004 throw RepositoryOperationFailed(
"update",
"the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5007 throw RepositoryOperationFailed(
"update",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5009 std::string cmd(
"oks-update.sh");
5018 cmd.append(
" --force");
5020 cmd.append(
" --merge");
5027 cmd.push_back(
'\"');
5029 cmd.push_back(
'\"');
5032 auto start_usage = std::chrono::steady_clock::now();
5044 static std::string version_prefix(
"update oks version ");
5046 std::string::size_type pos =
version.find(version_prefix);
5056 std::cout << cmd_out.
cat2str();
5057 log_timestamp() <<
"[OKS update] => done in " << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now()-start_usage).count() / 1000. <<
" ms" << std::endl;
5067 throw RepositoryOperationFailed(
"commit",
"the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5070 throw RepositoryOperationFailed(
"commit",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5072 std::string cmd(
"oks-commit.sh");
5080 if(comments.empty() || std::all_of(comments.begin(), comments.end(), [](
char c) { return std::isspace(c); }))
5083 const std::string log_file_name(get_temporary_dir() +
'/' +
"oks-commit-msg." + std::to_string(getpid()) +
':' + std::to_string(
reinterpret_cast<std::uintptr_t
>(
this)) +
".txt");
5087 std::ofstream f(log_file_name);
5089 f.exceptions(std::ostream::failbit | std::ostream::badbit);
5092 throw std::runtime_error(
"create message file failed");
5097 catch (
const std::exception& ex)
5099 std::ostringstream ss;
5100 ss <<
"cannot write to file \'" << log_file_name <<
"\' to save commit message: " << ex.what();
5104 cmd.append(
" -f \'");
5105 cmd.append(log_file_name);
5106 cmd.push_back(
'\'');
5168 auto start_usage = std::chrono::steady_clock::now();
5178 int status = system(cmd.c_str());
5180 unlink(log_file_name.c_str());
5182 if (!credentials.empty())
5183 unsetenv(
"OKS_COMMIT_USER");
5192 std::cout << cmd_out.
cat2str();
5193 log_timestamp() <<
"[OKS commit] => done in " << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now()-start_usage).count() / 1000. <<
" ms" << std::endl;
5196 static std::string version_prefix(
"commit oks version ");
5198 std::string::size_type pos =
version.find(version_prefix);
5212 throw RepositoryOperationFailed(
"tag",
"the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5215 throw RepositoryOperationFailed(
"tag",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5217 std::string cmd(
"oks-tag.sh");
5225 if(tag.empty() || std::all_of(tag.begin(), tag.end(), [](
char c) { return std::isspace(c); }))
5228 cmd.append(
" -t \'");
5230 cmd.append(
"\' -c \'");
5232 cmd.push_back(
'\'');
5234 auto start_usage = std::chrono::steady_clock::now();
5248 std::cout << cmd_out.
cat2str();
5249 log_timestamp() <<
"[OKS tag] => done in " << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now()-start_usage).count() / 1000. <<
" ms" << std::endl;
5253std::list<std::string>
5259 throw RepositoryOperationFailed(
"diff",
"the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5262 throw RepositoryOperationFailed(
"diff",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5264 std::string cmd(
"oks-diff.sh");
5272 if(!sha1.empty() && !sha2.empty())
5274 cmd.append(
" --sha ");
5281 cmd.append(
" --unmerged");
5287 std::string output = cmd_out.
cat2str();
5291 std::cout << output <<
"[OKS get_diff] => done" << std::endl;
5294 std::istringstream s(output);
5299 const char * diff_pattern =
"git diff --name-only ";
5301 while (std::getline(s, line))
5302 if (line.find(diff_pattern) == 0)
5310 std::ostringstream text;
5311 text <<
"cannot find \"" << diff_pattern <<
"\" pattern in output of oks-diff.sh:\n" << output;
5315 std::list<std::string> result;
5317 while (std::getline(s, line))
5318 result.push_back(line);
5326 for (
const auto& x : ver.
m_files)
5327 if (loaded_files.find(x) != loaded_files.end())
5333std::vector<OksRepositoryVersion>
5336 std::string cmd(
"oks-log.sh");
5344 cmd.append(command_line);
5349 std::string output = cmd_out.
cat2str();
5351 std::istringstream s(output);
5356 while (std::getline(s, line))
5357 if (line.find(
"git log ") == 0)
5365 std::ostringstream text;
5366 text <<
"cannot find \"git log\" pattern in output of oks-log.sh:\n" << output;
5370 std::set<std::string> loaded_files;
5372 if (skip_irrelevant)
5377 loaded_files.emplace(x.first->substr(len));
5380 loaded_files.emplace(x.first->substr(len));
5383 std::vector<OksRepositoryVersion> vec;
5388 while (std::getline(s, line))
5394 std::string::size_type idx1 = 0;
5395 std::string::size_type idx2 = line.find(
'|');
5397 if (idx2 != std::string::npos)
5401 idx2 = line.find(
'|', idx1);
5403 if (idx2 != std::string::npos)
5405 ver.
m_user = line.substr(idx1, idx2-idx1);
5407 idx2 = line.find(
'|', idx1);
5409 if (idx2 != std::string::npos)
5411 ver.
m_date = std::stol(line.substr(idx1, idx2-idx1));
5422 std::ostringstream text;
5423 text <<
"unexpected line \"" << line <<
"\" in output of oks-log.sh:\n" << output;
5433 if (skip_irrelevant &&
check_relevant(loaded_files, ver) ==
false)
5436 vec.emplace_back(ver);
5447 if (skip_irrelevant ==
false ||
check_relevant(loaded_files, ver))
5448 vec.emplace_back(ver);
5454std::vector<OksRepositoryVersion>
5457 std::string command_line;
5459 if(!since.empty() && !until.empty())
5461 command_line.push_back(
' ');
5462 command_line.append(since);
5463 command_line.append(
"..");
5464 command_line.append(until);
5466 else if(!since.empty())
5468 command_line.push_back(
' ');
5469 command_line.append(since);
5470 command_line.append(
"..origin/master");
5472 else if(!until.empty())
5474 command_line.append(
" ..");
5475 command_line.append(until);
5484 std::string
out(in);
5485 std::replace(
out.begin(),
out.end(),
' ',
'T');
5490std::vector<OksRepositoryVersion>
5493 std::string command_line;
5497 command_line.append(
" --since ");
5503 command_line.append(
" --until ");
5507 command_line.append(
" origin/master");
5519 throw RepositoryOperationFailed(
"status",
"the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5522 throw RepositoryOperationFailed(
"status",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5524 std::string cmd(
"oks-version.sh");
5532 std::string output = cmd_out.
cat2str();
5534 static std::string version_prefix(
"oks version ");
5536 std::string::size_type pos =
version.find(version_prefix);
5542 std::ostringstream text;
5543 text <<
"cannot read oks version from oks-version.sh output: \"" << output <<
'\"';
5556 throw RepositoryOperationFailed(
"status",
"the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5559 throw RepositoryOperationFailed(
"status",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5561 std::string cmd(
"oks-status.sh");
5569 std::string output = cmd_out.
cat2str();
5573 std::cout << output <<
"[OKS get_status] => done" << std::endl;
5576 std::istringstream s(output);
5581 const char * diff_pattern =
"git status --porcelain";
5583 while (std::getline(s, line))
5584 if (line.find(diff_pattern) == 0)
5592 std::ostringstream text;
5593 text <<
"cannot find \"" << diff_pattern <<
"\" pattern in output of oks-status.sh:\n" << output;
5597 std::list<std::string> result;
5599 while (std::getline(s, line))
5601 if (line.find(
" D ") == 0)
5602 removed.insert(line.substr(3));
5603 else if (line.find(
" M ") == 0)
5604 updated.insert(line.substr(3));
5605 else if (line.find(
"?? ") == 0)
5606 added.insert(line.substr(3));
5609 std::ostringstream text;
5610 text <<
"unexpected output \"" << line <<
"\" in output of oks-status.sh:\n" << output;
5717 std::ostringstream
out;
5720 c.second->check_relationships(
out,
true);
5729 auto now(std::chrono::system_clock::now());
5730 auto time_since_epoch(
now.time_since_epoch());
5731 auto seconds_since_epoch(std::chrono::duration_cast<std::chrono::seconds>(time_since_epoch));
5733 std::time_t now_t(std::chrono::system_clock::to_time_t(std::chrono::system_clock::time_point(seconds_since_epoch)));
5736 std::size_t len = std::strftime(buff, 128 - 16,
"%Y-%b-%d %H:%M:%S.", std::localtime(&now_t));
5737 sprintf(buff+len,
"%03d ", (
int)(std::chrono::duration_cast<std::chrono::milliseconds>(time_since_epoch).count() - seconds_since_epoch.count()*1000));
5739 std::ostream& s (severity <=
Warning ? std::cerr : std::cout);
5741 s << buff << (severity ==
Error ?
"ERROR " : severity ==
Warning ?
"WARNING " : severity ==
Debug ?
"DEBUG " :
"");
void operator<<(TraceStreamer &x, const ers::Issue &r)
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
static std::string fill(const char *prefix, const std::string &name, const std::string &reason) 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
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
static NotifyFN create_notify_fn
std::list< OksClass *, boost::fast_pool_allocator< OksClass * > > FList
static NotifyFN delete_notify_fn
static ChangeNotifyFN change_notify_fn
std::map< const char *, OksClass *, SortStr > Map
std::set< OksClass *, SortByName > Set
Provides interface to the OKS XML schema and data files.
const std::string & get_logical_name() const
void unlock()
Unlock OKS file.
void get_all_include_files(const OksKernel *kernel, std::set< OksFile * > &out)
Get all include files.
void lock()
Lock OKS file.
void write(OksXmlOutputStream &)
std::unordered_map< OksFile *, Set, oks::hash_file_ptr, oks::equal_file_ptr > IMap
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
void update_status_of_file(bool update_local=true, bool update_repository=true)
Update status of file.
std::map< const std::string *, OksFile *, SortByName > Map
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
const std::string & get_full_file_name() const
std::unordered_set< OksFile *, oks::hash_file_ptr, oks::equal_file_ptr > Set
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)
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.
static std::string p_repository_mapping_dir
OksFile * find_file(const std::string &s, const OksFile::Map &files) const
std::vector< OksFile * > p_preload_added_files
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::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
std::map< const OksFile *, OksFile * > p_preload_file_info
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)
OKS method implementation class.
OksObject describes instance of OksClass.
struct dunedaq::oks::OksObject::OksUid uid
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
static OksObject * read(const oks::ReadFileParams &)
void unbind_file(const OksFile *)
const OksClass * GetClass() const
void remove_RCR(OksObject *, const OksRelationship *) noexcept
std::map< const std::string *, OksObject *, SortById > SMap
std::unordered_map< const std::string *, OksObject *, oks::hash_str, oks::equal_str > Map
const std::string & GetId() const
@ KernelCreateSchemaClassList
@ KernelCreateDataObjectList
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.
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,...)
#define ERS_DECLARE_ISSUE( namespace_name, class_name, message_, attributes)
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)
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
Monitoring thread not set
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
OksObject * pop(const OksClass *c, const std::string &id)
std::map< std::string, T > map_str_t
std::vector< OksObject * > created
std::map< const OksClass *, map_str_t< OksObject * > * > data
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