82 std::filesystem::remove_all(path);
84 catch (std::exception &ex)
86 Oks::error_msg(
"OksKernel::~OksKernel") <<
"cannot remove user repository \"" << path <<
"\"" << ex.what() << std::endl;
118 return std::string(strerror_r(
error, buffer, 1024));
125 "cannot set group ID " <<
id <<
" for the file \'" << file <<
"\': chown() failed with code " << code <<
" , reason = \'" << why <<
'\'',
135 "Found unresolved reference(s):\n" << which,
142 "class \"" << name <<
"\" is defined in files \"" << f1 <<
"\" and \"" << f2 <<
"\"",
151 "internal error: " << text,
156 CanNotOpenFile::fill(
const char * prefix,
const std::string& name,
const std::string& reason)
noexcept
158 std::string result(prefix);
161 if(name.empty())
return (result +
"file name is empty");
163 result +=
"cannot load file \'" + name +
'\'' ;
165 if(!reason.empty()) {
166 result +=
" because:\n" + reason;
173 FailedLoadFile::fill(
const std::string& what,
const std::string& name,
const std::string& reason)
noexcept
175 return (std::string(
"Failed to load ") + what +
" \"" + name +
"\" because:\n" + reason);
181 return (std::string(
"Failed to re-load file(s) ") + names +
" because:\n" + reason);
187 return (std::string(
"Failed to ") + op +
" file(s) because:\n" + reason);
191 CanNotCreateFile::fill(
const char * prefix,
const char * what,
const std::string& name,
const std::string& reason)
noexcept
193 return std::string(prefix) +
"(): failed to create new " + what +
" \'" + name +
"\' because:\n" +
reason;
199 return std::string(prefix) +
"(): failed to create user repository dir, mkdtemp(\'" + name +
"\') failed: " +
strerror(errno);
203 CanNotWriteToFile::fill(
const char * prefix,
const char * item,
const std::string& name,
const std::string& reason)
noexcept
205 return (std::string(prefix) +
"(): failed to write " + item +
" to \'" + name +
"\' because:\n" + reason);
211 return (std::string(
"Failed to make a backup file of \'") + name +
"\' because:\n" + reason);
217 return (std::string(
"Failed to set active ") + item +
" file \'" + name +
"\' because:\n" + reason);
223 std::ostringstream
s;
224 s <<
"Failed to move ";
225 if(c)
s <<
"class " <<
c->get_name();
226 else s <<
"object " << o;
227 s <<
" to file \'" <<
file.get_full_file_name() <<
"\' because:\n" <<
reason;
234 return (std::string(
"Cannot add class \'") +
c.get_name() +
"\' because:\n" + reason);
240 std::ostringstream text;
241 text <<
"realpath(\'" << path <<
"\') has failed with code " << error_code <<
": \'" <<
strerror(error_code) <<
'\'';
246 static const std::string&
249 static std::string s_dir;
250 static std::once_flag flag;
252 std::call_once(flag, []()
256 if (!getenv(
"OKS_GIT_NO_VAR_DIR"))
258 OksSystem::User myself;
260 s_dir =
"/var/run/user/";
261 s_dir.append(std::to_string(myself.
identity()));
263 if (std::filesystem::is_directory(s_dir) ==
false)
265 TLOG_DEBUG(1) <<
"directory " << s_dir <<
" does not exist";
270 const std::filesystem::space_info si = std::filesystem::space(s_dir);
271 const double available =
static_cast<double>(si.available) /
static_cast<double>(si.capacity);
275 TLOG_DEBUG(1) <<
"usage of " << s_dir <<
" is " <<
static_cast<int>((1.0 - available) * 100.0) <<
"%, will use standard temporary path";
282 s_dir = std::filesystem::temp_directory_path().string();
284 catch (std::exception& ex)
286 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot get temporary directory path: " << ex.what() << std::endl;
299 return "862f2957270";
306 static std::once_flag flag;
308 std::call_once(flag, []()
310 if (
const char * s = getenv(
"TDAQ_DB_REPOSITORY"))
314 if (!std::all_of(rep.begin(), rep.end(), [](
char c) { return std::isspace(c); }))
316 const char * p = getenv(
"OKS_GIT_PROTOCOL");
328 if (token.find(p) == 0)
340 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot find OKS_GIT_PROTOCOL=\"" << p <<
"\" in TDAQ_DB_REPOSITORY=\"" << rep <<
'\"' << std::endl;
352 static std::once_flag flag;
354 std::call_once(flag, []()
356 if (
const char * s = getenv(
"OKS_REPOSITORY_MAPPING_DIR"))
376 if(
const char * s = getenv(
"TDAQ_DB_USER_REPOSITORY")) {
392 TLOG_DEBUG( 1) <<
"Failed to set user-repository-root:\n\tcaused by: repository-root is not set" ;
409 TLOG_DEBUG( 1) <<
"Failed to set user-repository-root = \'" << s <<
"\':\n\tcaused by: " << ex.
what() ;
412 for(std::string::size_type idx = s.size()-1; idx > 0 && s[idx] ==
'/' ; idx--) {
431 static std::string s_host_name;
432 static std::once_flag flag;
434 std::call_once(flag, []()
438 if (s_host_name.empty())
439 s_host_name =
"unknown.host";
449 static std::string s_domain_name;
450 static std::once_flag flag;
452 std::call_once(flag, []()
456 if (idx != std::string::npos)
459 if (s_domain_name.empty())
460 s_domain_name =
"unknown.domain";
464 return s_domain_name;
470 static std::string s_user_name;
471 static std::once_flag flag;
473 std::call_once(flag, []()
478 if (s_user_name.empty())
479 s_user_name =
"unknown.user";
492 long file_length = 0;
496 f.seekg(0, std::ios::end);
499 file_length =
static_cast<std::streamoff
>(f.tellg());
501 file_length = f.tellg();
504 f.seekg(0, std::ios::beg);
512make_fname(
const char * f,
size_t f_len,
const std::string& file,
bool * p,
const OksFile *
const * fh)
514 const char _prefix [] =
"OksKernel::";
515 std::string fname(_prefix, (
sizeof(_prefix)-1));
517 fname.append(f, f_len);
519 const char _x1 [] =
"(file \'";
520 fname.append(_x1, (
sizeof(_x1)-1));
522 fname.push_back(
'\'');
528 const char _true_str [] =
", true";
529 fname.append(_true_str, (
sizeof(_true_str)-1));
532 const char _false_str [] =
", false";
533 fname.append(_false_str, (
sizeof(_false_str)-1));
540 const char _x2 [] =
", included by file \'";
541 fname.append(_x2, (
sizeof(_x2)-1));
542 fname.append((*fh)->get_full_file_name());
543 fname.push_back(
'\'');
546 fname.push_back(
')');
558 std::cerr <<
"ERROR [" << msg <<
"]:\n";
return std::cerr;
565 std::cerr <<
"WARNING [" << msg <<
"]:\n";
return std::cerr;
572 std::string::size_type pos = 0;
573 std::string::size_type p_start = 0;
574 std::string::size_type p_end = 0;
577 ((p_start = s.find(
"$(", pos)) != std::string::npos) &&
578 ((p_end = s.find(
")", p_start + 2)) != std::string::npos)
580 std::string var(s, p_start + 2, p_end - p_start - 2);
582 char *
env = getenv(var.c_str());
585 s.replace(p_start, p_end - p_start + 1,
env);
596 char resolved_name[PATH_MAX];
598 if(realpath(path.c_str(), resolved_name) != 0) {
599 path = resolved_name;
604 TLOG_DEBUG( 3) <<
"realpath(\'" << path <<
"\') has failed with code " << errno <<
": \'" <<
strerror(errno) <<
'\'' ;
616 "abcdefghijklmnoprstuvwxyz"
617 "ABCDEFGHIJKLMNOPRSTUVWXYZ";
623 static const size_t slen(
sizeof(
symbols)-1);
624 static const size_t slen2(slen*slen);
626 char b[16], *buf = b;
632 if((
size_t)
count >= slen) {
635 if((
size_t)
count >= slen2) {
669 std::ostringstream s;
671 while(j++ < 1000000) {
677 std::ofstream f(s2.c_str(), std::ios::in);
682 std::string s3(file);
696 long size = pathconf(
".", _PC_PATH_MAX);
699 Oks::error_msg(
"OksKernel::OksKernel") <<
"pathconf(\".\", _PC_PATH_MAX) has failed with code " << errno <<
": \'" <<
strerror(errno) <<
'\'' << std::endl;
710 Oks::error_msg(
"OksKernel::OksKernel") <<
"getcwd() has failed with code " << errno <<
": \'" <<
strerror(errno) <<
'\'' << std::endl;
754 OSK_VERBOSE_REPORT(
"Enter OksKernel::OksKernel(" << sm <<
", " << vm <<
", " << tm <<
')')
756 struct __InitFromEnv__ {
770 for(
unsigned int i = 0; i <
sizeof(vars) /
sizeof(__InitFromEnv__); ++i) {
771 if(
char * s = getenv(vars[i].name)) {
772 vars[i].value = (strcmp(s,
"no")) ?
true :
false;
777 const char * oks_db_root = getenv(
"OKS_DB_ROOT");
779 if (oks_db_root ==
nullptr || *oks_db_root == 0)
780 oks_db_root = getenv(
"DUNEDAQ_DB_PATH");
784 OSK_VERBOSE_REPORT(
"database root = \'" << oks_db_root <<
"\' (as defined by the OKS_DB_ROOT or DUNEDAQ_DB_PATH)");
789 if (oks_db_root ==
nullptr)
798 while (t.
next(token))
818 static std::once_flag flag;
820 std::call_once(flag, []()
822 if (
char * s = getenv(
"OKS_KERNEL_THREADS_POOL_SIZE"))
838 Oks::error_msg(
"OksKernel::OksKernel()") <<
" sysconf(_SC_NPROCESSORS_ONLN) has failed with code " << errno <<
": \'" <<
strerror(errno) <<
'\'' << std::endl;
858 std::string param, val;
861 version = getenv(
"TDAQ_DB_VERSION");
867 if(
const char * value = strchr(
version,
':'))
873 Oks::error_msg(
"OksKernel::OksKernel") <<
"bad version value \"" <<
version <<
"\" expecting parameter:value format (check TDAQ_DB_VERSION variable)" << std::endl;
885 if (branch_name.empty())
886 if (
const char *var = getenv(
"TDAQ_DB_BRANCH"))
893 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot check out user repository: " << ex.
what() << std::endl;
907 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot read user repository version: " << ex.
what() << std::endl;
962 Oks::error_msg(
"OksKernel::OksKernel") <<
"cannot copy user repository: " << ex.
what() << std::endl;
978 const OksFile::Map * src_files[2] = { &src.p_schema_files, &src.p_data_files };
979 OksFile::Map * dst_files[2] = { &p_schema_files, &p_data_files };
981 for (
int i = 0; i < 2; ++i)
983 for (
const auto& j : *src_files[i])
987 (*dst_files[i])[&f->p_full_name] = f;
998 for(
const auto& i : src.p_classes) {
1000 OksClass * c =
new OksClass (src_c.p_name, src_c.p_description, src_c.p_abstract,
nullptr, src_c.p_transient);
1003 p_classes[c->get_name().c_str()] = c;
1005 const_cast<OksClass&
>(src_c).p_id = idx++;
1006 c->p_id = src_c.p_id;
1007 c_table[c->p_id] = c;
1009 c->p_abstract = src_c.p_abstract;
1010 c->p_to_be_deleted = src_c.p_to_be_deleted;
1011 c->p_instance_size = src_c.p_instance_size;
1012 c->p_file = (*p_schema_files.find(&src_c.p_file->p_full_name)).second;
1013 c->p_objects = (src_c.p_objects ?
new OksObject::Map() : nullptr);
1017 if (
const std::list<std::string *> * scls = src_c.p_super_classes)
1019 c->p_super_classes = new std::list<std::string *>();
1021 for (const auto& j : *scls)
1022 c->p_super_classes->push_back(new std::string(*j));
1027 if (
const std::list<OksAttribute *> * attrs = src_c.p_attributes)
1029 c->p_attributes = new std::list<OksAttribute *>();
1031 for (const auto& j : *attrs)
1033 OksAttribute * a = new OksAttribute(j->p_name, c);
1035 a->p_range = j->p_range;
1036 a->p_data_type = j->p_data_type;
1037 a->p_multi_values = j->p_multi_values;
1038 a->p_no_null = j->p_no_null;
1039 a->p_init_value = j->p_init_value;
1040 a->p_init_data = j->p_init_data;
1041 a->p_format = j->p_format;
1042 a->p_description = j->p_description;
1044 if (j->p_enumerators)
1045 a->p_enumerators = new std::vector<std::string>(*j->p_enumerators);
1047 c->p_attributes->push_back(a);
1053 if (
const std::list<OksRelationship *> * rels = src_c.p_relationships)
1055 c->p_relationships =
new std::list<OksRelationship *>();
1057 for (
const auto& j : *rels)
1059 OksRelationship * r =
new OksRelationship(j->p_name, c);
1061 r->p_rclass = j->p_rclass;
1062 r->p_low_cc = j->p_low_cc;
1063 r->p_high_cc = j->p_high_cc;
1064 r->p_composite = j->p_composite;
1065 r->p_exclusive = j->p_exclusive;
1066 r->p_dependent = j->p_dependent;
1067 r->p_description = j->p_description;
1069 c->p_relationships->push_back(r);
1075 if (
const std::list<OksMethod *> * mets = src_c.p_methods)
1077 c->p_methods =
new std::list<OksMethod *>();
1079 for (
const auto& j : *mets)
1083 if (
const std::list<OksMethodImplementation *> * impls = j->p_implementations)
1085 m->p_implementations =
new std::list<OksMethodImplementation *>();
1087 for (
const auto& x : *impls)
1088 m->p_implementations->push_back(
new OksMethodImplementation(x->get_language(), x->get_prototype(), x->get_body(), m));
1091 c->p_methods->push_back(m);
1099 for (
const auto& i : src.p_classes)
1101 OksClass *
c = c_table[i.second->p_id];
1104 if (
const std::list<OksRelationship *> * rels = i.second->p_relationships)
1106 for (
const auto& j : *rels)
1107 c->find_relationship(j->get_name())->p_class_type = (j->p_class_type ? c_table[j->p_class_type->p_id] :
nullptr);
1111 if (
const OksClass::FList * spcls = i.second->p_all_super_classes)
1113 c->p_all_super_classes =
new OksClass::FList();
1115 for (
const auto& j : *spcls)
1116 c->p_all_super_classes->push_back(c_table[j->p_id]);
1119 if (
const OksClass::FList * sbcls = i.second->p_all_sub_classes)
1121 c->p_all_sub_classes =
new OksClass::FList();
1123 for (
const auto& j : *sbcls)
1124 c->p_all_sub_classes->push_back(c_table[j->p_id]);
1128 c->p_data_info =
new OksDataInfo::Map();
1129 size_t instance_size = 0;
1132 if (
const std::list<OksAttribute *> * attrs = i.second->p_all_attributes)
1134 c->p_all_attributes =
new std::list<OksAttribute *>();
1136 for (
const auto& j : *attrs)
1138 OksAttribute * a = (c_table[j->p_class->p_id])->find_direct_attribute(j->get_name());
1139 c->p_all_attributes->push_back(a);
1140 (*
c->p_data_info)[a->get_name()] =
new OksDataInfo(instance_size++, a);
1145 if (
const std::list<OksRelationship *> * rels = i.second->p_all_relationships)
1147 c->p_all_relationships =
new std::list<OksRelationship *>();
1149 for (
const auto& j : *rels)
1151 OksRelationship *
r = (c_table[j->p_class->p_id])->find_direct_relationship(j->get_name());
1152 c->p_all_relationships->push_back(r);
1153 (*
c->p_data_info)[
r->get_name()] =
new OksDataInfo(instance_size++, r);
1158 if (
const std::list<OksMethod *> * mets = i.second->p_all_methods)
1160 c->p_all_methods =
new std::list<OksMethod *>();
1162 for (
const auto& j : *mets)
1163 c->p_all_methods->push_back((c_table[j->p_class->p_id])->find_direct_method(j->get_name()));
1167 if (
const std::vector<OksClass *> * ih = i.second->p_inheritance_hierarchy)
1169 c->p_inheritance_hierarchy =
new std::vector<OksClass *>();
1170 c->p_inheritance_hierarchy->reserve(ih->size());
1172 for (
const auto& j : *ih)
1173 c->p_inheritance_hierarchy->push_back(c_table[j->p_id]);
1180 if(!src.p_objects.empty()) {
1185 OksObject ** o_table =
new OksObject * [src.p_objects.size()];
1190 for(OksObject::Set::const_iterator i = src.p_objects.begin(); i != src.p_objects.end(); ++i, ++idx) {
1191 OksObject * src_o(*i);
1192 src_o->p_user_data =
reinterpret_cast<void *
>(idx);
1194 OksClass *
c = c_table[src_o->uid.class_id->p_id];
1196 OksObject * o =
new OksObject(
1198 src_o->uid.object_id,
1201 src_o->p_duplicated_object_id_idx,
1202 (*p_data_files.find(&src_o->file->p_full_name)).second
1206 (*
c->p_objects)[&o->uid.object_id] = o;
1207 p_objects.insert(o);
1209 if(
size_t num_of_attrs =
c->number_of_all_attributes()) {
1210 const OksData * src_data = src_o->data;
1211 OksData * dst_data = o->data;
1213 std::list<OksAttribute *>::const_iterator ia_dst =
c->all_attributes()->begin();
1214 std::list<OksAttribute *>::const_iterator ia_src = src_o->uid.class_id->all_attributes()->begin();
1216 for(
size_t j = 0; j < num_of_attrs; ++j) {
1217 *dst_data = *src_data;
1219 OksAttribute * a_dst(*ia_dst);
1223 if(a_dst->get_data_type() == OksData::class_type) {
1224 if(a_dst->get_is_multi_values() ==
false) {
1225 dst_data->data.CLASS = c_table[src_data->data.CLASS->p_id];
1228 OksData::List::iterator li_dst = dst_data->data.LIST->begin();
1229 OksData::List::iterator li_src = src_data->data.LIST->begin();
1231 while(li_dst != dst_data->data.LIST->end()) {
1232 (*li_dst)->data.CLASS = c_table[(*li_src)->data.CLASS->p_id];
1241 else if(a_dst->get_data_type() == OksData::enum_type) {
1242 OksAttribute * a_src(*ia_src);
1243 const std::string * p_enumerators_first(&((*(a_src->p_enumerators))[0]));
1245 if(a_dst->get_is_multi_values() ==
false) {
1246 unsigned long dx = src_data->data.ENUMERATION - p_enumerators_first;
1247 dst_data->data.ENUMERATION = &((*(a_dst->p_enumerators))[dx]);
1250 OksData::List::iterator li_dst = dst_data->data.LIST->begin();
1251 OksData::List::iterator li_src = src_data->data.LIST->begin();
1253 while(li_dst != dst_data->data.LIST->end()) {
1254 unsigned long dx = (*li_src)->data.ENUMERATION - p_enumerators_first;
1255 (*li_dst)->data.ENUMERATION = &((*(a_dst->p_enumerators))[dx]);
1274 for(
const auto& src_o : src.p_objects) {
1275 OksClass *
c = c_table[src_o->uid.class_id->p_id];
1276 OksObject * o(o_table[
reinterpret_cast<unsigned long>(src_o->p_user_data)]);
1278 if(
size_t num_of_rels =
c->number_of_all_relationships()) {
1279 const OksData * src_data(src_o->data +
c->number_of_all_attributes());
1280 OksData * dst_data(o->data +
c->number_of_all_attributes());
1282 for(
size_t j = 0; j < num_of_rels; ++j) {
1283 dst_data->type = src_data->type;
1284 switch(src_data->type) {
1285 case OksData::list_type:
1286 dst_data->data.LIST =
new OksData::List();
1287 for(
const auto& x : *src_data->data.LIST) {
1288 OksData *
d =
new OksData();
1290 if(x->type == OksData::object_type)
1292 if(
const OksObject * o2 = x->data.OBJECT)
1294 d->Set(o_table[
reinterpret_cast<unsigned long>(o2->p_user_data)]);
1298 d->Set((OksObject *)
nullptr);
1301 else if(x->type == OksData::uid_type)
1303 d->Set(c_table[x->data.UID.class_id->p_id], *x->data.UID.object_id);
1305 else if(x->type == OksData::uid2_type)
1307 d->Set(*x->data.UID2.class_id, *x->data.UID2.object_id);
1311 ers::error(kernel::InternalError(
ERS_HERE,
"unexpected data type in relationship list"));
1314 dst_data->data.LIST->push_back(d);
1318 case OksData::object_type:
1319 if(
const OksObject * o2 = src_data->data.OBJECT) {
1320 dst_data->data.OBJECT = o_table[
reinterpret_cast<unsigned long>(o2->p_user_data)];
1323 dst_data->data.OBJECT = 0;
1327 case OksData::uid_type:
1328 dst_data->data.UID.class_id = c_table[src_data->data.UID.class_id->p_id];
1329 dst_data->data.UID.object_id =
new OksString(*src_data->data.UID.object_id);
1332 case OksData::uid2_type:
1333 dst_data->data.UID2.class_id =
new OksString(*src_data->data.UID2.class_id);
1334 dst_data->data.UID2.object_id =
new OksString(*src_data->data.UID2.object_id);
1347 if (
const std::list<OksRCR *> * src_rcrs = src_o->p_rcr)
1349 o->p_rcr =
new std::list<OksRCR *>();
1351 for (
const auto& j : *src_rcrs)
1352 o->p_rcr->push_back(
1354 o_table[
reinterpret_cast<unsigned long>(j->obj->p_user_data)],
1355 (c_table[j->relationship->p_class->p_id])->find_direct_relationship(j->relationship->get_name())
1371 if (copy_repository && p_user_repository_root_inited)
1373 OksFile::Map * files_map[2] = { &p_schema_files, &p_data_files };
1375 for (
int i = 0; i < 2; ++i)
1377 std::vector<OksFile *> files;
1379 for (
auto& f : *files_map[i])
1380 files.push_back(
f.second);
1382 files_map[i]->clear();
1384 for (
auto& f : files)
1386 std::string name = p_user_repository_root;
1387 name.push_back(
'/');
1388 name.append(
f->get_repository_name());
1390 (*files_map[i])[&
f->p_full_name] = f;
1411 std::cout <<
" * push " << (push_back ?
"back" :
"front") <<
" repository search directory \'" << s <<
"\'\n";
1417 TLOG_DEBUG( 1) <<
"Cannot insert repository dir \'" << dir <<
"\':\n\tcaused by: " << ex ;
1431 std::cout <<
" * remove repository search directory \'" << dir <<
"\'\n";
1496 s <<
"OKS KERNEL DUMP:\n" <<
"OKS VERSION: " << k.
GetVersion() << std::endl;
1500 s <<
" Loaded schema:\n";
1503 s <<
" " << i.second->get_full_file_name() << std::endl;
1507 s <<
" Loaded data:\n";
1510 s <<
" " << j.second->get_full_file_name() << std::endl;
1513 s <<
" No loaded data files\n";
1517 s <<
" The classes:\n";
1524 s <<
" No loaded schema files\n";
1526 s <<
"END OF OKS KERNEL DUMP.\n";
1534 static std::string suffix;
1535 static std::once_flag flag;
1537 std::call_once(flag, []()
1539 std::ostringstream s;
1549 static std::mutex p_check_read_only_mutex;
1550 std::lock_guard scoped_lock(p_check_read_only_mutex);
1553 std::ofstream f(s.c_str(), std::ios::out);
1573 std::shared_ptr<std::ifstream> f(
new std::ifstream(full_path.c_str()));
1577 file_h =
new OksFile(xmls, short_path, full_path,
this);
1599 bool file_exists =
false;
1603 if(stat(file_name.c_str(), &buf) == 0) {
1605 Oks::warning_msg(fname) <<
" File \"" << file_name <<
"\" already exists\n";
1615 std::ofstream f(file_name.c_str());
1620 throw std::runtime_error(
"cannot open file in write mode");
1623 throw std::runtime_error(
"cannot create file");
1630 std::cout <<
"Creating new " << msg <<
" file \"" << file_name <<
"\"..." << std::endl;
1637 const char _s1_str[] =
" - \'";
1638 const char _s2_str[] =
"\' tested as ";
1640 return ((std::string(_s1_str,
sizeof(_s1_str)-1) + name).append(_s2_str,
sizeof(_s2_str)-1)).append(test, test_len);
1644#define TEST_PATH_TOKEN(path, file, msg) \
1645std::string token(path); \
1646token.push_back('/'); \
1647token.append(file); \
1648Oks::substitute_variables(token); \
1649if(Oks::real_path(token, true)) { \
1650 TLOG_DEBUG(2) << fname << " returns \'" << token << "\' (filename relative to " << msg << " database repository directory)"; \
1654 const char _test_name[] = "relative to database repository directory"; \
1655 tested_files.push_back(mk_name_and_test(token, _test_name, sizeof(_test_name)-1)); \
1664 const char _fname[] =
"get_file_path";
1669 std::list<std::string> tested_files;
1672 bool is_absolute_path =
false;
1676 fname =
make_fname(_fname,
sizeof(_fname) - 1, s2,
nullptr, &file_h);
1680 is_absolute_path =
true;
1683 if (is_absolute_path || file_h == 0)
1687 std::string s3 =
s_cwd;
1704 TLOG_DEBUG(2) << fname <<
" returns external \'" << s2 <<
"\' (an absolute filename or relative to CWD=\'" <<
s_cwd <<
"\')";
1708 std::ostringstream text;
1709 text << fname <<
" file does not belong to oks git repository\n"
1710 "provide file repository name, or unset TDAQ_DB_REPOSITORY and try again with the DUNEDAQ_DB_PATH environment variable";
1711 throw std::runtime_error(text.str().c_str());
1715 TLOG_DEBUG(2) << fname <<
" returns \'" << s2 <<
"\' (an absolute filename or relative to CWD=\'" <<
s_cwd <<
"\')";
1721 if (is_absolute_path)
1723 const char _test_name[] =
"an absolute file name";
1724 tested_files.push_back(
mk_name_and_test(s2, _test_name,
sizeof(_test_name) - 1));
1728 const char _test_name[] =
"relative to current working directory";
1729 tested_files.push_back(
mk_name_and_test(s2, _test_name,
sizeof(_test_name) - 1));
1742 if (!is_absolute_path)
1749 if (file_h && !is_absolute_path)
1752 std::string::size_type pos = s2.find_last_of(
'/');
1754 if (pos != std::string::npos)
1762 TLOG_DEBUG(2) << fname <<
" returns \'" << s2 <<
"\' (filename relative to parent file)";
1767 const char _test_name[] =
"relative to parent file";
1768 tested_files.push_back(
mk_name_and_test(s2, _test_name,
sizeof(_test_name) - 1));
1774 TLOG_DEBUG(2) << fname <<
" throw exception (file was not found)";
1776 std::ostringstream text;
1777 text << fname <<
" found no readable file among " << tested_files.size() <<
" tested:\n";
1778 for (
auto & i : tested_files)
1779 text << i << std::endl;
1781 throw std::runtime_error(text.str().c_str());
1800 const char _fname[] =
"k_load_file";
1801 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, short_file_name, &bind, &parent_h);
1805 std::string full_file_name;
1810 catch (std::exception & e) {
1818 OksFile::Map::const_iterator i =
p_schema_files.find(&full_file_name);
1819 if(i !=
p_schema_files.end())
return i->second->check_parent(parent_h);
1822 if(i !=
p_data_files.end())
return i->second->check_parent(parent_h);
1824 std::shared_ptr<std::ifstream> f(
new std::ifstream(full_file_name.c_str()));
1830 throw std::runtime_error(
"k_load_file(): file is empty");
1837 OksFile * file_h =
new OksFile(xmls, short_file_name, full_file_name,
this);
1853 throw std::runtime_error(
"k_load_file(): failed to parse header");
1856 k_load_data(file_h, format, xmls, file_length, bind, parent_h, pipeline);
1864 throw std::runtime_error(
"k_load_file(): cannot open file");
1870 catch (std::exception & e) {
1874 throw FailedLoadFile(
"file", full_file_name,
"caught unknown exception");
1882 for(std::list<std::string>::const_iterator i = f.p_list_of_include_files.begin(); i != f.p_list_of_include_files.end(); ++i) {
1886 if((*i)[0] ==
'/') {
1887 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\")");
1889 else if((*i)[0] ==
'.') {
1890 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\")");
1892 else if((*i).find(
'/') == std::string::npos) {
1893 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\")");
1903 catch (std::exception & e) {
1917 std::shared_ptr<std::ifstream> f(
new std::ifstream(file_name.c_str()));
1920 throw std::runtime_error(
"get_includes(): cannot open file");
1924 OksFile fp(xmls, file_name, file_name,
this);
1937 catch (std::exception & e) {
1948 if(includes.find(file) != includes.end()) {
1949 if(file->p_included_by != parent) {
1951 file->p_included_by = parent;
1968 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) {
1972 igraph[i->second].insert(it->second);
1975 std::cerr <<
"cannot find schema " << *x <<
" included by " << i->second->get_full_file_name() << std::endl;
1981 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) {
1983 OksFile::Map::const_iterator it =
p_data_files.find(&f);
1985 igraph[i->second].insert(it->second);
1991 igraph[i->second].insert(it->second);
1994 std::cerr <<
"cannot find file " << *x <<
" included by " << i->second->get_full_file_name() << std::endl;
2010 std::list<OksFile *> to_be_closed[2];
2012 for(
int c = 0; c < 2; ++c) {
2013 for(OksFile::Map::iterator i = files[c]->begin(); i != files[c]->end(); ++i) {
2014 if(
OksFile * p =
const_cast<OksFile *
>(i->second->p_included_by)) {
2015 bool found_parent =
false;
2019 if(igraph.find(p) != igraph.end()) {
2020 OksFile::IMap::iterator j = igraph.find(p);
2026 TLOG_DEBUG( 1 ) <<
"the parent of file " << i->second->get_full_file_name() <<
" is not valid" ;
2031 for(OksFile::IMap::iterator j = igraph.begin(); j != igraph.end(); ++j) {
2033 found_parent =
true;
2038 if(found_parent ==
false) {
2039 TLOG_DEBUG( 1 ) <<
"the file " << i->second->get_full_file_name() <<
" is not included by any other file and will be closed" ;
2040 to_be_closed[c].push_back(i->second);
2048 for(std::list<OksFile *>::const_iterator i = to_be_closed[1].begin(); i != to_be_closed[1].end(); ++i) {
2049 num += (*i)->p_list_of_include_files.size();
2054 for(std::list<OksFile *>::const_iterator i = to_be_closed[0].begin(); i != to_be_closed[0].end(); ++i) {
2055 num += (*i)->p_list_of_include_files.size();
2061 TLOG_DEBUG( 1 ) <<
"go into recursive call, number of potentially closed includes is " << num ;
2070 TLOG_DEBUG( 1 ) <<
"rebuild classes since number of schema files has been changed from " << num_of_schema_files <<
" to " <<
schema_files().size() ;
2079 bool found_include_changes(
false);
2082 std::shared_ptr<std::ifstream> file(
new std::ifstream(fp->
get_full_file_name().c_str()));
2085 throw std::runtime_error(std::string(
"k_preload_includes(): cannot open file \"") + fp->
get_full_file_name() +
'\"');
2090 std::set<std::string> included;
2094 included.insert(*i);
2100 file->seekg(0, std::ios::end);
2102 long file_length =
static_cast<std::streamoff
>(file->tellg());
2104 if(file_length == 0) {
2105 throw std::runtime_error(std::string(
"k_preload_includes(): file \"") + fp->
get_full_file_name() +
"\" is empty");
2108 file->seekg(0, std::ios::beg);
2119 throw std::runtime_error(std::string(
"k_preload_includes(): failed to read header of file \"") + fp->
get_full_file_name() +
'\"');
2126 throw std::runtime_error(std::string(
"k_preload_includes(): file \"") + fp->
get_full_file_name() +
"\" is not valid oks file");
2136 std::set<std::string>::const_iterator x = included.find(*i);
2137 if(x != included.end()) {
2138 TLOG_DEBUG(3) <<
"include \'" << *i <<
"\' already exists, skip...";
2143 found_include_changes =
true;
2145 std::string full_file_name;
2150 catch (std::exception & e) {
2154 OksFile::Map::const_iterator j =
p_schema_files.find(&full_file_name);
2156 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is already loaded schema file \'" << j->first <<
'\'';
2162 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is already loaded data file \'" << j->first <<
'\'';
2167 if(f->p_oks_format ==
"schema") {
2168 std::string new_schema_full_file_name = f->get_full_file_name();
2171 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is a schema file, that was already loaded";
2175 if(allow_schema_extension) {
2176 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is new schema file, loading...";
2181 std::ostringstream text;
2182 text <<
"k_preload_includes(): include of new schema file (\'" << *i <<
"\') is not allowed on data reload";
2183 throw std::runtime_error(text.str().c_str());
2187 else if(f->p_oks_format ==
"data" || f->p_oks_format ==
"extended" || f->p_oks_format ==
"compact") {
2188 TLOG_DEBUG(3) <<
"the include \'" << *i <<
"\' is new data file, pre-loading...";
2191 new_files_h.insert(f);
2192 f->p_list_of_include_files.clear();
2193 if(
k_preload_includes(f, new_files_h, allow_schema_extension)) found_include_changes =
true;
2194 f->p_included_by = fp;
2195 f->update_status_of_file();
2199 std::ostringstream text;
2200 text <<
"k_preload_includes(): failed to parse header of included \'" << full_file_name <<
"\' file";
2201 throw std::runtime_error(text.str().c_str());
2205 throw std::runtime_error(
"k_load_file(): cannot open file");
2214 catch (std::exception & e) {
2218 return found_include_changes;
2227 if (
const char * path = getenv(
"TDAQ_DB_USER_REPOSITORY_PATH"))
2231 std::string user_repo;
2233 if (
const char * user_repo_base = getenv(
"TDAQ_DB_USER_REPOSITORY_ROOT"))
2234 user_repo = user_repo_base;
2236 user_repo = get_temporary_dir();
2238 user_repo.push_back(
'/');
2239 if (
const char * user_repo_pattern = getenv(
"TDAQ_DB_USER_REPOSITORY_PATTERN"))
2240 user_repo.append(user_repo_pattern);
2242 user_repo.append(
"oks.XXXXXX");
2244 std::unique_ptr<char[]> dir_template(
new char[user_repo.size() + 1]);
2245 strcpy(dir_template.get(), user_repo.c_str());
2247 if (
char * tmp_dirname = mkdtemp(dir_template.get()))
2261 OksFile::Map::const_iterator i = files.find(&at);
2262 if(i != files.end())
return (*i).second;
2269 for(
const auto& f : files)
2271 if (s == f.second->get_short_file_name())
2308 const char _fname[] =
"k_load_schema";
2309 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, short_file_name,
nullptr, &parent_h);
2313 std::string full_file_name;
2318 catch (std::exception & e) {
2319 throw CanNotOpenFile(
"k_load_schema", short_file_name, e.what());
2334 std::shared_ptr<std::ifstream> f(
new std::ifstream(full_file_name.c_str()));
2337 throw std::runtime_error(
"k_load_schema(): cannot open file");
2342 fp =
new OksFile(xmls, short_file_name, full_file_name,
this);
2345 throw std::runtime_error(
"k_load_schema(): failed to read header of file");
2348 throw std::runtime_error(
"k_load_schema(): file is not oks schema file");
2364 catch (std::exception & e) {
2368 throw FailedLoadFile(
"schema file", full_file_name,
"caught unknown exception");
2386 std::cout <<
"(non-fully-qualified filename was \"" << fp->
get_short_file_name() <<
"\")\n";
2394 std::list<OksClass *>
set;
2407 if(c->get_name().empty()) {
2408 throw std::runtime_error(
"k_load_schema(): failed to read a class");
2411 OksClass::Map::const_iterator ic =
p_classes.find(c->get_name().c_str());
2413 bool are_different = (*ic->second != *c);
2415 c->p_transient =
true;
2419 static bool ers_report = (getenv(
"OKS_KERNEL_ERS_REPORT_DUPLICATED_CLASSES") !=
nullptr);
2424 const char _fname[] =
"k_load_schema";
2427 <<
" Class \"" << c->get_name() <<
"\" was already loaded from file \'" << c->get_file()->get_full_file_name() <<
"\'\n";
2431 std::stringstream text;
2432 text << (are_different ?
"different " :
"") <<
"class \"" << c->get_name() <<
"\" was already loaded from file \'" << c->get_file()->get_full_file_name() <<
'\'';
2433 throw std::runtime_error(text.str().c_str());
2446 fp->
p_size = xmls->get_position();
2451 for(std::list<OksClass *>::iterator i2 =
set.begin(); i2 !=
set.end(); ++i2)
2452 (*OksClass::create_notify_fn)(*i2);
2455 std::set<OksClass *> set2;
2457 for(std::list<OksClass *>::iterator i2 =
set.begin(); i2 !=
set.end(); ++i2) {
2459 if(c->p_all_sub_classes && !c->p_all_sub_classes->empty()) {
2460 for(OksClass::FList::iterator i3 = c->p_all_sub_classes->begin(); i3 != c->p_all_sub_classes->end(); ++i3) {
2461 if(set2.find(*i3) == set2.end()) {
2475 catch (std::exception & e) {
2487 const char _fname[] =
"new_schema";
2488 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, s,
nullptr,
nullptr);
2495 std::string file_name(s);
2508 throw std::runtime_error(
"the file is already loaded");
2511 OksFile * file_h =
new OksFile(file_name,
"",
"",
"schema",
this);
2522 catch (std::exception & e) {
2526 throw CanNotCreateFile(
"new_schema",
"schema file", file_name,
"caught unknown exception");
2572 std::cout <<
"Making backup of schema file \"" << pf->
p_full_name <<
"\"...\n";
2595 const char _fname[] =
"k_save_schema";
2601 std::string tmp_file_name;
2616 size_t numberOfClasses = 0;
2619 numberOfClasses =
classes->size();
2623 if(i->second->p_file == fh) numberOfClasses++;
2633 std::ofstream f(tmp_file_name.c_str());
2634 f.exceptions ( std::ostream::failbit | std::ostream::badbit );
2637 std::ostringstream text;
2638 text <<
"cannot create temporal file \'" << tmp_file_name <<
"\' to save schema";
2639 throw std::runtime_error(text.str().c_str());
2643 std::cout <<
"Saving " << numberOfClasses <<
" classes to schema file \"" << pf->
p_full_name <<
"\"...\n";
2660 std::ostringstream errors;
2661 bool found_errors =
false;
2667 found_errors |= i.second->check_relationships(errors,
false);
2668 i.second->save(xmls);
2675 if (i.second->p_file == fh)
2677 found_errors |= i.second->check_relationships(errors,
false);
2678 i.second->save(xmls);
2685 kernel::BindError ex(
ERS_HERE, errors.str());
2689 throw std::runtime_error(ex.what());
2699 xmls.
put_last_tag(
"oks-schema",
sizeof(
"oks-schema")-1);
2707 if(rename(tmp_file_name.c_str(), pf->
p_full_name.c_str())) {
2708 std::ostringstream text;
2709 text <<
"cannot rename \'" << tmp_file_name <<
"\' to \'" << pf->
p_full_name <<
'\'';
2710 throw std::runtime_error(text.str().c_str());
2713 tmp_file_name.erase(0);
2720 throw std::runtime_error(ex.
what());
2729 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
2732 catch (std::exception & ex) {
2734 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
2749 pf->
rename(short_name, long_name);
2757 const char _fname[] =
"save_as_schema";
2758 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, new_name,
nullptr, &pf);
2763 if(!new_name.length()) {
2764 throw std::runtime_error(
"the new filename is empty");
2786 catch (std::exception & ex) {
2806 TLOG_DEBUG(2) <<
"skip read-only schema file \'" << *(i->first) <<
'\'';
2851 std::cout << (pf->
p_included_by ?
" * c" :
"C") <<
"lose OKS schema \"" << pf->
p_full_name <<
"\"..." << std::endl;
2863 std::set<OksClass *> sorted;
2867 if(pf == c->p_file) sorted.insert(c);
2868 c->p_to_be_deleted =
true;
2871 for(std::set<OksClass *>::iterator j = sorted.begin(); j != sorted.end(); ++j) {
2879 TLOG_DEBUG(4) <<
"exit for file " << (
void *)pf;
2891 i->second->p_to_be_deleted =
true;
2912 TLOG_DEBUG(4) <<
"enter for file " << (
void *)f;
2946 TLOG_DEBUG(4) <<
"exit for file " << (
void *)f;
2949std::list<OksClass *> *
2952 std::string fname(
"OksKernel::create_list_of_schema_classes(");
2954 fname.push_back(
'\'');
2959 std::list<OksClass *> * clist =
nullptr;
2962 for(OksClass::Map::const_iterator i =
p_classes.begin(); i !=
p_classes.end(); ++i) {
2963 if(pf == i->second->p_file) {
2964 if(!clist && !(clist =
new std::list<OksClass *>())) {
2968 clist->push_back(i->second);
2986 for(OksFile::Map::const_iterator i = files.begin(); i != files.end(); ++i) {
2990 if(*ufs == 0) { *ufs =
new std::list<OksFile *>(); }
2991 (*ufs)->push_back(i->second);
2993 else if(fs == wr ) {
2994 if(*rfs == 0) { *rfs =
new std::list<OksFile *>(); }
2995 (*rfs)->push_back(i->second);
3019 std::list<OksFile *> * files[] =
3020 {
nullptr,
nullptr,
nullptr,
nullptr };
3022 std::set<OksFile *> * sets[] =
3028 for (
int i = 0; i < 4; ++i)
3029 if (std::list<OksFile *> * f = files[i])
3033 sets[i % 2]->insert(f->front());
3055 if(parents.insert(file).second ==
false) {
3056 text +=
"(ignoring circular dependency between included files...)\n";
3061 text += file->get_full_file_name();
3062 text +=
"\' includes:\n";
3070 std::set<const OksFile *> parents;
3073 bool has_no_parents(text.empty());
3076 text += file.get_full_file_name();
3077 text += (has_no_parents ?
"\' has problem:\n" :
"\' that has problem:\n");
3080 std::lock_guard lock(
p_mutex);
3086 std::lock_guard lock(
p_mutex);
3089 std::ostringstream s;
3092 s <<
"Found 1 error parsing OKS data:\n" << *
m_errors.begin();
3095 s <<
"Found " <<
m_errors.size() <<
" errors parsing OKS data:";
3097 for(std::list<std::string>::const_iterator i =
m_errors.begin(); i !=
m_errors.end(); ++i) {
3098 s <<
"\nERROR [" << j++ <<
"] ***: " << *i;
3128 m_fp->p_number_of_items = 0;
3132 m_fp->p_number_of_items++;
3142 catch (std::exception& ex) {
3169 for(OksFile::Map::const_iterator i = files.begin(); i != files.end(); ++i) {
3170 if(i->second == f)
return true;
3180 (*c)[o->
GetId()] = o;
3186 std::map< const OksClass *, map_str_t<OksObject *> * >::iterator i =
data.find(c);
3187 if(i !=
data.end()) {
3189 if(j != i->second->end()) {
3191 i->second->erase(j);
3192 if(i->second->empty()) {
3213 std::map<OksFile *, std::vector<std::string> > included;
3215 std::set<OksFile *>::const_iterator i;
3217 bool check_includes(
false);
3218 bool found_schema_files(
false);
3219 std::string file_names;
3223 for(std::set<OksFile *>::const_iterator fi = files_h.begin(); fi != files_h.end();) {
3225 found_schema_files =
true;
3228 Oks::error_msg(
"OksKernel::reload_data") <<
"file " << (
void *)(*fi) <<
" is not OKS data or schema file, skip..." << std::endl;
3229 files_h.erase(fi++);
3233 if(fi != files_h.begin()) file_names.append(
", ");
3234 file_names.push_back(
'\"');
3235 file_names.append((*fi)->get_full_file_name());
3236 file_names.push_back(
'\"');
3244 if(found_schema_files) {
3245 throw std::runtime_error(
"Reload of modified schema files is not supported");
3250 if(files_h.empty())
return;
3258 for(i = files_h.begin(); i != files_h.end(); ++i) {
3259 if((*i)->is_locked()) {
3264 for(OksObject::Set::const_iterator oi =
p_objects.begin(); oi !=
p_objects.end(); ++oi) {
3265 if((*oi)->file == *i) reload_objects.
put(*oi);
3273 std::set<OksFile *> new_files;
3275 for(i = files_h.begin(); i != files_h.end(); ++i) {
3287 if(!new_files.empty()) {
3288 TLOG_DEBUG(2) << new_files.size() <<
" new files will be loaded";
3291 for(i = new_files.begin(); i != new_files.end(); ++i) {
3300 std::set<OksFile *> files_to_be_closed;
3302 if(check_includes) {
3303 size_t num_of_closing_files = 0;
3310 std::map<std::string, OksFile *> good_files;
3313 if(files_to_be_closed.find(j->second) == files_to_be_closed.end()) {
3314 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) {
3325 if(i->second->p_included_by && files_to_be_closed.find(i->second) == files_to_be_closed.end()) {
3326 TLOG_DEBUG(3) <<
"check the file \'" << i->second->get_full_file_name() <<
"\' is included";
3327 const std::string& s = i->second->get_full_file_name();
3335 std::map<std::string, OksFile *>::const_iterator j = good_files.find(s);
3337 if(j != good_files.end()) {
3341 files_to_be_closed.insert(f2);
3343 for(OksObject::Set::const_iterator oi =
p_objects.begin(); oi !=
p_objects.end(); ++oi) {
3344 if((*oi)->file == f2) {
3345 reload_objects.
put(*oi);
3349 if (files_h.erase(f2)) {
3361 if(num_of_closing_files == files_to_be_closed.size()) {
3365 num_of_closing_files = files_to_be_closed.size();
3370 TLOG_DEBUG(2) <<
"no changes in the list of includes";
3378 if(c->p_all_relationships && !c->p_all_relationships->empty()) {
3379 const unsigned int atts_num(c->number_of_all_attributes());
3384 for(std::list<OksRelationship *>::iterator i = c->p_all_relationships->begin(); i != c->p_all_relationships->end(); ++i, ++d) {
3386 if(r->get_is_composite() && r->get_is_exclusive()) {
3389 d->data.OBJECT->remove_RCR(
obj, r);
3393 for(OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
3417 for(i = files_h.begin(); i != files_h.end(); ++i) {
3418 std::shared_ptr<std::ifstream> f(
new std::ifstream((*i)->get_full_file_name().c_str()));
3422 OksFile fp(xmls, (*i)->get_short_file_name(), (*i)->get_full_file_name(),
this);
3427 std::cout <<
" * reading data file \"" << (*i)->get_full_file_name() <<
"\"..." << std::endl;
3432 ReadFileParams read_params( *i, *xmls, ((format ==
'X') ? 0 : &alias_table),
this, format, &reload_objects );
3443 (*i)->update_status_of_file();
3444 (*i)->p_is_updated =
false;
3457 oset.insert(ox->second);
3463 std::ostringstream text;
3464 text <<
"there are " << oset.size() <<
" removed objects:\n";
3466 for(OksObject::FSet::iterator x = oset.begin(); x != oset.end(); ++x) {
3467 text <<
" - object " << *x << std::endl;
3477 for(OksObject::FSet::const_iterator x2 = refs.begin(); x2 != refs.end(); ++x2) {
3478 TLOG_DEBUG(3) <<
"*** add object " << *x2 <<
" to the list of updated *** ";
3485 for(OksObject::FSet::iterator ox = oset.begin(); ox != oset.end(); ++ox) {
3489 TLOG_DEBUG(4) <<
"skip dangling object " << (
void *)o;
3493 TLOG_DEBUG(3) <<
"*** remove non-reloaded object " << o <<
" => " << (
void *)o <<
" ***";
3499 for(std::set<OksFile *>::const_iterator x = files_to_be_closed.begin(); x != files_to_be_closed.end(); ++x) {
3508 if (duplicated_objs_mode ==
true)
3510 for (
auto& o : reload_objects.
created)
3519 catch (std::exception & e) {
3539 TLOG_DEBUG( 1 ) <<
"remove file " << (*j)->get_full_file_name() ;
3547 TLOG_DEBUG( 1 ) <<
"restore file " << i->second->get_full_file_name() ;
3548 (*i->second) = (*j->second);
3571 const char _fname[] =
"k_load_data";
3572 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, short_file_name, &bind, &parent_h);
3576 std::string full_file_name;
3581 catch (std::exception & e) {
3592 Oks::warning_msg(fname) <<
" The file \'" << full_file_name <<
"\' was already loaded";
3598 std::shared_ptr<std::ifstream> f(
new std::ifstream(full_file_name.c_str()));
3601 throw std::runtime_error(
"k_load_data(): cannot open file");
3607 throw std::runtime_error(
"k_load_data(): file is empty");
3612 fp =
new OksFile(xmls, short_file_name, full_file_name,
this);
3615 throw std::runtime_error(
"k_load_data(): failed to read header of file");
3627 throw std::runtime_error(
"k_load_data(): file is not an oks data file");
3630 k_load_data(fp, format, xmls, file_length, bind, parent_h, pipeline);
3643 catch (std::exception & e) {
3660 std::cout << (parent_h ?
" * r" :
"R") <<
"eading data file \"" << fp->
get_full_file_name()
3661 <<
"\" in " << (format ==
'n' ?
"normal" : (format ==
'X' ?
"extended" :
"compact")) <<
" format (" << file_length <<
" bytes)...\n";
3663 std::cout <<
"(non-fully-qualified filename was \"" << fp->
get_short_file_name() <<
"\")\n";
3676 m_pipeline = pipeline;
3679 m_pipeline = pipeline_guard.get();
3711 catch (std::exception& e) {
3720 const char _fname[] =
"new_data";
3721 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, s,
nullptr,
nullptr);
3728 std::string file_name(s);
3741 throw std::runtime_error(
"the file is already loaded");
3756 catch (std::exception & e) {
3797 k_save_data(pf, ignoreBadObjects, true_file_h,
nullptr, force_defaults);
3827 std::cout <<
"Making backup of data file \"" << pf->
p_full_name <<
"\"...\n";
3851 const char _fname[] =
"k_save_data";
3857 std::string tmp_file_name;
3865 size_t numberOfObjects = 0;
3868 numberOfObjects =
objects->size();
3870 if(!ignoreBadObjects) {
3873 for(OksObject::FSet::const_iterator i =
objects->begin(); i !=
objects->end(); ++i) {
3874 errors += (*i)->report_dangling_references();
3877 if(!errors.empty()) {
3878 std::ostringstream text;
3879 text <<
"the file contains objects with dangling references:\n" << errors;
3880 throw std::runtime_error(text.str().c_str());
3887 std::set<OksFile *> includes;
3892 bool found_bad_object =
false;
3895 if((*i)->file == fh) {
3898 if((*i)->is_consistent(includes,
"WARNING") ==
false) {
3899 found_bad_object =
true;
3901 if((*i)->is_duplicated() ==
true) {
3903 Oks::error_msg(fname) <<
" The file contains duplicated object " << *i << std::endl;
3905 found_bad_object =
true;
3911 if(found_bad_object && ignoreBadObjects ==
false) {
3912 throw std::runtime_error(
"the file contains inconsistent/duplicated objects or misses includes");
3929 std::fstream f(pf->
p_full_name.c_str(), std::ios::in);
3935 std::fstream f2(pf->
p_full_name.c_str(), std::ios::out);
3938 std::ostringstream text;
3939 text <<
"cannot open file \'" << pf->
p_full_name <<
"\' for writing";
3940 throw std::runtime_error(text.str().c_str());
3951 std::ofstream f(tmp_file_name.c_str());
3953 f.exceptions ( std::ostream::failbit | std::ostream::badbit );
3956 std::ostringstream text;
3957 text <<
"cannot create temporal file \'" << tmp_file_name <<
"\' to save data";
3958 throw std::runtime_error(text.str().c_str());
3963 std::cout <<
"Saving " << numberOfObjects <<
" objects " << (force_defaults ?
"with enforced default values " :
"") <<
"to data file \"" << pf->
p_full_name <<
"\"...\n";
3978 for(OksClass::Map::const_iterator i =
p_classes.begin(); i !=
p_classes.end() && f.good(); ++i) {
3981 for(OksObject::Map::const_iterator j = i->second->p_objects->begin(); j != i->second->p_objects->end(); ++j) {
3983 sorted[j->first] = j->second;
3987 for(OksObject::SMap::iterator j = sorted.begin(); j != sorted.end(); ++j) {
3988 j->second->put(xmls, force_defaults);
3995 file_len = f.tellp();
4005 long written_len = 0;
4007 std::shared_ptr<std::ifstream> f(
new std::ifstream(tmp_file_name.c_str()));
4010 f->seekg(0, std::ios::end);
4011 written_len =
static_cast<std::streamoff
>(f->tellg());
4014 if(written_len != file_len) {
4015 unlink(tmp_file_name.c_str());
4016 std::ostringstream text;
4017 text <<
"write error in file \'" << tmp_file_name <<
"\': " << written_len <<
" bytes been written instead of " << file_len;
4018 throw std::runtime_error(text.str().c_str());
4026 if(
int code = stat(pf->
p_full_name.c_str(), &buf)) {
4027 std::ostringstream text;
4028 text <<
"cannot get information about file \'" << pf->
p_full_name <<
"\': stat() failed with code " << code <<
", reason = \'" <<
strerror(errno) <<
'\'';
4029 throw std::runtime_error(text.str().c_str());
4035 if(
int code = rename(tmp_file_name.c_str(), pf->
p_full_name.c_str())) {
4036 std::ostringstream text;
4037 text <<
"cannot rename file \'" << tmp_file_name <<
"\' to \'" << pf->
p_full_name <<
"\': rename() failed with code " << code <<
", reason = \'" <<
strerror(errno) <<
'\'';
4038 throw std::runtime_error(text.str().c_str());
4041 tmp_file_name.erase(0);
4049 throw std::runtime_error(ex.
what());
4059 if(
int code = stat(pf->
p_full_name.c_str(), &buf2)) {
4060 std::ostringstream text;
4061 text <<
"cannot get information about file \'" << pf->
p_full_name <<
"\': stat() failed with code " << code <<
", reason = \'" <<
strerror(errno) <<
'\'';
4062 throw std::runtime_error(text.str().c_str());
4068 if(buf.st_mode != buf2.st_mode) {
4069 if(
int code = chmod(pf->
p_full_name.c_str(), buf.st_mode) != 0) {
4070 std::ostringstream text;
4071 text <<
"cannot set protection mode for file \'" << pf->
p_full_name <<
"\': chmod() failed with code " << code <<
", reason = \'" <<
strerror(errno) <<
'\'';
4072 throw std::runtime_error(text.str().c_str());
4078 if(buf.st_gid != buf2.st_gid) {
4079 if(
int code = chown(pf->
p_full_name.c_str(), (gid_t)(-1), buf.st_gid) != 0) {
4088 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
4091 catch (std::exception & e) {
4093 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
4098 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
4113 pf->
rename(short_name, long_name);
4120 const char _fname[] =
"save_as_data";
4121 std::string fname =
make_fname(_fname,
sizeof(_fname)-1, new_name,
nullptr, &pf);
4126 if(!new_name.length()) {
4127 throw std::runtime_error(
"the new filename is empty");
4151 catch (std::exception & ex) {
4169 k_save_data(i->second,
false,
nullptr,
nullptr, force_defaults);
4172 TLOG_DEBUG(2) <<
"skip read-only data file \'" << *(i->first) <<
'\'';
4194 const char _fname[] =
"k_close_data";
4213 for(OksObject::Set::const_iterator i =
p_objects.begin(); i !=
p_objects.end(); ++i) {
4223 while(!olist->empty()) {
4263 for(OksClass::Map::const_iterator i =
p_classes.begin(); i !=
p_classes.end(); ++i) {
4264 if(i->second->p_objects) {
4265 delete i->second->p_objects;
4266 i->second->p_objects = 0;
4287 TLOG_DEBUG(4) <<
"enter for file " << (
void *)fp;
4322 TLOG_DEBUG(4) <<
"leave for file " << (
void *)fp;
4326std::list<OksObject *> *
4329 const char _fname[] =
"create_list_of_data_objects";
4336 std::list<OksObject *> * olist =
new std::list<OksObject *>();
4339 for(OksObject::Set::const_iterator i =
p_objects.begin(); i !=
p_objects.end(); ++i) {
4340 if((*i)->file == fp) olist->push_back(*i);
4344 if(olist->empty()) {
4377 (*i)->bind_objects();
4384 const std::string error_text(strchr(ex.
what(),
'\n')+1);
4407 for(OksClass::Map::const_iterator i = all_classes.begin(); i != all_classes.end(); ++i) {
4410 for(OksObject::Map::const_iterator j = objs->begin(); j != objs->end(); ++j) {
4412 unsigned short l1 = c->number_of_all_attributes();
4413 unsigned short l2 = l1 + c->number_of_all_relationships();
4420 if(rm_objs.find(d->data.OBJECT) != rm_objs.end()) {
4422 const OksClass * __c(d->data.OBJECT->GetClass());
4423 const OksString& __id(d->data.OBJECT->GetId());
4425 TLOG_DEBUG(5) <<
"set relationship of " << o <<
": " << *d;
4429 for(OksData::List::const_iterator li = d->data.LIST->begin(); li != d->data.LIST->end(); ++li) {
4432 if(rm_objs.find(lid->
data.
OBJECT) != rm_objs.end()) {
4437 TLOG_DEBUG(5) <<
"set relationship of " << o <<
": " << *d;
4453 OksClass::Map::const_iterator i =
p_classes.find(name);
4454 return (i !=
p_classes.end() ? i->second : 0);
4461 TLOG_DEBUG(4) <<
"enter for class \"" << c->get_name() <<
'\"';
4473 c->p_file->p_is_updated =
true;
4490 TLOG_DEBUG(4) <<
"enter for class \"" << c->get_name() <<
'\"';
4503 if(
size_t num_of_classes =
p_classes.size()) {
4505 size_t array_size = num_of_classes *
sizeof(
OksClass*) /
sizeof(
wchar_t);
4507 OksClass::Map::iterator i =
p_classes.begin();
4508 unsigned long idx(0);
4510 for(; i !=
p_classes.end(); ++i) i->second->registrate_class(skip_registered);
4517 if(!c->p_all_sub_classes) c->p_all_sub_classes =
new OksClass::FList();
4518 else c->p_all_sub_classes->clear();
4526 for(OksClass::FList::const_iterator j = scl->begin(); j != scl->end(); ++j) {
4527 (*j)->p_all_sub_classes->push_back(c);
4535 if(!c->get_is_abstract()) {
4538 wmemset(
reinterpret_cast<wchar_t *
>(table), 0, array_size);
4539 for(OksClass::FList::const_iterator j1 = spc->begin(); j1 != spc->end(); ++j1) {
4541 for(OksClass::FList::const_iterator j2 = sbc->begin(); j2 != sbc->end(); ++j2) {
4544 table[c2->
p_id] = c2;
4550 unsigned int count(0);
4551 for(
unsigned int x = 0; x < num_of_classes; ++x) {
4552 if(table[x]) count++;
4556 std::vector<OksClass *> * cih;
4557 if(!c->p_inheritance_hierarchy) {
4558 cih = c->p_inheritance_hierarchy =
new std::vector<OksClass *>();
4561 cih = c->p_inheritance_hierarchy;
4565 cih->reserve(count);
4567 for(
unsigned int x = 0; x < num_of_classes; ++x) {
4568 if(table[x]) cih->push_back(table[x]);
4578 std::ostringstream s;
4581 if(std::vector<OksClass *> * cis = i->second->p_inheritance_hierarchy) {
4582 s <<
" - class \'" << i->second->get_name() <<
"\' shares IDs with " << cis->size() <<
" classes: ";
4584 for(std::vector<OksClass *>::const_iterator j = cis->begin(); j != cis->end(); ++j) {
4587 for(OksClass::Set::const_iterator j = sorted.begin(); j != sorted.end(); ++j) {
4588 if(j != sorted.begin()) s <<
", ";
4589 s <<
'\'' << (*j)->get_name() <<
'\'';
4595 TLOG_DEBUG(2) <<
"Schema inheritance hierarchy used to test objects with equal IDs:\n" << s.str();
4620 std::string fname(
"OksKernel::is_dangling(");
4623 fname +=
"?object?) returns true";
4626 fname += o->
GetId();
4627 fname +=
"\") returns false";
4643 bool not_found =
true;
4647 for(OksClass::Map::const_iterator i =
p_classes.begin(); i !=
p_classes.end(); ++i) {
4648 if(i->second == c) {
4657 std::string fname(
"OksKernel::is_dangling(");
4660 fname +=
"?class?) returns true";
4663 fname += c->get_name();
4664 fname +=
"\") returns false";
4677 for(std::vector<std::string>::const_iterator i = names_in.begin(); i != names_in.end(); ++i) {
4679 if(c != 0 && classes_out.find(c) == classes_out.end()) {
4680 classes_out.insert(c);
4682 for(OksClass::FList::const_iterator j = sc->begin(); j != sc->end(); ++j) {
4683 classes_out.insert(*j);
4724 throw RepositoryOperationFailed(op,
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
4735 std::ostringstream text;
4751 if(
int result = chdir(
p_dir)) {
4753 <<
"chdir (\'" <<
p_dir <<
"\') failed with code " << result <<
": " <<
strerror(errno) << std::endl;
4771 std::string cat2str()
const;
4772 std::string last_str()
const;
4774 void check_command_status(
int status);
4785 p_file_name = get_temporary_dir() +
'/' + command_name +
'.' + std::to_string(getpid()) +
':' + std::to_string(
reinterpret_cast<std::uintptr_t
>(k)) +
".txt";
4803 std::filebuf * buf = f.rdbuf();
4805 char c = buf->sbumpc();
4818 std::string lastline;
4822 f.seekg(-1, std::ios_base::end);
4823 if (f.peek() ==
'\n')
4825 f.seekg(-1, std::ios_base::cur);
4826 for (
int i = f.tellg(); i >= 0; i--)
4828 if (f.peek() ==
'\n')
4833 f.seekg(i, std::ios_base::beg);
4837 getline(f, lastline);
4848 std::ostringstream text;
4852 else if (
int error_code = WEXITSTATUS(status))
4854 std::ostringstream text;
4855 text <<
p_command.substr(0,
p_command.find_first_of(
' ')) <<
" exit with error code " << error_code <<
", output:\n" <<
cat2str();
4867 file_h->
rename(new_name);
4873 file_h->
rename(new_name);
4887 std::string cmd(
"oks-checkout.sh");
4899 cmd.push_back(
'\"');
4901 cmd.push_back(
'\"');
4904 if (!branch_name.empty())
4907 cmd.append(branch_name);
4910 auto start_usage = std::chrono::steady_clock::now();
4915 log_timestamp() <<
"[OKS checkout] => " << cmd << std::endl;
4926 std::cout << cmd_out.
cat2str();
4927 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;
4930 static std::string version_prefix(
"checkout oks version ");
4932 std::string::size_type pos =
version.find(version_prefix);
4961 std::string cmd(
"oks-copy.sh");
4970 cmd.append(destination);
4975 auto start_usage = std::chrono::steady_clock::now();
4987 std::cout << cmd_out.
cat2str();
4988 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;
4999 throw RepositoryOperationFailed(
"update",
"the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5002 throw RepositoryOperationFailed(
"update",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5004 std::string cmd(
"oks-update.sh");
5013 cmd.append(
" --force");
5015 cmd.append(
" --merge");
5022 cmd.push_back(
'\"');
5024 cmd.push_back(
'\"');
5027 auto start_usage = std::chrono::steady_clock::now();
5039 static std::string version_prefix(
"update oks version ");
5041 std::string::size_type pos =
version.find(version_prefix);
5051 std::cout << cmd_out.
cat2str();
5052 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;
5062 throw RepositoryOperationFailed(
"commit",
"the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5065 throw RepositoryOperationFailed(
"commit",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5067 std::string cmd(
"oks-commit.sh");
5075 if(comments.empty() || std::all_of(comments.begin(), comments.end(), [](
char c) { return std::isspace(c); }))
5078 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");
5082 std::ofstream f(log_file_name);
5084 f.exceptions(std::ostream::failbit | std::ostream::badbit);
5087 throw std::runtime_error(
"create message file failed");
5092 catch (
const std::exception& ex)
5094 std::ostringstream ss;
5095 ss <<
"cannot write to file \'" << log_file_name <<
"\' to save commit message: " << ex.what();
5099 cmd.append(
" -f \'");
5100 cmd.append(log_file_name);
5101 cmd.push_back(
'\'');
5163 auto start_usage = std::chrono::steady_clock::now();
5173 int status = system(cmd.c_str());
5175 unlink(log_file_name.c_str());
5177 if (!credentials.empty())
5178 unsetenv(
"OKS_COMMIT_USER");
5187 std::cout << cmd_out.
cat2str();
5188 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;
5191 static std::string version_prefix(
"commit oks version ");
5193 std::string::size_type pos =
version.find(version_prefix);
5207 throw RepositoryOperationFailed(
"tag",
"the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5210 throw RepositoryOperationFailed(
"tag",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5212 std::string cmd(
"oks-tag.sh");
5220 if(tag.empty() || std::all_of(tag.begin(), tag.end(), [](
char c) { return std::isspace(c); }))
5223 cmd.append(
" -t \'");
5225 cmd.append(
"\' -c \'");
5227 cmd.push_back(
'\'');
5229 auto start_usage = std::chrono::steady_clock::now();
5243 std::cout << cmd_out.
cat2str();
5244 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;
5248std::list<std::string>
5254 throw RepositoryOperationFailed(
"diff",
"the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5257 throw RepositoryOperationFailed(
"diff",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5259 std::string cmd(
"oks-diff.sh");
5267 if(!sha1.empty() && !sha2.empty())
5269 cmd.append(
" --sha ");
5276 cmd.append(
" --unmerged");
5282 std::string output = cmd_out.
cat2str();
5286 std::cout << output <<
"[OKS get_diff] => done" << std::endl;
5289 std::istringstream s(output);
5294 const char * diff_pattern =
"git diff --name-only ";
5296 while (std::getline(s, line))
5297 if (line.find(diff_pattern) == 0)
5305 std::ostringstream text;
5306 text <<
"cannot find \"" << diff_pattern <<
"\" pattern in output of oks-diff.sh:\n" << output;
5310 std::list<std::string> result;
5312 while (std::getline(s, line))
5313 result.push_back(line);
5321 for (
const auto& x : ver.
m_files)
5322 if (loaded_files.find(x) != loaded_files.end())
5328std::vector<OksRepositoryVersion>
5331 std::string cmd(
"oks-log.sh");
5339 cmd.append(command_line);
5344 std::string output = cmd_out.
cat2str();
5346 std::istringstream s(output);
5351 while (std::getline(s, line))
5352 if (line.find(
"git log ") == 0)
5360 std::ostringstream text;
5361 text <<
"cannot find \"git log\" pattern in output of oks-log.sh:\n" << output;
5365 std::set<std::string> loaded_files;
5367 if (skip_irrelevant)
5372 loaded_files.emplace(x.first->substr(len));
5375 loaded_files.emplace(x.first->substr(len));
5378 std::vector<OksRepositoryVersion> vec;
5383 while (std::getline(s, line))
5389 std::string::size_type idx1 = 0;
5390 std::string::size_type idx2 = line.find(
'|');
5392 if (idx2 != std::string::npos)
5396 idx2 = line.find(
'|', idx1);
5398 if (idx2 != std::string::npos)
5400 ver.
m_user = line.substr(idx1, idx2-idx1);
5402 idx2 = line.find(
'|', idx1);
5404 if (idx2 != std::string::npos)
5406 ver.
m_date = std::stol(line.substr(idx1, idx2-idx1));
5417 std::ostringstream text;
5418 text <<
"unexpected line \"" << line <<
"\" in output of oks-log.sh:\n" << output;
5428 if (skip_irrelevant &&
check_relevant(loaded_files, ver) ==
false)
5431 vec.emplace_back(ver);
5442 if (skip_irrelevant ==
false ||
check_relevant(loaded_files, ver))
5443 vec.emplace_back(ver);
5449std::vector<OksRepositoryVersion>
5452 std::string command_line;
5454 if(!since.empty() && !until.empty())
5456 command_line.push_back(
' ');
5457 command_line.append(since);
5458 command_line.append(
"..");
5459 command_line.append(until);
5461 else if(!since.empty())
5463 command_line.push_back(
' ');
5464 command_line.append(since);
5465 command_line.append(
"..origin/master");
5467 else if(!until.empty())
5469 command_line.append(
" ..");
5470 command_line.append(until);
5479 std::string
out(in);
5480 std::replace(
out.begin(),
out.end(),
' ',
'T');
5485std::vector<OksRepositoryVersion>
5488 std::string command_line;
5492 command_line.append(
" --since ");
5498 command_line.append(
" --until ");
5502 command_line.append(
" origin/master");
5514 throw RepositoryOperationFailed(
"status",
"the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5517 throw RepositoryOperationFailed(
"status",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5519 std::string cmd(
"oks-version.sh");
5527 std::string output = cmd_out.
cat2str();
5529 static std::string version_prefix(
"oks version ");
5531 std::string::size_type pos =
version.find(version_prefix);
5537 std::ostringstream text;
5538 text <<
"cannot read oks version from oks-version.sh output: \"" << output <<
'\"';
5551 throw RepositoryOperationFailed(
"status",
"the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5554 throw RepositoryOperationFailed(
"status",
"the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5556 std::string cmd(
"oks-status.sh");
5564 std::string output = cmd_out.
cat2str();
5568 std::cout << output <<
"[OKS get_status] => done" << std::endl;
5571 std::istringstream s(output);
5576 const char * diff_pattern =
"git status --porcelain";
5578 while (std::getline(s, line))
5579 if (line.find(diff_pattern) == 0)
5587 std::ostringstream text;
5588 text <<
"cannot find \"" << diff_pattern <<
"\" pattern in output of oks-status.sh:\n" << output;
5592 std::list<std::string> result;
5594 while (std::getline(s, line))
5596 if (line.find(
" D ") == 0)
5597 removed.insert(line.substr(3));
5598 else if (line.find(
" M ") == 0)
5599 updated.insert(line.substr(3));
5600 else if (line.find(
"?? ") == 0)
5601 added.insert(line.substr(3));
5604 std::ostringstream text;
5605 text <<
"unexpected output \"" << line <<
"\" in output of oks-status.sh:\n" << output;
5712 std::ostringstream
out;
5715 c.second->check_relationships(
out,
true);
5724 auto now(std::chrono::system_clock::now());
5725 auto time_since_epoch(
now.time_since_epoch());
5726 auto seconds_since_epoch(std::chrono::duration_cast<std::chrono::seconds>(time_since_epoch));
5728 std::time_t now_t(std::chrono::system_clock::to_time_t(std::chrono::system_clock::time_point(seconds_since_epoch)));
5731 std::size_t len = std::strftime(buff, 128 - 16,
"%Y-%b-%d %H:%M:%S.", std::localtime(&now_t));
5732 sprintf(buff+len,
"%03d ", (
int)(std::chrono::duration_cast<std::chrono::milliseconds>(time_since_epoch).count() - seconds_since_epoch.count()*1000));
5734 std::ostream& s (severity <=
Warning ? std::cerr : std::cout);
5736 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