DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
dunedaq::oks::OksKernel Class Reference

Provides interface to the OKS kernel. More...

#include <kernel.hpp>

Collaboration diagram for dunedaq::oks::OksKernel:
[legend]

Public Types

enum  RepositoryUpdateType { DiscardChanges , MergeChanges , NoChanges }

Public Member Functions

 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.
 OksKernel (const OksKernel &src, bool copy_repository=false)
 Copy constructor.
 ~OksKernel ()
OksProfilerGetOksProfiler () const
bool get_verbose_mode () const
 Get status of verbose mode. The method returns true, if the verbose mode is switched 'On'.
void set_verbose_mode (const bool b)
 Set status of verbose mode. To switch 'On'/'Off' use the method's parameter:
bool get_silence_mode () const
 Get status of silence mode. The method returns true, if the silence mode is switched 'On'. In such case the OKS will not print any info, warnings and error messages.
void set_silence_mode (const bool b)
 Set status of silence mode. To switch 'On'/'Off' use the method's parameter:
bool get_profiling_mode () const
 Get status of profiling mode. The method returns true, if the profiling mode is switched 'On'. In such case the OKS will report time spend to execute main methods and a summary table of their calls on the OKS kernel destroy.
void set_profiling_mode (const bool b)
 Set status of profiling mode. To switch 'On'/'Off' use the method's parameter:
bool get_allow_duplicated_classes_mode () const
 Get status of duplicated classes mode. The method returns true, if the duplicated classes mode is switched 'On'. In such case the OKS will allow to load classes with equal names. Only first loaded class is taken into account, the next ones are ignored.
bool get_allow_duplicated_objects_mode () const
 Get status of duplicated objects mode. The method returns true, if the duplicated objects mode is switched 'On'. In such case the OKS will allow to load objects of the same class with equal IDs. The ID for duplicated object will be generated automatically.
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:
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 switched 'On'. In such case the OKS will throw exception when there are objects with equal IDs within class inheritance hierarchy.
void set_allow_duplicated_classes_mode (const bool b)
 Set status of duplicated classes mode. To switch 'On'/'Off' use the method's parameter:
void set_allow_duplicated_objects_mode (const bool b)
 Set status of duplicated objects mode. To switch 'On'/'Off' use the method's parameter:
std::shared_mutex & get_mutex ()
 Return OKS kernel mutex.
OksFilefind_schema_file (const std::string &s) const
 Finds OKS schema file.
OksFilefind_data_file (const std::string &s) const
 Finds OKS data file.
std::list< OksClass * > * create_list_of_schema_classes (OksFile *) const
 Creates list of classes which belong to given file.
std::list< OksObject * > * create_list_of_data_objects (OksFile *) const
 Creates list of objects which belong to given file.
OksFilecreate_file_info (const std::string &short_file_name, const std::string &file_name)
 Creates OKS file descriptor.
std::string get_file_path (const std::string &path, const OksFile *parent_file=0, bool strict_paths=true) const
 Calculates full path to file.
const std::string & get_repository_version ()
bool is_user_repository_created () const
const std::string & get_user_repository_root () const
 Get user OKS repository root.
void set_user_repository_root (const std::string &path, const std::string &version="")
 Set user OKS repository root.
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.
void k_close_dangling_includes ()
 Close files which lost their parent.
OksFileload_file (const std::string &name, bool bind=true)
 Load OKS database file.
OksFileload_schema (const std::string &name, const OksFile *parent=0)
 Load OKS schema file.
OksFilenew_schema (const std::string &name)
 Create OKS schema file.
void save_schema (OksFile *file_h, bool force=false, OksFile *true_file_h=0)
 Save OKS schema file.
void save_schema (OksFile *file_h, bool force, const OksClass::Map &classes)
 Save classes into given OKS schema file.
void backup_schema (OksFile *pf, const char *suffix=".bak")
 Backup OKS schema file.
void save_as_schema (const std::string &name, OksFile *file_h)
 Save OKS schema file under new name.
void save_all_schema ()
 Save all OKS schema files.
void close_schema (OksFile *file_h)
 Close OKS schema file.
void close_all_schema ()
 Close all OKS schema files.
void set_active_schema (OksFile *file_h)
 Set active OKS schema file.
void k_set_active_schema (OksFile *file_h)
 Set active OKS schema file. Non thread-safe version of the set_active_schema() method;.
OksFileget_active_schema () const
 Get active OKS schema file.
const OksFile::Mapschema_files () const
 Get all schema files.
void create_lists_of_updated_schema_files (std::list< OksFile * > **updated, std::list< OksFile * > **removed) const
 Get modified schema files.
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.
OksFileload_data (const std::string &name, bool bind=true)
 Load OKS data file.
void reload_data (std::set< OksFile * > &files, bool allow_schema_extension=true)
 Reload OKS data files.
OksFilenew_data (const std::string &name, const std::string &logical_name="", const std::string &type="")
 Create OKS data file.
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 save_data (OksFile *file_h, const OksObject::FSet &objects)
 Save objects into given OKS data file.
void backup_data (OksFile *pf, const char *suffix=".bak")
 Backup OKS data file.
void save_as_data (const std::string &new_name, OksFile *file_h)
 Save OKS data file under new name.
void save_all_data (bool force_defaults=false)
 Save all OKS data files.
void close_data (OksFile *file_h, bool unbind_objects=true)
 Close OKS data file.
void close_all_data ()
 Close all OKS data files.
void set_active_data (OksFile *file_h)
 Set active OKS data file.
void k_set_active_data (OksFile *)
 Set active OKS data file.
OksFileget_active_data () const
 Get active OKS data file.
const OksFile::Mapdata_files () const
 Get all data files.
void create_lists_of_updated_data_files (std::list< OksFile * > **updated, std::list< OksFile * > **removed) const
 Get modified data files.
void get_modified_files (std::set< OksFile * > &mfs, std::set< OksFile * > &rfs, const std::string &version)
 Get modified data files.
const std::list< std::string > & get_repository_dirs () const
 Get repository search directories.
void commit_repository (const std::string &comments, const std::string &credentials="")
 Commit user modifications into repository.
void tag_repository (const std::string &tag)
 Tag current state of repository.
std::time_t get_repository_checkout_ts () const
 Return repository checkout timestamp.
void update_repository (const std::string &hash_val, RepositoryUpdateType update_type)
 Update user repository files from origin by hash.
void update_repository (const std::string &param, const std::string &val, RepositoryUpdateType update_type)
 Update user repository files from origin.
std::list< std::string > get_repository_versions_diff (const std::string &sha1, const std::string &sha2)
std::list< std::string > get_repository_unmerged_files ()
std::vector< OksRepositoryVersionget_repository_versions (bool skip_irrelevant, const std::string &command_line)
 Return repository versions.
std::vector< OksRepositoryVersionget_repository_versions_by_hash (bool skip_irrelevant=true, const std::string &sha1="", const std::string &sha2="")
 Return repository versions between hash keys.
std::vector< OksRepositoryVersionget_repository_versions_by_date (bool skip_irrelevant=true, const std::string &since="", const std::string &until="")
 Return repository versions between timestamps.
std::string read_repository_version ()
 Read and return current repository version.
std::string insert_repository_dir (const std::string &dir, bool push_back=true)
 Insert repository search directory.
void remove_repository_dir (const std::string &dir)
 Remove repository search directory.
const OksClass::Mapclasses () const
 Get classes.
size_t number_of_classes () const
 Get number of classes.
const OksObject::Setobjects () const
 Get objects.
size_t number_of_objects () const
 Get number of objects.
OksClassfind_class (const std::string &class_name) const
 Find class by name (C++ string).
OksClassfind_class (const char *class_name) const
 Find class by name (C-string).
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 registrate_all_classes (bool skip_registered=false)
 The method rebuilds all classes taking into account inheritance.
bool is_dangling (OksClass *class_ptr) const
 Check pointer on oks class.
bool is_dangling (OksObject *obj_ptr) const
 Check pointer on oks object.
void subscribe_create_class (void(*f)(OksClass *))
 Subscribe on class creation.
void subscribe_change_class (void(*f)(OksClass *, OksClass::ChangeType, const void *))
 Subscribe on class changing.
void subscribe_delete_class (void(*f)(OksClass *))
 Subscribe on class destroying.
void subscribe_create_object (OksObject::notify_obj cb_f, void *parameter)
 Subscribe on object creation.
void subscribe_change_object (OksObject::notify_obj, void *)
 Subscribe on object changing.
void subscribe_delete_object (OksObject::notify_obj, void *)
 Subscribe on object deleting.
void bind_objects ()
 Bind oks objects.
const std::string & get_bind_objects_status () const noexcept
 Return status of oks objects binding.
const std::string & get_bind_classes_status () const noexcept
 Return status of oks classes binding.
void unset_repository_created ()
 Set repository created flag to false to avoid created repository removal in destructor;.

Static Public Member Functions

static const char * GetVersion ()
 Get OKS version. The method returns string containing CVS tag and date of OKS build.
static std::string & get_host_name ()
 Get hostname of given process.
static std::string & get_domain_name ()
 Get domain name of host.
static std::string & get_user_name ()
 Get username of given process.
static bool get_skip_string_range ()
 Get status of string range validator.
static void set_skip_string_range (const bool b)
 Set status of string range validator. To switch 'On'/'Off' use the method's parameter:
static bool check_read_only (OksFile *f)
 Check if the OKS file is read-only.
static const std::string & get_repository_root ()
 Get OKS repository root.
static const std::string & get_repository_mapping_dir ()
 Get OKS repository name.
static std::string get_tmp_file (const std::string &file_name)
 Generates temporal file name.
static const char * get_cwd ()
static void reset_cwd ()
 Reset current working dir in case of chdir() call.
static void set_use_strict_repository_paths (bool flag)
 Set flag to use strict-repository-paths check.

Private Types

template<typename T>
using map_str_t = std::map<std::string, T>

Private Member Functions

std::string create_user_repository_dir ()
void remove_user_repository_dir ()
void k_copy_repository (const std::string &source, const std::string &destination)
void k_checkout_repository (const std::string &param, const std::string &val, const std::string &branch)
 Check out repository files into local user directory.
OksFilefind_file (const std::string &s, const OksFile::Map &files) const
void k_rename_repository_file (OksFile *file_h, const std::string &new_name)
OksFilek_load_file (const std::string &name, bool bind, const OksFile *parent, OksPipeline *pipeline)
void k_load_includes (const OksFile &, OksPipeline *)
bool k_preload_includes (OksFile *file_h, std::set< OksFile * > &new_files, bool allow_schema_extension)
void clear_preload_file_info ()
void restore_preload_file_info ()
OksFilek_load_schema (const std::string &, const OksFile *)
void k_load_schema (OksFile *fp, std::shared_ptr< OksXmlInputStream > xmls, const OksFile *parent_h)
void k_close_schema (OksFile *)
void k_save_schema (OksFile *, bool force=false, OksFile *=0, const OksClass::Map *=0)
void k_rename_schema (OksFile *, const std::string &short_name, const std::string &long_name)
OksFilek_load_data (const std::string &, bool, const OksFile *, OksPipeline *)
void k_load_data (OksFile *fp, char format, std::shared_ptr< OksXmlInputStream > xmls, long file_length, bool bind, const OksFile *parent_h, OksPipeline *)
void k_close_data (OksFile *, bool)
void k_save_data (OksFile *, bool=false, OksFile *=nullptr, const OksObject::FSet *=nullptr, bool force_defaults=false)
void k_rename_data (OksFile *, const std::string &short_name, const std::string &long_name)
void k_bind_objects ()
void k_check_bind_classes_status () const noexcept
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 objects.
void k_add (OksClass *)
void k_remove (OksClass *)
void define (OksObject *o)
void undefine (OksObject *o)
void add_data_file (OksFile *)
void add_schema_file (OksFile *)
void remove_data_file (OksFile *)
void remove_schema_file (OksFile *)
bool test_parent (OksFile *file, OksFile::IMap::iterator &i)

Private Attributes

bool p_silence
bool p_verbose
bool p_profiling
bool p_allow_repository
bool p_allow_duplicated_classes
bool p_allow_duplicated_objects
bool p_test_duplicated_objects_via_inheritance
std::string p_user_repository_root
bool p_user_repository_root_inited
bool p_user_repository_root_created
std::string p_repository_version
std::time_t p_repository_checkout_ts
std::time_t p_repository_update_ts
std::shared_mutex p_kernel_mutex
std::mutex p_objects_mutex
std::mutex p_objects_refs_mutex
std::shared_mutex p_schema_mutex
OksFile::Map p_schema_files
OksFile::Map p_data_files
OksFilep_active_schema
OksFilep_active_data
bool p_close_all
std::list< std::string > p_repository_dirs
OksClass::Map p_classes
OksProfilerprofiler
OksObject::Set p_objects
std::string p_bind_objects_status
std::string p_bind_classes_status
LoadErrors p_load_errors
std::map< const OksFile *, OksFile * > p_preload_file_info
std::vector< OksFile * > p_preload_added_files
OksObject::notify_obj p_create_object_notify_fn
void * p_create_object_notify_param
OksObject::notify_obj p_change_object_notify_fn
void * p_change_object_notify_param
OksObject::notify_obj p_delete_object_notify_fn
void * p_delete_object_notify_param

Static Private Attributes

static bool p_skip_string_range = false
static bool p_use_strict_repository_paths = true
static std::string p_repository_root
static std::string p_repository_mapping_dir
static std::mutex p_parallel_out_mutex
static char * s_cwd = nullptr
static unsigned long p_count = 0
static int p_threads_pool_size = 0

Friends

class OksFile
class OksClass
class OksObject
struct OksLoadObjectsJob
struct OksData
std::ostream & operator<< (std::ostream &s, OksKernel &k)

Detailed Description

Provides interface to the OKS kernel.

It is responsible for loading OKS data and schema files and it provides access to loaded OKS classes and their objects.

To work with OKS schema the following base methods are available:

To work with OKS data the following base methods are available:

  • load_data() - load OKS data from file (i.e. read description of OKS objects)
  • reload_data() - reload data file, e.g. to revert to saved data or when it was modified by external process
  • new_data() - create new OKS data file
  • set_active_data() - use this data file for newly created classes
  • save_data() - save OKS data file
  • close_data() - close OKS data file and unload all objects from it
  • objects() - get all objects (unsorted by classes or IDs)

To work with OKS server the following methods can be used:

When schema or data are modified, the process can give callback using the following methods:

When objects are created in unordered manner or by efficiency reasons files are loaded with non-bind option, the objects can be bind (i.e. linked) using the following methods:

In case of problems most of above methods throw exceptions derived from oks::exception class.

Most of the OksKernel methods are thread-safe. Those which are not thread-safe, are started from prefix "k_".

Definition at line 581 of file kernel.hpp.

Member Typedef Documentation

◆ map_str_t

template<typename T>
using dunedaq::oks::OksKernel::map_str_t = std::map<std::string, T>
private

Definition at line 591 of file kernel.hpp.

Member Enumeration Documentation

◆ RepositoryUpdateType

Enumerator
DiscardChanges 
MergeChanges 
NoChanges 

Definition at line 1595 of file kernel.hpp.

Constructor & Destructor Documentation

◆ OksKernel() [1/2]

dunedaq::oks::OksKernel::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.

All parameters of the constructor are optional.

Parameters
silence_mode- defines kernel silence mode
verbose_mode- defines kernel verbose mode
profiling_mode- switch kernel into profiling mode

Definition at line 738 of file kernel.cpp.

738 :
739 p_silence (sm),
740 p_verbose (vm),
741 p_profiling (tm),
742 p_allow_repository (allow_repository),
748 p_active_schema (nullptr),
749 p_active_data (nullptr),
750 p_close_all (false),
751 profiler (nullptr),
758{
759 OSK_VERBOSE_REPORT("Enter OksKernel::OksKernel(" << sm << ", " << vm << ", " << tm << ')')
760
761 struct __InitFromEnv__ {
762 const char * name;
763 bool& value;
764 } vars[] = {
765 {"OKS_KERNEL_VERBOSE", p_verbose },
766 {"OKS_KERNEL_SILENCE", p_silence },
767 {"OKS_KERNEL_PROFILING", p_profiling },
768 {"OKS_KERNEL_ALLOW_REPOSITORY", p_allow_repository },
769 {"OKS_KERNEL_ALLOW_DUPLICATED_CLASSES", p_allow_duplicated_classes },
770 {"OKS_KERNEL_ALLOW_DUPLICATED_OBJECTS", p_allow_duplicated_objects },
771 {"OKS_KERNEL_TEST_DUPLICATED_OBJECTS_VIA_INHERITANCE", p_test_duplicated_objects_via_inheritance },
772 {"OKS_KERNEL_SKIP_STRING_RANGE", p_skip_string_range }
773 };
774
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;
778 }
779 }
780
781 {
782 const char * oks_db_root = getenv("OKS_DB_ROOT");
783
784 if (oks_db_root == nullptr || *oks_db_root == 0)
785 oks_db_root = getenv("DUNEDAQ_DB_PATH");
786 else
788
789 OSK_VERBOSE_REPORT("database root = \'" << oks_db_root << "\' (as defined by the OKS_DB_ROOT or DUNEDAQ_DB_PATH)");
790
791
792 // if not defined, set oks_db_root to empty string (to avoid std::string constructor crash when string is 0)
793
794 if (oks_db_root == nullptr)
795 oks_db_root = "";
796
797
798 // temporal set
799
800 Oks::Tokenizer t(oks_db_root, ":");
801 std::string token;
802
803 while (t.next(token))
805 }
806
807
808
809
810 {
811 std::unique_lock lock(p_kernel_mutex);
812
813 if(!p_count++) {
817 }
818
819 get_cwd();
820 }
821
822 {
823 static std::once_flag flag;
824
825 std::call_once(flag, []()
826 {
827 if (char * s = getenv("OKS_KERNEL_THREADS_POOL_SIZE"))
828 {
829 if (*s != '\0')
830 {
831 p_threads_pool_size = atoi(s);
832 if (p_threads_pool_size < 1)
834 }
835 }
836
838 {
839 errno = 0;
840 p_threads_pool_size = sysconf(_SC_NPROCESSORS_ONLN);
841 if (p_threads_pool_size == -1 && !errno)
842 {
843 Oks::error_msg("OksKernel::OksKernel()") << " sysconf(_SC_NPROCESSORS_ONLN) has failed with code " << errno << ": \'" << strerror(errno) << '\'' << std::endl;
845 }
846 }
847
850
851 TLOG_DEBUG(2) << "Threads pool size: " << p_threads_pool_size;
852 }
853 );
854
855 }
856
857 // process OKS server URL settings if any
858 if (p_allow_repository && !get_repository_root().empty())
859 {
860 if (get_user_repository_root().empty())
861 {
862 // parse specific version option if any
863 std::string param, val;
864
865 if (!version)
866 version = getenv("TDAQ_DB_VERSION");
867
868 if (version)
869 {
870 if(*version)
871 {
872 if(const char * value = strchr(version, ':'))
873 {
874 param.assign(version, value-version);
875 val.assign(value+1);
876 }
877 else
878 Oks::error_msg("OksKernel::OksKernel") << "bad version value \"" << version << "\" expecting parameter:value format (check TDAQ_DB_VERSION variable)" << std::endl;
879 }
880 }
881
882 try
883 {
884 std::string tmp_dirname = OksKernel::create_user_repository_dir();
885
886 set_user_repository_root(tmp_dirname);
889
890 if (branch_name.empty())
891 if (const char *var = getenv("TDAQ_DB_BRANCH"))
892 branch_name = var;
893
894 k_checkout_repository(param, val, branch_name);
895 }
896 catch(exception& ex)
897 {
898 Oks::error_msg("OksKernel::OksKernel") << "cannot check out user repository: " << ex.what() << std::endl;
899 }
900 }
901 else
902 {
903 if(!p_silence)
904 {
905 try
906 {
907 std::lock_guard lock(p_parallel_out_mutex);
908 std::cout << "attach to repository \"" << get_user_repository_root() << "\" version " << read_repository_version() << std::endl;
909 }
910 catch(exception& ex)
911 {
912 Oks::error_msg("OksKernel::OksKernel") << "cannot read user repository version: " << ex.what() << std::endl;
913 }
914 }
915 }
916 }
917
918#ifndef ERS_NO_DEBUG
919 if(p_profiling)
920 profiler = (OksProfiler *) new OksProfiler();
921#endif
922}
void insert(const std::string &path)
Definition kernel.cpp:96
static NotifyFN create_notify_fn
Definition class.hpp:971
static NotifyFN delete_notify_fn
Definition class.hpp:973
static ChangeNotifyFN change_notify_fn
Definition class.hpp:972
OksObject::notify_obj p_change_object_notify_fn
Definition kernel.hpp:2166
const std::string & get_user_repository_root() const
Get user OKS repository root.
Definition kernel.cpp:375
static bool p_use_strict_repository_paths
Definition kernel.hpp:2033
static std::mutex p_parallel_out_mutex
Definition kernel.hpp:2051
void set_user_repository_root(const std::string &path, const std::string &version="")
Set user OKS repository root.
Definition kernel.cpp:394
OksProfiler * profiler
Definition kernel.hpp:2075
std::string create_user_repository_dir()
Definition kernel.cpp:2230
OksObject::notify_obj p_delete_object_notify_fn
Definition kernel.hpp:2169
void * p_delete_object_notify_param
Definition kernel.hpp:2170
static int p_threads_pool_size
Definition kernel.hpp:2079
static unsigned long p_count
Definition kernel.hpp:2073
std::string read_repository_version()
Read and return current repository version.
Definition kernel.cpp:5514
std::string p_user_repository_root
Definition kernel.hpp:2037
static bool p_skip_string_range
Definition kernel.hpp:2032
static const std::string & get_repository_root()
Get OKS repository root.
Definition kernel.cpp:309
void * p_change_object_notify_param
Definition kernel.hpp:2167
static const char * get_cwd()
Definition kernel.cpp:694
std::shared_mutex p_kernel_mutex
Definition kernel.hpp:2047
bool p_test_duplicated_objects_via_inheritance
Definition kernel.hpp:2030
OksObject::notify_obj p_create_object_notify_fn
Definition kernel.hpp:2163
std::string insert_repository_dir(const std::string &dir, bool push_back=true)
Insert repository search directory.
Definition kernel.cpp:1403
void k_checkout_repository(const std::string &param, const std::string &val, const std::string &branch)
Check out repository files into local user directory.
Definition kernel.cpp:4885
void * p_create_object_notify_param
Definition kernel.hpp:2164
static std::ostream & error_msg(const char *)
Definition kernel.cpp:561
caught dunedaq::conffwk::Exception exception
#define OSK_VERBOSE_REPORT(MSG)
Definition defs.hpp:93
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
const std::string strerror(int error)
Convert C error number to string.
Definition kernel.cpp:119
static GitFoldersHolder s_git_folders
Definition kernel.cpp:115

◆ OksKernel() [2/2]

dunedaq::oks::OksKernel::OksKernel ( const OksKernel & src,
bool copy_repository = false )

Copy constructor.

It is used by RDB RW server to make fast copy.

Parameters
src- kernel to copy

Definition at line 924 of file kernel.cpp.

924 :
925 p_silence (src.p_silence),
926 p_verbose (src.p_verbose),
927 p_profiling (src.p_profiling),
928 p_allow_repository (src.p_allow_repository),
929 p_allow_duplicated_classes (src.p_allow_duplicated_classes),
930 p_allow_duplicated_objects (src.p_allow_duplicated_objects),
931 p_test_duplicated_objects_via_inheritance (src.p_test_duplicated_objects_via_inheritance),
932 p_user_repository_root (src.p_user_repository_root),
933 p_user_repository_root_inited (src.p_user_repository_root_inited),
935 p_repository_version (src.p_repository_version),
936 p_repository_checkout_ts (src.p_repository_checkout_ts),
937 p_repository_update_ts (src.p_repository_update_ts),
938 p_active_schema (nullptr),
939 p_active_data (nullptr),
940 p_close_all (false),
941 profiler (nullptr),
948{
949
950 {
951 std::unique_lock lock(p_kernel_mutex);
952 p_count++;
953 }
954
955 if (copy_repository && p_user_repository_root_inited)
956 {
957 try
958 {
963 k_copy_repository(src.p_user_repository_root, p_user_repository_root);
964 }
965 catch(exception& ex)
966 {
967 Oks::error_msg("OksKernel::OksKernel") << "cannot copy user repository: " << ex.what() << std::endl;
969 throw;
970 }
971
973 }
974
975
976 // copy repository directories
977 for (const auto& i : src.p_repository_dirs)
978 p_repository_dirs.push_back(i);
979
980
981 // copy schema and data files
982 {
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 };
985
986 for (int i = 0; i < 2; ++i)
987 {
988 for (const auto& j : *src_files[i])
989 {
990 OksFile * f = new OksFile(*j.second);
991 f->p_kernel = this;
992 (*dst_files[i])[&f->p_full_name] = f;
993 }
994 }
995 }
996
997 // search a class in map is not efficient, if there are many such operations; use array with class index for fast search
998 OksClass ** c_table = new OksClass * [src.p_classes.size()];
999 unsigned int idx(0);
1000
1001
1002 // copy classes: first iteration to define class names and simple properties
1003 for(const auto& i : src.p_classes) {
1004 const OksClass& src_c(*i.second);
1005 OksClass * c = new OksClass (src_c.p_name, src_c.p_description, src_c.p_abstract, nullptr, src_c.p_transient); // pass 0 kernel to avoid class insertion
1006
1007 c->p_kernel = this;
1008 p_classes[c->get_name().c_str()] = c;
1009
1010 const_cast<OksClass&>(src_c).p_id = idx++;
1011 c->p_id = src_c.p_id;
1012 c_table[c->p_id] = c;
1013
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);
1019
1020
1021 // copy super-classes
1022 if (const std::list<std::string *> * scls = src_c.p_super_classes)
1023 {
1024 c->p_super_classes = new std::list<std::string *>();
1025
1026 for (const auto& j : *scls)
1027 c->p_super_classes->push_back(new std::string(*j));
1028 }
1029
1030
1031 // copy direct attributes
1032 if (const std::list<OksAttribute *> * attrs = src_c.p_attributes)
1033 {
1034 c->p_attributes = new std::list<OksAttribute *>();
1035
1036 for (const auto& j : *attrs)
1037 {
1038 OksAttribute * a = new OksAttribute(j->p_name, c);
1039
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;
1048
1049 if (j->p_enumerators)
1050 a->p_enumerators = new std::vector<std::string>(*j->p_enumerators);
1051
1052 c->p_attributes->push_back(a);
1053 }
1054 }
1055
1056
1057 // copy direct relationships
1058 if (const std::list<OksRelationship *> * rels = src_c.p_relationships)
1059 {
1060 c->p_relationships = new std::list<OksRelationship *>();
1061
1062 for (const auto& j : *rels)
1063 {
1064 OksRelationship * r = new OksRelationship(j->p_name, c);
1065
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;
1073
1074 c->p_relationships->push_back(r);
1075 }
1076 }
1077
1078
1079 // copy direct methods
1080 if (const std::list<OksMethod *> * mets = src_c.p_methods)
1081 {
1082 c->p_methods = new std::list<OksMethod *>();
1083
1084 for (const auto& j : *mets)
1085 {
1086 OksMethod * m = new OksMethod(j->p_name, j->p_description, c);
1087
1088 if (const std::list<OksMethodImplementation *> * impls = j->p_implementations)
1089 {
1090 m->p_implementations = new std::list<OksMethodImplementation *>();
1091
1092 for (const auto& x : *impls)
1093 m->p_implementations->push_back(new OksMethodImplementation(x->get_language(), x->get_prototype(), x->get_body(), m));
1094 }
1095
1096 c->p_methods->push_back(m);
1097 }
1098 }
1099 }
1100
1101
1102 // copy classes: second iteration to resolve pointers to classes
1103
1104 for (const auto& i : src.p_classes)
1105 {
1106 OksClass * c = c_table[i.second->p_id];
1107
1108 // link p_class_type of relationship
1109 if (const std::list<OksRelationship *> * rels = i.second->p_relationships)
1110 {
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);
1113 }
1114
1115 // copy all super- and sub- classes
1116 if (const OksClass::FList * spcls = i.second->p_all_super_classes)
1117 {
1118 c->p_all_super_classes = new OksClass::FList();
1119
1120 for (const auto& j : *spcls)
1121 c->p_all_super_classes->push_back(c_table[j->p_id]);
1122 }
1123
1124 if (const OksClass::FList * sbcls = i.second->p_all_sub_classes)
1125 {
1126 c->p_all_sub_classes = new OksClass::FList();
1127
1128 for (const auto& j : *sbcls)
1129 c->p_all_sub_classes->push_back(c_table[j->p_id]);
1130 }
1131
1132 // create oks object layout information
1133 c->p_data_info = new OksDataInfo::Map();
1134 size_t instance_size = 0;
1135
1136 // copy all attributes
1137 if (const std::list<OksAttribute *> * attrs = i.second->p_all_attributes)
1138 {
1139 c->p_all_attributes = new std::list<OksAttribute *>();
1140
1141 for (const auto& j : *attrs)
1142 {
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);
1146 }
1147 }
1148
1149 // copy all relationships
1150 if (const std::list<OksRelationship *> * rels = i.second->p_all_relationships)
1151 {
1152 c->p_all_relationships = new std::list<OksRelationship *>();
1153
1154 for (const auto& j : *rels)
1155 {
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);
1159 }
1160 }
1161
1162 // copy all methods
1163 if (const std::list<OksMethod *> * mets = i.second->p_all_methods)
1164 {
1165 c->p_all_methods = new std::list<OksMethod *>();
1166
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()));
1169 }
1170
1171 // copy inheritance hierarchy
1172 if (const std::vector<OksClass *> * ih = i.second->p_inheritance_hierarchy)
1173 {
1174 c->p_inheritance_hierarchy = new std::vector<OksClass *>();
1175 c->p_inheritance_hierarchy->reserve(ih->size());
1176
1177 for (const auto& j : *ih)
1178 c->p_inheritance_hierarchy->push_back(c_table[j->p_id]);
1179 }
1180 }
1181
1182
1183 // copy objects
1184
1185 if(!src.p_objects.empty()) {
1186
1187 // search an object in a class is not efficien, if there are many such operations
1188 // use array with class index for fast search
1189
1190 OksObject ** o_table = new OksObject * [src.p_objects.size()];
1191 idx = 0;
1192
1193 // first iteration: create objects with attributes
1194
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);
1198
1199 OksClass * c = c_table[src_o->uid.class_id->p_id];
1200
1201 OksObject * o = new OksObject(
1202 c,
1203 src_o->uid.object_id,
1204 src_o->p_user_data,
1205 src_o->p_int32_id,
1206 src_o->p_duplicated_object_id_idx,
1207 (*p_data_files.find(&src_o->file->p_full_name)).second
1208 );
1209
1210 o_table[idx] = o;
1211 (*c->p_objects)[&o->uid.object_id] = o;
1212 p_objects.insert(o);
1213
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;
1217
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();
1220
1221 for(size_t j = 0; j < num_of_attrs; ++j) {
1222 *dst_data = *src_data;
1223
1224 OksAttribute * a_dst(*ia_dst);
1225
1226 // process in a special way CLASS type (reference on class)
1227
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];
1231 }
1232 else {
1233 OksData::List::iterator li_dst = dst_data->data.LIST->begin();
1234 OksData::List::iterator li_src = src_data->data.LIST->begin();
1235
1236 while(li_dst != dst_data->data.LIST->end()) {
1237 (*li_dst)->data.CLASS = c_table[(*li_src)->data.CLASS->p_id];
1238 ++li_dst;
1239 ++li_src;
1240 }
1241 }
1242 }
1243
1244 // process in a special way ENUM type (reference on attribute's data)
1245
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]));
1249
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]);
1253 }
1254 else {
1255 OksData::List::iterator li_dst = dst_data->data.LIST->begin();
1256 OksData::List::iterator li_src = src_data->data.LIST->begin();
1257
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]);
1261 ++li_dst;
1262 ++li_src;
1263 }
1264 }
1265 }
1266
1267 src_data++;
1268 dst_data++;
1269
1270 ia_dst++;
1271 ia_src++;
1272 }
1273 }
1274 }
1275
1276
1277 // second iteration: link relationships of objects
1278
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)]);
1282
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());
1286
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();
1294
1295 if(x->type == OksData::object_type)
1296 {
1297 if(const OksObject * o2 = x->data.OBJECT)
1298 {
1299 d->Set(o_table[reinterpret_cast<unsigned long>(o2->p_user_data)]);
1300 }
1301 else
1302 {
1303 d->Set((OksObject *)nullptr);
1304 }
1305 }
1306 else if(x->type == OksData::uid_type)
1307 {
1308 d->Set(c_table[x->data.UID.class_id->p_id], *x->data.UID.object_id);
1309 }
1310 else if(x->type == OksData::uid2_type)
1311 {
1312 d->Set(*x->data.UID2.class_id, *x->data.UID2.object_id);
1313 }
1314 else
1315 {
1316 ers::error(kernel::InternalError(ERS_HERE, "unexpected data type in relationship list"));
1317 }
1318
1319 dst_data->data.LIST->push_back(d);
1320 }
1321 break;
1322
1324 if(const OksObject * o2 = src_data->data.OBJECT) {
1325 dst_data->data.OBJECT = o_table[reinterpret_cast<unsigned long>(o2->p_user_data)];
1326 }
1327 else {
1328 dst_data->data.OBJECT = 0;
1329 }
1330 break;
1331
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);
1335 break;
1336
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);
1340 break;
1341
1342 default:
1343 ers::error(kernel::InternalError(ERS_HERE, "unexpected data type in relationship"));
1344 break;
1345 }
1346
1347 src_data++;
1348 dst_data++;
1349 }
1350 }
1351
1352 if (const std::list<OksRCR *> * src_rcrs = src_o->p_rcr)
1353 {
1354 o->p_rcr = new std::list<OksRCR *>();
1355
1356 for (const auto& j : *src_rcrs)
1357 o->p_rcr->push_back(
1358 new OksRCR(
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())
1361 )
1362 );
1363 }
1364 else
1365 {
1366 o->p_rcr = nullptr;
1367 }
1368 }
1369
1370 delete [] o_table;
1371 }
1372
1373 delete [] c_table;
1374
1375 // rename all files
1376 if (copy_repository && p_user_repository_root_inited)
1377 {
1378 OksFile::Map * files_map[2] = { &p_schema_files, &p_data_files };
1379
1380 for (int i = 0; i < 2; ++i)
1381 {
1382 std::vector<OksFile *> files;
1383
1384 for (auto& f : *files_map[i])
1385 files.push_back(f.second);
1386
1387 files_map[i]->clear();
1388
1389 for (auto& f : files)
1390 {
1391 std::string name = p_user_repository_root;
1392 name.push_back('/');
1393 name.append(f->get_repository_name());
1394 f->rename(name);
1395 (*files_map[i])[&f->p_full_name] = f;
1396 }
1397 }
1398 }
1399}
#define ERS_HERE
std::list< OksClass *, boost::fast_pool_allocator< OksClass * > > FList
Definition class.hpp:240
std::map< const std::string *, OksFile *, SortByName > Map
Definition file.hpp:372
friend class OksClass
Definition kernel.hpp:585
std::string p_repository_version
Definition kernel.hpp:2040
std::time_t p_repository_checkout_ts
Definition kernel.hpp:2041
OksClass::Map p_classes
Definition kernel.hpp:2071
OksFile::Map p_schema_files
Definition kernel.hpp:2055
friend struct OksData
Definition kernel.hpp:588
std::list< std::string > p_repository_dirs
Definition kernel.hpp:2066
void remove_user_repository_dir()
Definition kernel.cpp:4946
std::time_t p_repository_update_ts
Definition kernel.hpp:2042
void k_copy_repository(const std::string &source, const std::string &destination)
Definition kernel.cpp:4964
friend class OksFile
Definition kernel.hpp:584
friend class OksObject
Definition kernel.hpp:586
OksObject::Set p_objects
Definition kernel.hpp:2077
OksFile::Map p_data_files
Definition kernel.hpp:2056
std::unordered_map< const std::string *, OksObject *, oks::hash_str, oks::equal_str > Map
Definition object.hpp:870
static bool real_path(std::string &, bool ignore_errors)
Definition kernel.cpp:599
void error(const Issue &issue)
Definition ers.hpp:92
std::map< std::string, OksDataInfo * > Map
Declare map of pointers to OksDataInfo (unsorted by name).
Definition object.hpp:351
std::list< OksData *, boost::fast_pool_allocator< OksData * > > List
Definition object.hpp:460

◆ ~OksKernel()

dunedaq::oks::OksKernel::~OksKernel ( )

Definition at line 1464 of file kernel.cpp.

1465{
1466 {
1468 OSK_VERBOSE_REPORT("ENTER OksKernel::~OksKernel()")
1469
1472
1473 std::unique_lock lock(p_kernel_mutex);
1474
1475 p_classes.erase(p_classes.begin(), p_classes.end());
1476
1477 --p_count;
1478
1479 if(p_count == 0) {
1480 std::lock_guard scoped_lock(s_get_cwd_mutex);
1481 delete [] s_cwd;
1482 s_cwd = nullptr;
1483 }
1484
1486 }
1487
1488#ifndef ERS_NO_DEBUG
1489 if(p_profiling) std::cout << *profiler << std::endl;
1490#endif
1491
1492 OSK_VERBOSE_REPORT("LEAVE OksKernel::~OksKernel()")
1493}
static char * s_cwd
Definition kernel.hpp:2068
void close_all_data()
Close all OKS data files.
Definition kernel.cpp:4248
void close_all_schema()
Close all OKS schema files.
Definition kernel.cpp:2888
#define OSK_PROFILING(FID, K)
Definition defs.hpp:102
static std::mutex s_get_cwd_mutex
Definition kernel.cpp:57

Member Function Documentation

◆ add_data_file()

void dunedaq::oks::OksKernel::add_data_file ( OksFile * f)
private

Definition at line 3772 of file kernel.cpp.

3773{
3774 p_data_files[&f->p_full_name] = f;
3775}

◆ add_schema_file()

void dunedaq::oks::OksKernel::add_schema_file ( OksFile * f)
private

Definition at line 3778 of file kernel.cpp.

3779{
3780 p_schema_files[&f->p_full_name] = f;
3781}

◆ backup_data()

void dunedaq::oks::OksKernel::backup_data ( OksFile * pf,
const char * suffix = ".bak" )

Backup OKS data file.

The method makes a backup of given OKS data file. The save operation is silent and ignores any consistency rules. The file is always saved in extended format.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS data file descriptor
suffixa suffix to be added to the name of file
Exceptions
Throwoks::exception in case of problems.

Definition at line 3813 of file kernel.cpp.

3814{
3815 std::shared_lock lock(p_kernel_mutex);
3816
3817 OksFile f(
3818 pf->get_full_file_name() + suffix,
3819 pf->get_logical_name(),
3820 pf->get_type(),
3821 pf->get_oks_format(),
3822 this
3823 );
3824
3825 f.p_created_by = pf->p_created_by;
3826 f.p_creation_time = pf->p_creation_time;
3827 f.p_created_on = pf->p_created_on;
3828 f.p_list_of_include_files = pf->p_list_of_include_files;
3829
3830 if(!p_silence) {
3831 std::lock_guard lock(p_parallel_out_mutex);
3832 std::cout << "Making backup of data file \"" << pf->p_full_name << "\"...\n";
3833 }
3834
3835 bool silence = p_silence;
3836
3837 p_silence = true;
3838
3839 try {
3840 k_save_data(&f, true, pf);
3841 }
3842 catch(exception& ex) {
3843 p_silence = silence;
3844 throw CanNotBackupFile(pf->p_full_name, ex);
3845 }
3846
3847 p_silence = silence;
3848}
void k_save_data(OksFile *, bool=false, OksFile *=nullptr, const OksObject::FSet *=nullptr, bool force_defaults=false)
Definition kernel.cpp:3854

◆ backup_schema()

void dunedaq::oks::OksKernel::backup_schema ( OksFile * pf,
const char * suffix = ".bak" )

Backup OKS schema file.

The method makes a backup of given OKS schema file. The save operation is silent and ignores any consistency rules.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS data file descriptor
suffixa suffix to be added to the name of file
Exceptions
Throwoks::exception in case of problems.

Definition at line 2559 of file kernel.cpp.

2560{
2561 std::shared_lock lock(p_kernel_mutex);
2562
2563 OksFile f(
2564 pf->get_full_file_name() + suffix,
2565 pf->get_logical_name(),
2566 pf->get_type(),
2567 pf->get_oks_format(),
2568 this
2569 );
2570
2571 f.p_created_by = pf->p_created_by;
2572 f.p_creation_time = pf->p_creation_time;
2573 f.p_created_on = pf->p_created_on;
2574 f.p_list_of_include_files = pf->p_list_of_include_files;
2575
2576 if(!p_silence) {
2577 std::cout << "Making backup of schema file \"" << pf->p_full_name << "\"...\n";
2578 }
2579
2580 bool silence = p_silence;
2581
2582 p_silence = true;
2583
2584 try {
2585 k_save_schema(&f, true, pf);
2586 }
2587 catch(exception& ex) {
2588 p_silence = silence;
2589 throw CanNotBackupFile(pf->p_full_name, ex);
2590 }
2591
2592 p_silence = silence;
2593}
void k_save_schema(OksFile *, bool force=false, OksFile *=0, const OksClass::Map *=0)
Definition kernel.cpp:2598

◆ bind_objects()

void dunedaq::oks::OksKernel::bind_objects ( )

Bind oks objects.

The method sets links between oks objects converting whenever it is possible values of relationships from the UID types to the OksObject pointer. It is used after sequential loading of several data files with bind_objects parameter set to false.

The status of the last bind objects call can be checked using get_bind_objects_status() method.

Exceptions
Throwoks::exception in case of problems.

Definition at line 4366 of file kernel.cpp.

4367{
4368 std::unique_lock lock(p_kernel_mutex);
4370}

◆ check_read_only()

bool dunedaq::oks::OksKernel::check_read_only ( OksFile * f)
static

Check if the OKS file is read-only.

Method returns true if the file is read-only and false if it is not. The method also changes the read-only flag in the file descriptor.

The method is thread-safe.

Definition at line 1537 of file kernel.cpp.

1538{
1539 static std::string suffix;
1540 static std::once_flag flag;
1541
1542 std::call_once(flag, []()
1543 {
1544 std::ostringstream s;
1545 s << '-' << get_user_name() << ':' << get_host_name() << ':' << getpid() << std::ends;
1546 suffix = s.str();
1547 }
1548 );
1549
1550 std::string s(fp->p_full_name);
1551 s.append(suffix);
1552
1553 {
1554 static std::mutex p_check_read_only_mutex;
1555 std::lock_guard scoped_lock(p_check_read_only_mutex);
1556
1557 {
1558 std::ofstream f(s.c_str(), std::ios::out);
1559 fp->p_is_read_only = (!f.good());
1560 }
1561
1562 TLOG_DEBUG( 3) << "read-only test on file \"" << s << "\" returns " << fp->p_is_read_only ;
1563
1564 if(!fp->p_is_read_only) {
1565 unlink(s.c_str());
1566 }
1567
1568 return fp->p_is_read_only;
1569 }
1570}
static std::string & get_host_name()
Get hostname of given process.
Definition kernel.cpp:434
static std::string & get_user_name()
Get username of given process.
Definition kernel.cpp:473

◆ classes()

const OksClass::Map & dunedaq::oks::OksKernel::classes ( ) const
inline

Get classes.

In multi-threaded environment to iterate through the set it could be necessary to acquire at least read oks kernel lock before calling the method to be sure that another thread does not modify the set of classes (i.e. destroy or create classes, open or close oks schema files).

Returns
The method returns const reference on set of classes loaded in-memory.

Definition at line 1772 of file kernel.hpp.

1772{return p_classes;}

◆ clear_preload_file_info()

void dunedaq::oks::OksKernel::clear_preload_file_info ( )
private

Definition at line 3530 of file kernel.cpp.

3531{
3532 for(std::map<const OksFile *, OksFile *>::iterator i = p_preload_file_info.begin(); i != p_preload_file_info.end(); ++i) {
3533 delete i->second;
3534 }
3535
3536 p_preload_file_info.clear();
3537 p_preload_added_files.clear();
3538}
std::vector< OksFile * > p_preload_added_files
Definition kernel.hpp:2087
std::map< const OksFile *, OksFile * > p_preload_file_info
Definition kernel.hpp:2086

◆ close_all_data()

void dunedaq::oks::OksKernel::close_all_data ( )

Close all OKS data files.

The method closes all OKS data files which were created or loaded by the OKS kernel.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Definition at line 4248 of file kernel.cpp.

4249{
4250 TLOG_DEBUG(4) << "enter";
4251
4252 {
4253 std::unique_lock lock(p_kernel_mutex);
4254
4255 p_close_all = true;
4256
4257 while(!p_data_files.empty()) {
4258 k_close_data(p_data_files.begin()->second, false);
4259 }
4260
4261 if(!p_objects.empty()) {
4262 for(OksObject::Set::iterator i = p_objects.begin(); i != p_objects.end(); ++i) {
4263 delete *i;
4264 }
4265
4266 p_objects.clear();
4267
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;
4272 }
4273 }
4274 }
4275
4276 p_close_all = false;
4277 }
4278
4279 TLOG_DEBUG(4) << "exit";
4280}
void k_close_data(OksFile *, bool)
Definition kernel.cpp:4197

◆ close_all_schema()

void dunedaq::oks::OksKernel::close_all_schema ( )

Close all OKS schema files.

The method closes all OKS schema files which were created or loaded by the OKS kernel.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Definition at line 2888 of file kernel.cpp.

2889{
2890 TLOG_DEBUG(4) << "enter";
2891
2892 {
2893 std::unique_lock lock(p_kernel_mutex);
2894
2895 for(OksClass::Map::iterator i = p_classes.begin(); i != p_classes.end(); ++i) {
2896 i->second->p_to_be_deleted = true;
2897 }
2898
2899 while(!p_schema_files.empty()) {
2900 k_close_schema(p_schema_files.begin()->second);
2901 }
2902 }
2903
2904 TLOG_DEBUG(4) << "exit";
2905}
void k_close_schema(OksFile *)
Definition kernel.cpp:2834

◆ close_data()

void dunedaq::oks::OksKernel::close_data ( OksFile * file_h,
bool unbind_objects = true )

Close OKS data file.

The method closes given OKS data file. All objects belonging to this data file will be destroyed in-memory. The relationships values of objects from others data files loaded in-memory will be converted from OksObject pointer to UID for all objects of closing data file, if the unbind_objects parameter is true. If it is necessary to close all loaded data files, it is recommended to use close_all_data() method and do not use close_data(..., true) method sequentially by performance reasons.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS schema file descriptor returned by a kernel method
unbind_objectsconvert values of relationships pointing to objects of closing data file from OksObject pointer to the UID

Definition at line 4188 of file kernel.cpp.

4189{
4190 std::unique_lock lock(p_kernel_mutex);
4191 k_close_data(fp, unbind);
4192}

◆ close_schema()

void dunedaq::oks::OksKernel::close_schema ( OksFile * file_h)

Close OKS schema file.

The method closes given OKS schema file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS schema file descriptor returned by a kernel method

Definition at line 2825 of file kernel.cpp.

2826{
2827 std::unique_lock lock(p_kernel_mutex);
2828 k_close_schema(pf);
2829}

◆ commit_repository()

void dunedaq::oks::OksKernel::commit_repository ( const std::string & comments,
const std::string & credentials = "" )

Commit user modifications into repository.

The method commits changes made in user repository into origin GIT repository.

Parameters
commentsuser comments
credentialsdaq token to get real user name (ignore, if empty)
Exceptions
Throwoks::exception in case of problems.

Definition at line 5062 of file kernel.cpp.

5063{
5064 std::unique_lock lock(p_kernel_mutex);
5065
5066 if (OksKernel::get_repository_root().empty())
5067 throw RepositoryOperationFailed("commit", "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5068
5069 if (get_user_repository_root().empty())
5070 throw RepositoryOperationFailed("commit", "the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5071
5072 std::string cmd("oks-commit.sh");
5073
5074 if (get_verbose_mode())
5075 cmd.append(" -v");
5076
5077 cmd.append(" -u ");
5078 cmd.append(get_user_repository_root());
5079
5080 if(comments.empty() || std::all_of(comments.begin(), comments.end(), [](char c) { return std::isspace(c); }))
5081 throw RepositoryOperationFailed("commit", "the commit message may not be empty");
5082
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");
5084
5085 try
5086 {
5087 std::ofstream f(log_file_name);
5088
5089 f.exceptions(std::ostream::failbit | std::ostream::badbit);
5090
5091 if (!f)
5092 throw std::runtime_error("create message file failed");
5093
5094 f << comments;
5095 f.close();
5096 }
5097 catch (const std::exception& ex)
5098 {
5099 std::ostringstream ss;
5100 ss << "cannot write to file \'" << log_file_name << "\' to save commit message: " << ex.what();
5101 throw RepositoryOperationFailed("commit", ss.str());
5102 }
5103
5104 cmd.append(" -f \'");
5105 cmd.append(log_file_name);
5106 cmd.push_back('\'');
5107
5108 // if (!credentials.empty())
5109 // {
5110 // try
5111 // {
5112 // auto token = daq::tokens::verify(credentials);
5113
5114 // const std::string author = token.get_subject();
5115
5116 // std::string email;
5117
5118 // if (token.has_payload_claim("email"))
5119 // email = token.get_payload_claim("email").as_string();
5120
5121 // if (email.empty())
5122 // email = author + '@' + get_domain_name();
5123
5124 // OksSystem::User user(author);
5125
5126 // cmd.append(" -n \'");
5127 // cmd.append(user.real_name());
5128 // cmd.append("\' -e \'");
5129 // cmd.append(email);
5130 // cmd.push_back('\'');
5131
5132 // static std::once_flag flag;
5133
5134 // std::call_once(flag, []()
5135 // {
5136 // const char * opt = " -o SendEnv=OKS_COMMIT_USER";
5137
5138 // std::string val;
5139
5140 // if (const char * s = getenv("GIT_SSH_COMMAND"))
5141 // {
5142 // if (strstr(s, opt) == nullptr)
5143 // val = s;
5144 // }
5145 // else
5146 // {
5147 // val = "ssh";
5148 // }
5149
5150 // if (!val.empty())
5151 // {
5152 // val.append(opt);
5153 // setenv("GIT_SSH_COMMAND", val.c_str(), 1);
5154 // }
5155 // }
5156 // );
5157
5158 // setenv("OKS_COMMIT_USER", credentials.c_str(), 1);
5159 // }
5160 // catch(const ers::Issue& ex)
5161 // {
5162 // std::ostringstream text;
5163 // text << '\t' << ex;
5164 // throw RepositoryOperationFailed("commit", text.str());
5165 // }
5166 // }
5167
5168 auto start_usage = std::chrono::steady_clock::now();
5169
5170 if (!p_silence)
5171 {
5172 std::lock_guard lock(p_parallel_out_mutex);
5173 log_timestamp() << "[OKS commit] => " << cmd << std::endl;
5174 }
5175
5176 CommandOutput cmd_out("oks-commit", this, cmd);
5177
5178 int status = system(cmd.c_str());
5179
5180 unlink(log_file_name.c_str());
5181
5182 if (!credentials.empty())
5183 unsetenv("OKS_COMMIT_USER");
5184
5185 cmd_out.check_command_status(status);
5186
5187 p_repository_update_ts = std::time(0);
5188
5189 if (!p_silence)
5190 {
5191 std::lock_guard lock(p_parallel_out_mutex);
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;
5194 }
5195
5196 static std::string version_prefix("commit oks version ");
5197 std::string version = cmd_out.last_str();
5198 std::string::size_type pos = version.find(version_prefix);
5199
5200 if(pos == 0)
5201 p_repository_version = version.substr(version_prefix.size());
5202 else
5203 throw RepositoryOperationFailed("commit", "cannot read oks version");
5204}
bool get_verbose_mode() const
Get status of verbose mode. The method returns true, if the verbose mode is switched 'On'.
Definition kernel.hpp:670
std::ostream & log_timestamp(__LogSeverity__ severity=Log)
Definition kernel.cpp:5727

◆ create_file_info()

OksFile * dunedaq::oks::OksKernel::create_file_info ( const std::string & short_file_name,
const std::string & file_name )

Creates OKS file descriptor.

Method returns pointer to the OKS file descriptor defined by the file_name parameter or 0 if such file does not exist. The user is responsible to destroy the descriptor after usage.

Parameters
short_file_nameshort name of the file (e.g. relative to OKS root)
file_namean absolute file name

The method is thread-safe.

Definition at line 1573 of file kernel.cpp.

1574{
1575 OksFile * file_h = 0;
1576
1577 {
1578 std::shared_ptr<std::ifstream> f(new std::ifstream(full_path.c_str()));
1579
1580 if(f->good()) {
1581 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(f));
1582 file_h = new OksFile(xmls, short_path, full_path, this);
1583 }
1584 }
1585
1586 // check file access permissions
1587
1588 if(file_h) {
1589 check_read_only(file_h);
1590 }
1591
1592 return file_h;
1593}
static bool check_read_only(OksFile *f)
Check if the OKS file is read-only.
Definition kernel.cpp:1537

◆ create_list_of_data_objects()

std::list< OksObject * > * dunedaq::oks::OksKernel::create_list_of_data_objects ( OksFile * fp) const

Creates list of objects which belong to given file.

Method returns pointer to the list of OKS objects or 0 if the file contains no objects. The user is responsible to destroy the list after usage.

The user should acquire a lock on OKS kernel before calling such method in the multi-threaded environment.

Definition at line 4332 of file kernel.cpp.

4333{
4334 const char _fname[] = "create_list_of_data_objects";
4335 std::string fname = make_fname(_fname, sizeof(_fname)-1, fp->get_full_file_name(), nullptr, nullptr);
4336
4338 OSK_VERBOSE_REPORT("ENTER " << fname)
4339
4340
4341 std::list<OksObject *> * olist = new std::list<OksObject *>();
4342
4343 if(!p_objects.empty()) {
4344 for(OksObject::Set::const_iterator i = p_objects.begin(); i != p_objects.end(); ++i) {
4345 if((*i)->file == fp) olist->push_back(*i);
4346 }
4347 }
4348
4349 if(olist->empty()) {
4350 delete olist;
4351 olist = 0;
4352 }
4353
4354
4355 OSK_VERBOSE_REPORT("LEAVE " << fname)
4356
4357 return olist;
4358}
std::string make_fname(const char *f, size_t f_len, const std::string &file, bool *p, const OksFile *const *fh)
Definition kernel.cpp:517

◆ create_list_of_schema_classes()

std::list< OksClass * > * dunedaq::oks::OksKernel::create_list_of_schema_classes ( OksFile * pf) const

Creates list of classes which belong to given file.

Method returns pointer to the list of OKS classes or 0 if the file contains no classes. The user is responsible to destroy the list after usage.

The user should acquire a lock on OKS kernel before calling such method in the multi-threaded environment.

Definition at line 2955 of file kernel.cpp.

2956{
2957 std::string fname("OksKernel::create_list_of_schema_classes(");
2958 fname.append(pf->get_full_file_name());
2959 fname.push_back('\'');
2960
2962 OSK_VERBOSE_REPORT("ENTER " << fname)
2963
2964 std::list<OksClass *> * clist = nullptr;
2965
2966 if(!p_classes.empty()) {
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 *>())) {
2970 return 0;
2971 }
2972
2973 clist->push_back(i->second);
2974 }
2975 }
2976 }
2977
2978 OSK_VERBOSE_REPORT("LEAVE " << fname)
2979
2980 return clist;
2981}

◆ create_lists_of_updated_data_files()

void dunedaq::oks::OksKernel::create_lists_of_updated_data_files ( std::list< OksFile * > ** updated,
std::list< OksFile * > ** removed ) const

Get modified data files.

The method returns all data files which were modified or removed by an external process. The method checks file system status of all OKS data files loaded and created by the OKS kernel. The file is considered to be updated if it was modified after it was last time saved by the OKS kernel, or modified after it was loaded or created.

The method return parameters are:

Parameters
updatedpointer to the list of modified data files
removedpointer to the list of removed data files

The user is responsible to delete returned pointers after usage.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Definition at line 3014 of file kernel.cpp.

3015{
3016 std::shared_lock lock(p_kernel_mutex);
3017
3019}
static void create_updated_lists(const OksFile::Map &files, std::list< OksFile * > **ufs, std::list< OksFile * > **rfs, OksFile::FileStatus wu, OksFile::FileStatus wr)
Definition kernel.cpp:2986

◆ create_lists_of_updated_schema_files()

void dunedaq::oks::OksKernel::create_lists_of_updated_schema_files ( std::list< OksFile * > ** updated,
std::list< OksFile * > ** removed ) const

Get modified schema files.

The method returns all schema files which were modified or removed by an external process. The method checks file system status of all OKS schema files loaded and created by the OKS kernel. The file is considered to be updated if it was modified after it was last time saved by the OKS kernel, or modified after it was loaded or created.

The method return parameters are:

Parameters
updatedpointer to the list of modified schema files
removedpointer to the list of removed schema files

The user is responsible to delete returned pointers after usage.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Definition at line 3006 of file kernel.cpp.

3007{
3008 std::shared_lock lock(p_kernel_mutex);
3009
3011}

◆ create_user_repository_dir()

std::string dunedaq::oks::OksKernel::create_user_repository_dir ( )
private

Definition at line 2230 of file kernel.cpp.

2231{
2232 if (const char * path = getenv("TDAQ_DB_USER_REPOSITORY_PATH"))
2233 return path;
2234
2235 // create user repository directory if necessary
2236 std::string user_repo;
2237
2238 if (const char * user_repo_base = getenv("TDAQ_DB_USER_REPOSITORY_ROOT"))
2239 user_repo = user_repo_base;
2240 else
2241 user_repo = get_temporary_dir();
2242
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);
2246 else
2247 user_repo.append("oks.XXXXXX");
2248
2249 std::unique_ptr<char[]> dir_template(new char[user_repo.size() + 1]);
2250 strcpy(dir_template.get(), user_repo.c_str());
2251
2252 if (char * tmp_dirname = mkdtemp(dir_template.get()))
2253 {
2254 return tmp_dirname;
2255 }
2256
2257 throw CanNotCreateRepositoryDir("make_user_repository_dir", user_repo);
2258}

◆ data_files()

const OksFile::Map & dunedaq::oks::OksKernel::data_files ( ) const
inline

Get all data files.

Get all data files which were created or loaded by the OKS kernel. The method is thread-safe.

Returns
Return map of the OKS data file descriptors (sorted by file names).

Definition at line 1498 of file kernel.hpp.

1498{return p_data_files;}

◆ define()

void dunedaq::oks::OksKernel::define ( OksObject * o)
inlineprivate

Definition at line 2153 of file kernel.hpp.

2153{ std::lock_guard lock(p_objects_mutex); p_objects.insert(o); }
std::mutex p_objects_mutex
Definition kernel.hpp:2048

◆ find_class() [1/2]

OksClass * dunedaq::oks::OksKernel::find_class ( const char * class_name) const

Find class by name (C-string).

If the method is used in the multi-threaded environment, it could be necessary to set read kernel lock before calling the method, if other threads can to create or to destroy oks classes and to open or close oks schema files.

Parameters
class_namename of the class
Returns
Return pointer on OKS class or null pointer, if such class cannot be found.

Definition at line 4456 of file kernel.cpp.

4457{
4458 OksClass::Map::const_iterator i = p_classes.find(name);
4459 return (i != p_classes.end() ? i->second : 0);
4460}

◆ find_class() [2/2]

OksClass * dunedaq::oks::OksKernel::find_class ( const std::string & class_name) const
inline

Find class by name (C++ string).

If the method is used in the multi-threaded environment, it could be necessary to set read kernel lock before calling the method, if other threads can to create or to destroy oks classes and to open or close oks schema files.

Parameters
class_namename of the class (std::string)
Returns
Return pointer on OKS class or null pointer, if such class can not be found.

Definition at line 1819 of file kernel.hpp.

1819{ return find_class(class_name.c_str()); }
OksClass * find_class(const std::string &class_name) const
Find class by name (C++ string).
Definition kernel.hpp:1819

◆ find_data_file()

OksFile * dunedaq::oks::OksKernel::find_data_file ( const std::string & s) const

Finds OKS data file.

Method returns pointer to the OKS data file with name s or 0, if there is no such data file found.

The user should acquire a lock on OKS kernel before calling such method in the multi-threaded environment.

Definition at line 2292 of file kernel.cpp.

2293{
2294 return find_file(s, p_data_files);
2295}
OksFile * find_file(const std::string &s, const OksFile::Map &files) const
Definition kernel.cpp:2262

◆ find_file()

OksFile * dunedaq::oks::OksKernel::find_file ( const std::string & s,
const OksFile::Map & files ) const
private

Definition at line 2262 of file kernel.cpp.

2263{
2264 try {
2265 std::string at = get_file_path(s, nullptr);
2266 OksFile::Map::const_iterator i = files.find(&at);
2267 if(i != files.end()) return (*i).second;
2268 }
2269 catch (...) {
2270 // return 0;
2271 }
2272
2273 // search files included as relative to parent
2274 for(const auto& f : files)
2275 {
2276 if (s == f.second->get_short_file_name())
2277 {
2278 return f.second;
2279 }
2280 }
2281
2282 return nullptr;
2283}
std::string get_file_path(const std::string &path, const OksFile *parent_file=0, bool strict_paths=true) const
Calculates full path to file.
Definition kernel.cpp:1665

◆ find_schema_file()

OksFile * dunedaq::oks::OksKernel::find_schema_file ( const std::string & s) const

Finds OKS schema file.

Method returns pointer to the OKS schema file with name s or 0, if there is no such schema file found.

The user should acquire a lock on OKS kernel before calling such method in the multi-threaded environment.

Definition at line 2286 of file kernel.cpp.

2287{
2288 return find_file(s, p_schema_files);
2289}

◆ get_active_data()

OksFile * dunedaq::oks::OksKernel::get_active_data ( ) const
inline

Get active OKS data file.

The method is thread-safe.

Returns
Return pointer to the active OKS data file descriptor or 0 if there is no an active data file.

Definition at line 1486 of file kernel.hpp.

1486{return p_active_data;}

◆ get_active_schema()

OksFile * dunedaq::oks::OksKernel::get_active_schema ( ) const
inline

Get active OKS schema file.

The method returns active schema file.

Returns
Return pointer to the active OKS schema file descriptor or 0 if there is no an active schema.

The method is thread-safe.

Definition at line 1215 of file kernel.hpp.

1215{return p_active_schema;}

◆ get_all_classes()

void dunedaq::oks::OksKernel::get_all_classes ( const std::vector< std::string > & names_in,
ClassSet & classes_out ) const

The method searches all classes including subclasses for given names.

Parameters
names_inarray of names of the classes to search in
classes_outthe output containing pointers to all classes by above names and their subclasses

Definition at line 4680 of file kernel.cpp.

4681{
4682 for(std::vector<std::string>::const_iterator i = names_in.begin(); i != names_in.end(); ++i) {
4683 OksClass * c = find_class(*i);
4684 if(c != 0 && classes_out.find(c) == classes_out.end()) {
4685 classes_out.insert(c);
4686 if(const OksClass::FList * sc = c->all_sub_classes()) {
4687 for(OksClass::FList::const_iterator j = sc->begin(); j != sc->end(); ++j) {
4688 classes_out.insert(*j);
4689 }
4690 }
4691 }
4692 }
4693}

◆ get_allow_duplicated_classes_mode()

bool dunedaq::oks::OksKernel::get_allow_duplicated_classes_mode ( ) const
inline

Get status of duplicated classes mode. The method returns true, if the duplicated classes mode is switched 'On'. In such case the OKS will allow to load classes with equal names. Only first loaded class is taken into account, the next ones are ignored.

Definition at line 735 of file kernel.hpp.

◆ get_allow_duplicated_objects_mode()

bool dunedaq::oks::OksKernel::get_allow_duplicated_objects_mode ( ) const
inline

Get status of duplicated objects mode. The method returns true, if the duplicated objects mode is switched 'On'. In such case the OKS will allow to load objects of the same class with equal IDs. The ID for duplicated object will be generated automatically.

Definition at line 746 of file kernel.hpp.

◆ get_bind_classes_status()

const std::string & dunedaq::oks::OksKernel::get_bind_classes_status ( ) const
inlinenoexcept

Return status of oks classes binding.

The method checks lack of dangling references on class types and returns string containing unbound references if any.

Returns
If all classes were successfully linked, the string is empty. Otherwise it contains description of unbound references and classes.

Definition at line 2012 of file kernel.hpp.

2012{ return p_bind_classes_status; }
std::string p_bind_classes_status
Definition kernel.hpp:2082

◆ get_bind_objects_status()

const std::string & dunedaq::oks::OksKernel::get_bind_objects_status ( ) const
inlinenoexcept

Return status of oks objects binding.

The method returns string containing unbound references after last bind_objects() call.

Returns
If all objects were successfully linked, the string is empty. Otherwise it contains description of unbound references and objects.

Definition at line 2000 of file kernel.hpp.

2000{ return p_bind_objects_status; }
std::string p_bind_objects_status
Definition kernel.hpp:2081

◆ get_cwd()

const char * dunedaq::oks::OksKernel::get_cwd ( )
static
Returns
current working dir

Definition at line 694 of file kernel.cpp.

695{
696 std::lock_guard scoped_lock(s_get_cwd_mutex);
697
698 if (!s_cwd)
699 {
700 errno = 0;
701 long size = pathconf(".", _PC_PATH_MAX);
702 if (errno)
703 {
704 Oks::error_msg("OksKernel::OksKernel") << "pathconf(\".\", _PC_PATH_MAX) has failed with code " << errno << ": \'" << strerror(errno) << '\'' << std::endl;
705 }
706 else
707 {
708 if (size == -1)
709 {
710 size = PATH_MAX;
711 }
712 s_cwd = new char[size];
713 if (!getcwd(s_cwd, (size_t) size))
714 {
715 Oks::error_msg("OksKernel::OksKernel") << "getcwd() has failed with code " << errno << ": \'" << strerror(errno) << '\'' << std::endl;
716 delete[] s_cwd;
717 s_cwd = 0;
718 }
719 }
720
721 if (!s_cwd)
722 {
723 s_cwd = new char[2];
724 s_cwd[0] = '/';
725 s_cwd[1] = 0;
726 }
727
728 TLOG_DEBUG(1) << "Current working dir: \'" << s_cwd << '\'';
729 }
730
731 return s_cwd;
732}
FELIX Initialization std::string initerror FELIX queue timed std::string queuename Unexpected chunk size

◆ get_domain_name()

std::string & dunedaq::oks::OksKernel::get_domain_name ( )
static

Get domain name of host.

Definition at line 452 of file kernel.cpp.

453{
454 static std::string s_domain_name;
455 static std::once_flag flag;
456
457 std::call_once(flag, []()
458 {
459 std::string::size_type idx = get_host_name().find('.');
460
461 if (idx != std::string::npos)
462 s_domain_name = get_host_name().substr(idx+1);
463
464 if (s_domain_name.empty())
465 s_domain_name = "unknown.domain";
466 }
467 );
468
469 return s_domain_name;
470}

◆ get_file_path()

std::string dunedaq::oks::OksKernel::get_file_path ( const std::string & path,
const OksFile * parent_file = 0,
bool strict_paths = true ) const

Calculates full path to file.

Method calculates full path to file. It takes into account the values of the OKS_DB_ROOT, TDAQ_DB_REPOSITORY, TDAQ_DB_USER_REPOSITORY and TDAQ_DB_PATH environment variables and optionally checks if the path is relative to the parent file defined by the parent_file parameter.

The method is thread-safe.

Parameters
pathshort, relative or absolute path to file
parent_filepointer to file including given one
Exceptions
Throwstd::exception in case of problems.

Definition at line 1665 of file kernel.cpp.

1666{
1667 strict_paths &= p_use_strict_repository_paths;
1668
1669 const char _fname[] = "get_file_path";
1670 std::string fname;
1671
1672 TLOG_DEBUG(2) << "ENTER " << make_fname(_fname, sizeof(_fname)-1, s, nullptr, &file_h);
1673
1674 std::list<std::string> tested_files;
1675
1676 // check absolute path or path relative to working directory
1677 bool is_absolute_path = false;
1678
1679 std::string s2(s);
1681 fname = make_fname(_fname, sizeof(_fname) - 1, s2, nullptr, &file_h);
1682
1683 // test if file has an absolute path
1684 if (s2[0] == '/')
1685 is_absolute_path = true;
1686
1687 // continue only if the file is an absolute path or it is not included
1688 if (is_absolute_path || file_h == 0)
1689 {
1690 if (!is_absolute_path && s_cwd && *s_cwd)
1691 {
1692 std::string s3 = s_cwd;
1693 s3.push_back('/');
1694 s2 = s3 + s2;
1695 }
1696
1697 if (Oks::real_path(s2, true))
1698 {
1699 if (!get_user_repository_root().empty() && strict_paths)
1700 {
1701 if (!get_repository_mapping_dir().empty() && s2.find(get_repository_mapping_dir()) == 0)
1702 {
1703 s2.erase(0, get_repository_mapping_dir().size()+1);
1705 }
1706 else if (s2.find(get_user_repository_root()) == 0)
1707 {
1708 // presumably from explicitly set TDAQ_DB_USER_REPOSITORY created externally
1709 TLOG_DEBUG(2) << fname << " returns external \'" << s2 << "\' (an absolute filename or relative to CWD=\'" << s_cwd << "\')";
1710 return s2;
1711 }
1712
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());
1717 }
1718 else
1719 {
1720 TLOG_DEBUG(2) << fname << " returns \'" << s2 << "\' (an absolute filename or relative to CWD=\'" << s_cwd << "\')";
1721 return s2;
1722 }
1723 }
1724 else
1725 {
1726 if (is_absolute_path)
1727 {
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));
1730 }
1731 else
1732 {
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));
1735 }
1736 }
1737 }
1738
1739 if( !get_user_repository_root().empty())
1740 {
1742 }
1743
1745 {
1746 // check paths relative to OKS database root directories
1747 if (!is_absolute_path)
1748 for (auto & i : p_repository_dirs)
1749 {
1750 TEST_PATH_TOKEN(i, s, "DUNEDAQ_DB_PATH")
1751 }
1752
1753 // check non-absolute path relative to parent file if any
1754 if (file_h && !is_absolute_path)
1755 {
1756 std::string s2(file_h->get_full_file_name());
1757 std::string::size_type pos = s2.find_last_of('/');
1758
1759 if (pos != std::string::npos)
1760 {
1761 s2.erase(pos + 1);
1762 s2.append(s);
1764
1765 if (Oks::real_path(s2, true))
1766 {
1767 TLOG_DEBUG(2) << fname << " returns \'" << s2 << "\' (filename relative to parent file)";
1768 return s2;
1769 }
1770 else
1771 {
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));
1774 }
1775 }
1776 }
1777 }
1778
1779 TLOG_DEBUG(2) << fname << " throw exception (file was not found)";
1780
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;
1785
1786 throw std::runtime_error(text.str().c_str());
1787}
static const std::string & get_repository_mapping_dir()
Get OKS repository name.
Definition kernel.cpp:355
static void substitute_variables(std::string &)
Definition kernel.cpp:575
#define TEST_PATH_TOKEN(path, file, msg)
Definition kernel.cpp:1649
std::string mk_name_and_test(const std::string &name, const char *test, size_t test_len)
Definition kernel.cpp:1640

◆ get_host_name()

std::string & dunedaq::oks::OksKernel::get_host_name ( )
static

Get hostname of given process.

Definition at line 434 of file kernel.cpp.

435{
436 static std::string s_host_name;
437 static std::once_flag flag;
438
439 std::call_once(flag, []()
440 {
442
443 if (s_host_name.empty())
444 s_host_name = "unknown.host";
445 }
446 );
447
448 return s_host_name;
449}
static const std::string & full_local_name()
fully qualified local host name
Definition Host.cpp:216
static const LocalHost * instance()
pointer to the singleton local host
Definition Host.cpp:226

◆ get_includes()

void dunedaq::oks::OksKernel::get_includes ( const std::string & file_name,
std::set< std::string > & includes,
bool use_repository_name = false )

Opens file and reads its shallow includes.

The method is thread-safe.

Exceptions
Throwstd::exception in case of problems.

Definition at line 1919 of file kernel.cpp.

1920{
1921 try {
1922 std::shared_ptr<std::ifstream> f(new std::ifstream(file_name.c_str()));
1923
1924 if(!f->good()) {
1925 throw std::runtime_error("get_includes(): cannot open file");
1926 }
1927
1928 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(f));
1929 OksFile fp(xmls, file_name, file_name, this);
1930
1931 if(fp.p_list_of_include_files.size()) {
1932 for(std::list<std::string>::iterator i = fp.p_list_of_include_files.begin(); i != fp.p_list_of_include_files.end(); ++i) {
1933 includes.insert(use_repository_name ? get_file_path(*i, &fp).substr(get_user_repository_root().size()+1) : get_file_path(*i, &fp));
1934 }
1935 }
1936
1937 f->close();
1938 }
1939 catch (exception & e) {
1940 throw (FailedLoadFile("file", file_name, e));
1941 }
1942 catch (std::exception & e) {
1943 throw (FailedLoadFile("file", file_name, e.what()));
1944 }
1945}

◆ get_modified_files()

void dunedaq::oks::OksKernel::get_modified_files ( std::set< OksFile * > & mfs,
std::set< OksFile * > & rfs,
const std::string & version )

Get modified data files.

The method returns the data files modified or removed by an external process in file system or repository.

The method return parameters are:

Parameters
mfsset of modified data files
rfsset of removed data files
versionrepository version to compare with (if needed)

The user is responsible to delete returned pointers after usage.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Definition at line 3022 of file kernel.cpp.

3023{
3024 std::list<OksFile *> * files[] =
3025 { nullptr, nullptr, nullptr, nullptr };
3026
3027 std::set<OksFile *> * sets[] =
3028 { &mfs, &rfs };
3029
3030 create_lists_of_updated_data_files(&files[0], &files[1]);
3031 create_lists_of_updated_schema_files(&files[2], &files[3]);
3032
3033 for (int i = 0; i < 4; ++i)
3034 if (std::list<OksFile *> * f = files[i])
3035 {
3036 while (!f->empty())
3037 {
3038 sets[i % 2]->insert(f->front());
3039 f->pop_front();
3040 }
3041 delete f;
3042 }
3043
3044 if (!get_user_repository_root().empty() && !version.empty())
3045 for (const auto& file_name : get_repository_versions_diff(get_repository_version(), version))
3046 {
3047 if (OksFile * f = find_data_file(file_name))
3048 sets[0]->insert(f);
3049 else if (OksFile * f = find_schema_file(file_name))
3050 sets[0]->insert(f);
3051 }
3052}
std::list< std::string > get_repository_versions_diff(const std::string &sha1, const std::string &sha2)
Definition kernel.cpp:5254
void create_lists_of_updated_data_files(std::list< OksFile * > **updated, std::list< OksFile * > **removed) const
Get modified data files.
Definition kernel.cpp:3014
OksFile * find_data_file(const std::string &s) const
Finds OKS data file.
Definition kernel.cpp:2292
void create_lists_of_updated_schema_files(std::list< OksFile * > **updated, std::list< OksFile * > **removed) const
Get modified schema files.
Definition kernel.cpp:3006
OksFile * find_schema_file(const std::string &s) const
Finds OKS schema file.
Definition kernel.cpp:2286
const std::string & get_repository_version()
Definition kernel.hpp:941

◆ get_mutex()

std::shared_mutex & dunedaq::oks::OksKernel::get_mutex ( )
inline

Return OKS kernel mutex.

The mutex is used to lock most OKS kernel update operations like loading of files. It is used by the RDB server performing OKS operations in multi-threaded environment.

Definition at line 825 of file kernel.hpp.

825{return p_kernel_mutex;}

◆ get_profiling_mode()

bool dunedaq::oks::OksKernel::get_profiling_mode ( ) const
inline

Get status of profiling mode. The method returns true, if the profiling mode is switched 'On'. In such case the OKS will report time spend to execute main methods and a summary table of their calls on the OKS kernel destroy.

Definition at line 713 of file kernel.hpp.

713{return p_profiling;}

◆ get_repository_checkout_ts()

std::time_t dunedaq::oks::OksKernel::get_repository_checkout_ts ( ) const
inline

Return repository checkout timestamp.

Return timestamp when the repository was checkout or updated last time (e.g. to track new changes).

Definition at line 1589 of file kernel.hpp.

1590 {
1592 }

◆ get_repository_dirs()

const std::list< std::string > & dunedaq::oks::OksKernel::get_repository_dirs ( ) const
inline

Get repository search directories.

The method is not thread-safe.

Returns
The method returns list of repository search directories.

Definition at line 1550 of file kernel.hpp.

1550{return p_repository_dirs;}

◆ get_repository_mapping_dir()

const std::string & dunedaq::oks::OksKernel::get_repository_mapping_dir ( )
static

Get OKS repository name.

The repository name is defined by last directory of the TDAQ_DB_REPOSITORY environment variable, e.g.: for the name of oks-repository-root="/usr/local/databases/v10" is "v10". The method returns an empty string, if the oks-repository-root is not set or its value contains no name.

Definition at line 355 of file kernel.cpp.

356{
357 static std::once_flag flag;
358
359 std::call_once(flag, []()
360 {
361 if (const char * s = getenv("OKS_REPOSITORY_MAPPING_DIR"))
362 {
365 }
366 }
367 );
368
370}
static std::string p_repository_mapping_dir
Definition kernel.hpp:2036

◆ get_repository_root()

const std::string & dunedaq::oks::OksKernel::get_repository_root ( )
static

Get OKS repository root.

The repository root is defined by the TDAQ_DB_REPOSITORY environment variable. The method returns an empty string, if the variable is not set or its value is empty.

Definition at line 309 of file kernel.cpp.

310{
311 static std::once_flag flag;
312
313 std::call_once(flag, []()
314 {
315 if (const char * s = getenv("TDAQ_DB_REPOSITORY"))
316 {
317 std::string rep(s);
318
319 if (!std::all_of(rep.begin(), rep.end(), [](char c) { return std::isspace(c); }))
320 {
321 const char * p = getenv("OKS_GIT_PROTOCOL");
322
323 if (p && !*p)
324 p = nullptr;
325
326 Oks::Tokenizer t(rep, "|");
327 std::string token;
328
329 while (t.next(token) && p_repository_root.empty())
330 {
331 if (p)
332 {
333 if (token.find(p) == 0)
334 {
335 p_repository_root = token;
336 }
337 }
338 else
339 {
340 p_repository_root = token;
341 }
342 }
343
344 if (p_repository_root.empty())
345 Oks::error_msg("OksKernel::OksKernel") << "cannot find OKS_GIT_PROTOCOL=\"" << p << "\" in TDAQ_DB_REPOSITORY=\"" << rep << '\"' << std::endl;
346 }
347 }
348 }
349 );
350
351 return p_repository_root;
352}
static std::string p_repository_root
Definition kernel.hpp:2035

◆ get_repository_unmerged_files()

std::list< std::string > dunedaq::oks::OksKernel::get_repository_unmerged_files ( )
inline

Special behavior of get_repository_versions_diff(), return unmerged files

Definition at line 1651 of file kernel.hpp.

1652 {
1653 return get_repository_versions_diff("", "");
1654 }

◆ get_repository_version()

const std::string & dunedaq::oks::OksKernel::get_repository_version ( )
inline

Definition at line 941 of file kernel.hpp.

942 {
944 }

◆ get_repository_versions()

std::vector< OksRepositoryVersion > dunedaq::oks::OksKernel::get_repository_versions ( bool skip_irrelevant,
const std::string & command_line )

Return repository versions.

Parameters
skip_irrelevantignore changes not affecting loaded configuration
command_lineforward command line parameter to the oks-git-log.sh
Exceptions
Throwoks::exception in case of problems.

Definition at line 5334 of file kernel.cpp.

5335{
5336 std::string cmd("oks-log.sh");
5337
5338 if (get_verbose_mode())
5339 cmd.append(" -v");
5340
5341 cmd.append(" -u ");
5342 cmd.append(get_user_repository_root());
5343
5344 cmd.append(command_line);
5345
5346 CommandOutput cmd_out("oks-log", this, cmd);
5347 cmd_out.check_command_status(system(cmd.c_str()));
5348
5349 std::string output = cmd_out.cat2str();
5350
5351 std::istringstream s(output);
5352
5353 std::string line;
5354 bool found = false;
5355
5356 while (std::getline(s, line))
5357 if (line.find("git log ") == 0)
5358 {
5359 found = true;
5360 break;
5361 }
5362
5363 if (found == false)
5364 {
5365 std::ostringstream text;
5366 text << "cannot find \"git log\" pattern in output of oks-log.sh:\n" << output;
5367 throw RepositoryOperationFailed("log", text.str());
5368 }
5369
5370 std::set<std::string> loaded_files;
5371
5372 if (skip_irrelevant)
5373 {
5374 std::size_t len = get_user_repository_root().size()+1;
5375
5376 for (const auto& x : p_schema_files)
5377 loaded_files.emplace(x.first->substr(len));
5378
5379 for (const auto& x : p_data_files)
5380 loaded_files.emplace(x.first->substr(len));
5381 }
5382
5383 std::vector<OksRepositoryVersion> vec;
5384 OksRepositoryVersion ver;
5385
5386 found = false;
5387
5388 while (std::getline(s, line))
5389 {
5390 if (found == false)
5391 {
5392 ver.clear();
5393
5394 std::string::size_type idx1 = 0;
5395 std::string::size_type idx2 = line.find('|');
5396
5397 if (idx2 != std::string::npos)
5398 {
5399 ver.m_commit_hash = line.substr(idx1, idx2);
5400 idx1 = idx2+1;
5401 idx2 = line.find('|', idx1);
5402
5403 if (idx2 != std::string::npos)
5404 {
5405 ver.m_user = line.substr(idx1, idx2-idx1);
5406 idx1 = idx2+1;
5407 idx2 = line.find('|', idx1);
5408
5409 if (idx2 != std::string::npos)
5410 {
5411 ver.m_date = std::stol(line.substr(idx1, idx2-idx1));
5412 ver.m_comment = line.substr(idx2+1);
5413 }
5414 }
5415 }
5416
5417
5418 if (!ver.m_comment.empty())
5419 found = true;
5420 else
5421 {
5422 std::ostringstream text;
5423 text << "unexpected line \"" << line << "\" in output of oks-log.sh:\n" << output;
5424 throw RepositoryOperationFailed("log", text.str());
5425 }
5426 }
5427 else
5428 {
5429 if (line.empty())
5430 {
5431 found = false;
5432
5433 if (skip_irrelevant && check_relevant(loaded_files, ver) == false)
5434 continue;
5435
5436 vec.emplace_back(ver);
5437 }
5438 else
5439 {
5440 ver.m_files.push_back(line);
5441 }
5442 }
5443 }
5444
5445 if (found)
5446 {
5447 if (skip_irrelevant == false || check_relevant(loaded_files, ver))
5448 vec.emplace_back(ver);
5449 }
5450
5451 return vec;
5452}
static bool check_relevant(const std::set< std::string > &loaded_files, const OksRepositoryVersion &ver)
Definition kernel.cpp:5324

◆ get_repository_versions_by_date()

std::vector< OksRepositoryVersion > dunedaq::oks::OksKernel::get_repository_versions_by_date ( bool skip_irrelevant = true,
const std::string & since = "",
const std::string & until = "" )

Return repository versions between timestamps.

Parameters
skip_irrelevantignore changes not affecting loaded configuration
sincelimit the versions committed on-or-after the specified date/time
untillimit the versions committed on-or-before the specified date/time
Exceptions
Throwoks::exception in case of problems.

Definition at line 5491 of file kernel.cpp.

5492{
5493 std::string command_line;
5494
5495 if(!since.empty())
5496 {
5497 command_line.append(" --since ");
5498 command_line.append(replace_datetime_spaces(since));
5499 }
5500
5501 if(!until.empty())
5502 {
5503 command_line.append(" --until ");
5504 command_line.append(replace_datetime_spaces(until));
5505 }
5506
5507 command_line.append(" origin/master");
5508
5509 return get_repository_versions(skip_irrelevant, command_line);
5510}
std::vector< OksRepositoryVersion > get_repository_versions(bool skip_irrelevant, const std::string &command_line)
Return repository versions.
Definition kernel.cpp:5334
static std::string replace_datetime_spaces(const std::string &in)
Definition kernel.cpp:5482

◆ get_repository_versions_by_hash()

std::vector< OksRepositoryVersion > dunedaq::oks::OksKernel::get_repository_versions_by_hash ( bool skip_irrelevant = true,
const std::string & sha1 = "",
const std::string & sha2 = "" )

Return repository versions between hash keys.

Parameters
skip_irrelevantignore changes not affecting loaded configuration
sha1limit the versions committed on-or-after the specified hash key; if empty, start from earliest available
sha2limit the versions committed on-or-before the specified hash key; if empty, retrieve all versions until "origin/master"
Exceptions
Throwoks::exception in case of problems.

Definition at line 5455 of file kernel.cpp.

5456{
5457 std::string command_line;
5458
5459 if(!since.empty() && !until.empty())
5460 {
5461 command_line.push_back(' ');
5462 command_line.append(since);
5463 command_line.append("..");
5464 command_line.append(until);
5465 }
5466 else if(!since.empty())
5467 {
5468 command_line.push_back(' ');
5469 command_line.append(since);
5470 command_line.append("..origin/master");
5471 }
5472 else if(!until.empty())
5473 {
5474 command_line.append(" ..");
5475 command_line.append(until);
5476 }
5477
5478 return get_repository_versions(skip_irrelevant, command_line);
5479}

◆ get_repository_versions_diff()

std::list< std::string > dunedaq::oks::OksKernel::get_repository_versions_diff ( const std::string & sha1,
const std::string & sha2 )

Return names of files updated between revisions.

Exceptions
Throwoks::exception in case of problems.

Definition at line 5254 of file kernel.cpp.

5255{
5256 std::unique_lock lock(p_kernel_mutex);
5257
5258 if (OksKernel::get_repository_root().empty())
5259 throw RepositoryOperationFailed("diff", "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5260
5261 if (get_user_repository_root().empty())
5262 throw RepositoryOperationFailed("diff", "the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5263
5264 std::string cmd("oks-diff.sh");
5265
5266 if (get_verbose_mode())
5267 cmd.append(" -v");
5268
5269 cmd.append(" -u ");
5270 cmd.append(get_user_repository_root());
5271
5272 if(!sha1.empty() && !sha2.empty())
5273 {
5274 cmd.append(" --sha ");
5275 cmd.append(sha1);
5276 cmd.push_back(' ');
5277 cmd.append(sha2);
5278 }
5279 else
5280 {
5281 cmd.append(" --unmerged");
5282 }
5283
5284 CommandOutput cmd_out("oks-diff", this, cmd);
5285 cmd_out.check_command_status(system(cmd.c_str()));
5286
5287 std::string output = cmd_out.cat2str();
5288
5289 if(!p_silence) {
5290 std::lock_guard lock(p_parallel_out_mutex);
5291 std::cout << output << "[OKS get_diff] => done" << std::endl;
5292 }
5293
5294 std::istringstream s(output);
5295
5296 std::string line;
5297 bool found = false;
5298
5299 const char * diff_pattern = "git diff --name-only ";
5300
5301 while (std::getline(s, line))
5302 if (line.find(diff_pattern) == 0)
5303 {
5304 found = true;
5305 break;
5306 }
5307
5308 if (found == false)
5309 {
5310 std::ostringstream text;
5311 text << "cannot find \"" << diff_pattern << "\" pattern in output of oks-diff.sh:\n" << output;
5312 throw RepositoryOperationFailed("get_diff", text.str());
5313 }
5314
5315 std::list<std::string> result;
5316
5317 while (std::getline(s, line))
5318 result.push_back(line);
5319
5320 return result;
5321}

◆ get_silence_mode()

bool dunedaq::oks::OksKernel::get_silence_mode ( ) const
inline

Get status of silence mode. The method returns true, if the silence mode is switched 'On'. In such case the OKS will not print any info, warnings and error messages.

Definition at line 691 of file kernel.hpp.

691{return p_silence;}

◆ get_skip_string_range()

bool dunedaq::oks::OksKernel::get_skip_string_range ( )
inlinestatic

Get status of string range validator.

The method returns true, if the check is switched 'Off'. If the check is switched 'On', OKS will validate string value using regexp regular expression, if it is defined for related attribute.

Definition at line 804 of file kernel.hpp.

804{return p_skip_string_range;}

◆ get_test_duplicated_objects_via_inheritance_mode()

bool dunedaq::oks::OksKernel::get_test_duplicated_objects_via_inheritance_mode ( ) const
inline

Get status of test inherited duplicated objects mode. The method returns true, if the mode is switched 'On'. In such case the OKS will throw exception when there are objects with equal IDs within class inheritance hierarchy.

Definition at line 770 of file kernel.hpp.

◆ get_tmp_file()

std::string dunedaq::oks::OksKernel::get_tmp_file ( const std::string & file_name)
static

Generates temporal file name.

Method generates temporal file name by adding numeric suffix to the file_name and testing the file existence.

Returns
Return name of temporal file.

The method is not thread-safe.

Definition at line 670 of file kernel.cpp.

671{
672 unsigned int j = 0;
673 std::string s2;
674 std::ostringstream s;
675
676 while(j++ < 1000000) {
677 s.str("");
678 s << file << '.' << get_user_name() << ':' << get_host_name() << ':' << getpid() << ':' << j;
679
680 s2 = s.str();
681
682 std::ofstream f(s2.c_str(), std::ios::in);
683
684 if(!f) return s2;
685 }
686
687 std::string s3(file);
688 s3 += ".tmp";
689
690 return s3;
691}

◆ get_updated_repository_files()

void dunedaq::oks::OksKernel::get_updated_repository_files ( std::set< std::string > & updated,
std::set< std::string > & added,
std::set< std::string > & removed )

Get repository modified schema files.

The method returns those schema files which corresponding repository files were modified or removed by an external process. The method checks file system status of all OKS schema files loaded and created by the OKS kernel. The file is considered to be updated if it was modified after it was last time saved by the OKS kernel, or modified after it was loaded or created.

The method return parameters are:

Parameters
updatedpointer to the list of modified schema files
removedpointer to the list of removed schema files

The user is responsible to delete returned pointers after usage.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Definition at line 5551 of file kernel.cpp.

5552{
5553 std::unique_lock lock(p_kernel_mutex);
5554
5555 if (OksKernel::get_repository_root().empty())
5556 throw RepositoryOperationFailed("status", "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5557
5558 if (get_user_repository_root().empty())
5559 throw RepositoryOperationFailed("status", "the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5560
5561 std::string cmd("oks-status.sh");
5562
5563 cmd.append(" -u ");
5564 cmd.append(get_user_repository_root());
5565
5566 CommandOutput cmd_out("oks-status", this, cmd);
5567 cmd_out.check_command_status(system(cmd.c_str()));
5568
5569 std::string output = cmd_out.cat2str();
5570
5571 if(p_verbose) {
5572 std::lock_guard lock(p_parallel_out_mutex);
5573 std::cout << output << "[OKS get_status] => done" << std::endl;
5574 }
5575
5576 std::istringstream s(output);
5577
5578 std::string line;
5579 bool found = false;
5580
5581 const char * diff_pattern = "git status --porcelain";
5582
5583 while (std::getline(s, line))
5584 if (line.find(diff_pattern) == 0)
5585 {
5586 found = true;
5587 break;
5588 }
5589
5590 if (found == false)
5591 {
5592 std::ostringstream text;
5593 text << "cannot find \"" << diff_pattern << "\" pattern in output of oks-status.sh:\n" << output;
5594 throw RepositoryOperationFailed("status", text.str());
5595 }
5596
5597 std::list<std::string> result;
5598
5599 while (std::getline(s, line))
5600 {
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));
5607 else
5608 {
5609 std::ostringstream text;
5610 text << "unexpected output \"" << line << "\" in output of oks-status.sh:\n" << output;
5611 throw RepositoryOperationFailed("status", text.str());
5612 }
5613 }
5614}

◆ get_user_name()

std::string & dunedaq::oks::OksKernel::get_user_name ( )
static

Get username of given process.

Definition at line 473 of file kernel.cpp.

474{
475 static std::string s_user_name;
476 static std::once_flag flag;
477
478 std::call_once(flag, []()
479 {
480 OksSystem::User myself;
481 s_user_name = myself.name_safe();
482
483 if (s_user_name.empty())
484 s_user_name = "unknown.user";
485 }
486 );
487
488 return s_user_name;
489}
const std::string & name_safe() const
username - no exception
Definition User.cpp:209

◆ get_user_repository_root()

const std::string & dunedaq::oks::OksKernel::get_user_repository_root ( ) const

Get user OKS repository root.

The user repository root is defined by the TDAQ_DB_USER_REPOSITORY environment variable. The method returns an empty string, if the variable is not set or its value is empty.

Definition at line 375 of file kernel.cpp.

376{
378 {
379 OksKernel * k(const_cast<OksKernel*>(this));
381 if(const char * s = getenv("TDAQ_DB_USER_REPOSITORY")) {
382 if(s[0] != 0) {
383 k->set_user_repository_root(s);
384 }
385 }
386 k->p_user_repository_root_inited = true;
387 }
388 }
389
391}
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.
Definition kernel.cpp:738

◆ get_verbose_mode()

bool dunedaq::oks::OksKernel::get_verbose_mode ( ) const
inline

Get status of verbose mode. The method returns true, if the verbose mode is switched 'On'.

Definition at line 670 of file kernel.hpp.

670{return p_verbose;}

◆ GetOksProfiler()

OksProfiler * dunedaq::oks::OksKernel::GetOksProfiler ( ) const
inline

Definition at line 619 of file kernel.hpp.

619{return profiler;}

◆ GetVersion()

const char * dunedaq::oks::OksKernel::GetVersion ( )
static

Get OKS version. The method returns string containing CVS tag and date of OKS build.

Definition at line 302 of file kernel.cpp.

303{
304 return "862f2957270";
305}

◆ insert_repository_dir()

std::string dunedaq::oks::OksKernel::insert_repository_dir ( const std::string & dir,
bool push_back = true )

Insert repository search directory.

The method trues to insert new repository search directory. If no such directory exists, then the method inserts new directory and returns its fully qualified name. Otherwise method does nothing and return empty string.

The method is not thread-safe.

Parameters
dirdirectory name
push_backif true, push new directory back; otherwise push directory front

Definition at line 1403 of file kernel.cpp.

1404{
1405 std::unique_lock lock(p_kernel_mutex);
1406
1407 std::string s(dir);
1409
1410 try {
1411 Oks::real_path(s, false);
1412
1413 if(std::find(p_repository_dirs.begin(), p_repository_dirs.end(), s) == p_repository_dirs.end()) {
1414 if(push_back) p_repository_dirs.push_back(s); else p_repository_dirs.push_front(s);
1415 if(p_verbose) {
1416 std::cout << " * push " << (push_back ? "back" : "front") << " repository search directory \'" << s << "\'\n";
1417 }
1418 return s;
1419 }
1420 }
1421 catch(exception& ex) {
1422 TLOG_DEBUG( 1) << "Cannot insert repository dir \'" << dir << "\':\n\tcaused by: " << ex ;
1423 }
1424
1425 return "";
1426}

◆ is_dangling() [1/2]

bool dunedaq::oks::OksKernel::is_dangling ( OksClass * class_ptr) const

Check pointer on oks class.

A pointer on class becomes dangling if such class was destroyed, or the schema file which contains it was closed. The method scans through all oks classes and checks if given pointer is valid, i.e. points to an oks class.

If the method is used in the multi-threaded environment, it may be necessary to set read kernel lock before calling the method, in case if another threads can to create or to destroy classes or to open or to close oks schema files.

Parameters
class_ptra pointer to the oks class to be tested
Returns
Return true if the pointer on class is not valid.

Definition at line 4643 of file kernel.cpp.

4644{
4646 OSK_VERBOSE_REPORT("Enter OksKernel::is_dangling(OksClass *)")
4647
4648 bool not_found = true;
4649
4650 {
4651 if(!p_classes.empty()) {
4652 for(OksClass::Map::const_iterator i = p_classes.begin(); i != p_classes.end(); ++i) {
4653 if(i->second == c) {
4654 not_found = false;
4655 break;
4656 }
4657 }
4658 }
4659 }
4660
4661 if(p_verbose) {
4662 std::string fname("OksKernel::is_dangling(");
4663
4664 if(not_found)
4665 fname += "?class?) returns true";
4666 else {
4667 fname += '\"';
4668 fname += c->get_name();
4669 fname += "\") returns false";
4670 }
4671
4672 OSK_VERBOSE_REPORT("LEAVE " << fname.c_str())
4673 }
4674
4675 return not_found;
4676}

◆ is_dangling() [2/2]

bool dunedaq::oks::OksKernel::is_dangling ( OksObject * obj_ptr) const

Check pointer on oks object.

A pointer on object becomes dangling if such object was destroyed, or the data file which contains it was closed. The method scans through all oks objects and checks if given pointer is valid, i.e. points to an oks object.

If the method is used in the multi-threaded environment, it may be necessary to set read kernel lock before calling the method, in case if another threads can to create or to destroy objects or to open or to close oks data files.

Parameters
obj_ptra pointer to the oks object to be tested
Returns
Return true if the pointer on object is not valid.

Definition at line 4612 of file kernel.cpp.

4613{
4615 OSK_VERBOSE_REPORT("Enter OksKernel::is_dangling(OksObject *)")
4616
4617 bool not_found;
4618
4619 {
4620 std::lock_guard lock(p_objects_mutex);
4621 not_found = (p_objects.find(o) == p_objects.end());
4622 }
4623
4624 if(p_verbose) {
4625 std::string fname("OksKernel::is_dangling(");
4626
4627 if(not_found)
4628 fname += "?object?) returns true";
4629 else {
4630 fname += '\"';
4631 fname += o->GetId();
4632 fname += "\") returns false";
4633 }
4634
4635 OSK_VERBOSE_REPORT("LEAVE " << fname.c_str())
4636 }
4637
4638 return not_found;
4639}

◆ is_user_repository_created()

bool dunedaq::oks::OksKernel::is_user_repository_created ( ) const
inline

Definition at line 947 of file kernel.hpp.

948 {
950 }

◆ k_add()

void dunedaq::oks::OksKernel::k_add ( OksClass * c)
private

Definition at line 4464 of file kernel.cpp.

4465{
4466 TLOG_DEBUG(4) << "enter for class \"" << c->get_name() << '\"';
4467
4468 if(p_active_schema == 0) {
4469 throw CannotAddClass(*c, "no active schema");
4470 }
4471
4472 if(p_classes.find(c->get_name().c_str()) != p_classes.end()) {
4473 throw CannotAddClass(*c, "class already exists");
4474 }
4475
4476 c->p_kernel = this;
4477 c->p_file = p_active_schema;
4478 c->p_file->p_is_updated = true;
4479
4480 p_classes[c->get_name().c_str()] = c;
4481
4482 try {
4484 }
4485 catch(exception& ex) {
4486 throw CannotAddClass(*c, ex);
4487 }
4488
4489 if(OksClass::create_notify_fn) (*OksClass::create_notify_fn)(c);
4490}
void registrate_all_classes(bool skip_registered=false)
The method rebuilds all classes taking into account inheritance.
Definition kernel.cpp:4504

◆ k_bind_objects()

void dunedaq::oks::OksKernel::k_bind_objects ( )
private

Definition at line 4373 of file kernel.cpp.

4374{
4375 TLOG_DEBUG(4) << "enter";
4376
4377 p_bind_objects_status.clear();
4378
4379 if(!p_objects.empty()) {
4380 for(OksObject::Set::iterator i = p_objects.begin(); i != p_objects.end(); ++i) {
4381 try {
4382 (*i)->bind_objects();
4383 }
4384 catch(ObjectBindError& ex) {
4385 if(ex.p_is_error) {
4386 throw;
4387 }
4388 else {
4389 const std::string error_text(strchr(ex.what(), '\n')+1);
4390 if(!p_bind_objects_status.empty()) p_bind_objects_status.push_back('\n');
4391 p_bind_objects_status.append(error_text);
4392
4393 TLOG_DEBUG(1) << error_text;
4394 }
4395 }
4396 }
4397 }
4398
4399 if(!p_silence && !p_bind_objects_status.empty()) {
4400 ers::warning(kernel::BindError(ERS_HERE, p_bind_objects_status));
4401 }
4402
4403 TLOG_DEBUG(4) << "exit with status:\n" << p_bind_objects_status;
4404}
void warning(const Issue &issue)
Definition ers.hpp:126

◆ k_check_bind_classes_status()

void dunedaq::oks::OksKernel::k_check_bind_classes_status ( ) const
privatenoexcept

Definition at line 5715 of file kernel.cpp.

5716{
5717 std::ostringstream out;
5718
5719 for (auto & c : p_classes)
5720 c.second->check_relationships(out, true);
5721
5722 p_bind_classes_status = out.str();
5723}
FELIX Initialization std::string initerror FELIX queue timed out

◆ k_checkout_repository()

void dunedaq::oks::OksKernel::k_checkout_repository ( const std::string & param,
const std::string & val,
const std::string & branch )
private

Check out repository files into local user directory.

The method checks out GIT repository files into local user directory. The files have to be loaded from repository defined by TDAQ_DB_REPOSITORY environment. The TDAQ_DB_USER_REPOSITORY environment defines user directory and must be set.

Parameters
paramforward parameter to oks-git-checkout.sh
valforward value of above parameter to oks-git-checkout.sh
branchname of the branch to check out
Exceptions
Throwoks::exception in case of problems.

Definition at line 4885 of file kernel.cpp.

4886{
4887 if (get_repository_root().empty())
4888 throw RepositoryOperationFailed("checkout", "the repository root is not set");
4889
4890 ReposDirs reps("checkout", s_cwd, this);
4891
4892 std::string cmd("oks-checkout.sh");
4893
4894 if(get_verbose_mode()) { cmd += " -v"; }
4895
4896 cmd.append(" -u ");
4897 cmd.append(get_user_repository_root());
4898
4899 if (!param.empty())
4900 {
4901 cmd.append(" --");
4902 cmd.append(param);
4903 cmd.push_back(' ');
4904 cmd.push_back('\"');
4905 cmd.append(val);
4906 cmd.push_back('\"');
4907 }
4908
4909 if (!branch_name.empty())
4910 {
4911 cmd.append(" -b ");
4912 cmd.append(branch_name);
4913 }
4914
4915 auto start_usage = std::chrono::steady_clock::now();
4916
4917 if (!p_silence)
4918 {
4919 std::lock_guard lock(p_parallel_out_mutex);
4920 log_timestamp() << "[OKS checkout] => " << cmd << std::endl;
4921 }
4922
4923 CommandOutput cmd_out("oks-checkout", this, cmd);
4924 cmd_out.check_command_status(system(cmd.c_str()));
4925
4927
4928 if(!p_silence)
4929 {
4930 std::lock_guard lock(p_parallel_out_mutex);
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;
4933 }
4934
4935 static std::string version_prefix("checkout oks version ");
4936 std::string version = cmd_out.last_str();
4937 std::string::size_type pos = version.find(version_prefix);
4938
4939 if (pos == 0)
4940 p_repository_version = version.substr(version_prefix.size());
4941 else
4942 throw RepositoryOperationFailed("checkout", "cannot read oks version");
4943}

◆ k_close_dangling_includes()

void dunedaq::oks::OksKernel::k_close_dangling_includes ( )

Close files which lost their parent.

When a file is closed or an include is removed, some files may lost their parent and needs to be closed.

The method is not thread-safe.

Definition at line 1966 of file kernel.cpp.

1967{
1968 // build inclusion graph
1969
1970 OksFile::IMap igraph;
1971
1972 for(OksFile::Map::iterator i = p_schema_files.begin(); i != p_schema_files.end(); ++i) {
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) {
1974 std::string f = get_file_path(*x, i->second);
1975 OksFile::Map::const_iterator it = p_schema_files.find(&f);
1976 if(it != p_schema_files.end()) {
1977 igraph[i->second].insert(it->second);
1978 }
1979 else {
1980 std::cerr << "cannot find schema " << *x << " included by " << i->second->get_full_file_name() << std::endl;
1981 }
1982 }
1983 }
1984
1985 for(OksFile::Map::iterator i = p_data_files.begin(); i != p_data_files.end(); ++i) {
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) {
1987 std::string f = get_file_path(*x, i->second);
1988 OksFile::Map::const_iterator it = p_data_files.find(&f);
1989 if(it != p_data_files.end()) {
1990 igraph[i->second].insert(it->second);
1991 }
1992 else {
1993 it = p_schema_files.find(&f);
1994
1995 if(it != p_schema_files.end()) {
1996 igraph[i->second].insert(it->second);
1997 }
1998 else {
1999 std::cerr << "cannot find file " << *x << " included by " << i->second->get_full_file_name() << std::endl;
2000 }
2001 }
2002 }
2003 }
2004
2005
2006 const size_t num_of_schema_files(schema_files().size());
2007
2008
2009 // calculate files to be closed
2010
2011 while(true) {
2012 std::list<OksFile *> schema_files, data_files; // files to be closed
2013
2014 OksFile::Map * files[2] = {&p_schema_files, &p_data_files};
2015 std::list<OksFile *> to_be_closed[2];
2016
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;
2021
2022 // check, the parent is valid
2023
2024 if(igraph.find(p) != igraph.end()) {
2025 OksFile::IMap::iterator j = igraph.find(p);
2026 if(test_parent(i->second, j)) {
2027 continue;
2028 }
2029 }
2030
2031 TLOG_DEBUG( 1 ) << "the parent of file " << i->second->get_full_file_name() << " is not valid" ;
2032
2033
2034 // try to find new parent
2035
2036 for(OksFile::IMap::iterator j = igraph.begin(); j != igraph.end(); ++j) {
2037 if(test_parent(i->second, j)) {
2038 found_parent = true;
2039 break;
2040 }
2041 }
2042
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);
2046 }
2047 }
2048 }
2049 }
2050
2051 int num = 0;
2052
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();
2055 k_close_data(*i, true);
2056 igraph.erase(*i);
2057 }
2058
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();
2061 k_close_schema(*i);
2062 igraph.erase(*i);
2063 }
2064
2065 if(num > 0) {
2066 TLOG_DEBUG( 1 ) << "go into recursive call, number of potentially closed includes is " << num ;
2067 }
2068 else {
2069 TLOG_DEBUG( 1 ) << "break loop";
2070 break;
2071 }
2072 }
2073
2074 if(num_of_schema_files != schema_files().size()) {
2075 TLOG_DEBUG( 1 ) << "rebuild classes since number of schema files has been changed from " << num_of_schema_files << " to " << schema_files().size() ;
2077 }
2078}
std::unordered_map< OksFile *, Set, oks::hash_file_ptr, oks::equal_file_ptr > IMap
Definition file.hpp:375
const OksFile::Map & data_files() const
Get all data files.
Definition kernel.hpp:1498
bool test_parent(OksFile *file, OksFile::IMap::iterator &i)
Definition kernel.cpp:1948
const OksFile::Map & schema_files() const
Get all schema files.
Definition kernel.hpp:1228

◆ k_close_data()

void dunedaq::oks::OksKernel::k_close_data ( OksFile * fp,
bool unbind )
private

Definition at line 4197 of file kernel.cpp.

4198{
4199 const char _fname[] = "k_close_data";
4200 std::string fname = make_fname(_fname, sizeof(_fname)-1, fp->p_full_name, &unbind, nullptr);
4201
4203 OSK_VERBOSE_REPORT("ENTER " << fname)
4204
4205 try {
4206 fp->unlock();
4207 }
4208 catch(exception& ex) {
4209 Oks::error_msg(fname) << ex.what() << std::endl;
4210 }
4211
4212 if(!p_silence) {
4213 std::lock_guard lock(p_parallel_out_mutex);
4214 std::cout << (fp->p_included_by ? " * c" : "C") << "lose OKS data \"" << fp->p_full_name << "\"..." << std::endl;
4215 }
4216
4217 if(unbind) {
4218 for(OksObject::Set::const_iterator i = p_objects.begin(); i != p_objects.end(); ++i) {
4219 OksObject *o = *i;
4220 if(o->file != fp) o->unbind_file(fp);
4221 }
4222 }
4223
4224 if(p_close_all == false) {
4225 std::list<OksObject *> * olist = create_list_of_data_objects(fp);
4226
4227 if(olist) {
4228 while(!olist->empty()) {
4229 OksObject *o = olist->front();
4230 olist->pop_front();
4231 if(!is_dangling(o)) delete o;
4232 }
4233
4234 delete olist;
4235 }
4236 }
4237
4238 remove_data_file(fp);
4239 delete fp;
4240
4241 if(p_active_data == fp) p_active_data = 0;
4242
4243 OSK_VERBOSE_REPORT("LEAVE " << fname)
4244}
bool is_dangling(OksClass *class_ptr) const
Check pointer on oks class.
Definition kernel.cpp:4643
std::list< OksObject * > * create_list_of_data_objects(OksFile *) const
Creates list of objects which belong to given file.
Definition kernel.cpp:4332
void remove_data_file(OksFile *)
Definition kernel.cpp:3784

◆ k_close_schema()

void dunedaq::oks::OksKernel::k_close_schema ( OksFile * pf)
private

Definition at line 2834 of file kernel.cpp.

2835{
2837
2838 if(!pf) {
2839 TLOG_DEBUG(1) << "enter for file (null)";
2840 return;
2841 }
2842 else {
2843 TLOG_DEBUG(2) << "enter for file " << pf->p_full_name;
2844 }
2845
2846 if(p_active_schema == pf) p_active_schema = 0;
2847
2848 try {
2849 pf->unlock();
2850 }
2851 catch(exception& ex) {
2852 Oks::error_msg("OksKernel::k_close_schema()") << ex.what() << std::endl;
2853 }
2854
2855 if(!p_silence)
2856 std::cout << (pf->p_included_by ? " * c" : "C") << "lose OKS schema \"" << pf->p_full_name << "\"..." << std::endl;
2857
2858 if(!p_classes.empty()) {
2859
2860 //
2861 // The fastest way to delete classes is delete
2862 // them in order of superclasses descreasing
2863 // because this reduces amount of work to restructure
2864 // child classes when their parent was deleted and
2865 // there will be no dangling classes
2866 //
2867
2868 std::set<OksClass *> sorted;
2869
2870 for(OksClass::Map::iterator i = p_classes.begin(); i != p_classes.end(); ++i) {
2871 OksClass *c = i->second;
2872 if(pf == c->p_file) sorted.insert(c);
2873 c->p_to_be_deleted = true;
2874 }
2875
2876 for(std::set<OksClass *>::iterator j = sorted.begin(); j != sorted.end(); ++j) {
2877 delete *j;
2878 }
2879 }
2880
2882 delete pf;
2883
2884 TLOG_DEBUG(4) << "exit for file " << (void *)pf;
2885}
void remove_schema_file(OksFile *)
Definition kernel.cpp:3790

◆ k_copy_repository()

void dunedaq::oks::OksKernel::k_copy_repository ( const std::string & source,
const std::string & destination )
private

Definition at line 4964 of file kernel.cpp.

4965{
4966 std::string cmd("oks-copy.sh");
4967
4968 if (get_verbose_mode())
4969 cmd.append(" -v");
4970
4971 cmd.append(" -s ");
4972 cmd.append(source);
4973
4974 cmd.append(" -d ");
4975 cmd.append(destination);
4976
4977 cmd.append(" -c ");
4978 cmd.append(get_repository_version());
4979
4980 auto start_usage = std::chrono::steady_clock::now();
4981
4982 if(!p_silence) {
4983 std::lock_guard lock(p_parallel_out_mutex);
4984 log_timestamp() << "[OKS copy] => " << cmd << std::endl;
4985 }
4986
4987 CommandOutput cmd_out("oks-copy", this, cmd);
4988 cmd_out.check_command_status(system(cmd.c_str()));
4989
4990 if(!p_silence) {
4991 std::lock_guard lock(p_parallel_out_mutex);
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;
4994 }
4995}

◆ k_load_data() [1/2]

OksFile * dunedaq::oks::OksKernel::k_load_data ( const std::string & short_file_name,
bool bind,
const OksFile * parent_h,
OksPipeline * pipeline )
private

Definition at line 3574 of file kernel.cpp.

3575{
3576 const char _fname[] = "k_load_data";
3577 std::string fname = make_fname(_fname, sizeof(_fname)-1, short_file_name, &bind, &parent_h);
3578
3579 OSK_VERBOSE_REPORT("ENTER " << fname)
3580
3581 std::string full_file_name;
3582
3583 try {
3584 full_file_name = get_file_path(short_file_name, parent_h);
3585 }
3586 catch (std::exception & e) {
3587 throw CanNotOpenFile("k_load_data", short_file_name, e.what());
3588 }
3589
3590 try {
3591
3592 OksFile *fp = find_data_file(full_file_name);
3593
3594 if(fp != 0) {
3595 if(p_verbose) {
3596 std::lock_guard lock(p_parallel_out_mutex);
3597 Oks::warning_msg(fname) << " The file \'" << full_file_name << "\' was already loaded";
3598 }
3599 return fp->check_parent(parent_h);
3600 }
3601
3602 {
3603 std::shared_ptr<std::ifstream> f(new std::ifstream(full_file_name.c_str()));
3604
3605 if(!f->good()) {
3606 throw std::runtime_error("k_load_data(): cannot open file");
3607 }
3608
3609 long file_length(get_file_length(*f));
3610
3611 if(!file_length) {
3612 throw std::runtime_error("k_load_data(): file is empty");
3613 }
3614
3615 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(f));
3616
3617 fp = new OksFile(xmls, short_file_name, full_file_name, this);
3618
3619 if(fp->p_oks_format.empty()) {
3620 throw std::runtime_error("k_load_data(): failed to read header of file");
3621 }
3622
3623 char format;
3624
3625 if(fp->p_oks_format.size() == 4 && cmp_str4n(fp->p_oks_format.c_str(), "data"))
3626 format = 'n';
3627 else if(fp->p_oks_format.size() == 8 && cmp_str8n(fp->p_oks_format.c_str(), "extended"))
3628 format = 'X';
3629 else if(fp->p_oks_format.size() == 7 && cmp_str7n(fp->p_oks_format.c_str(), "compact"))
3630 format = 'c';
3631 else {
3632 throw std::runtime_error("k_load_data(): file is not an oks data file");
3633 }
3634
3635 k_load_data(fp, format, xmls, file_length, bind, parent_h, pipeline);
3636
3637 OSK_VERBOSE_REPORT("LEAVE " << fname)
3638
3639 return fp;
3640 }
3641 }
3642 catch (FailedLoadFile&) {
3643 throw;
3644 }
3645 catch (exception & e) {
3646 throw (FailedLoadFile("data file", full_file_name, e));
3647 }
3648 catch (std::exception & e) {
3649 throw (FailedLoadFile("data file", full_file_name, e.what()));
3650 }
3651}
OksFile * k_load_data(const std::string &, bool, const OksFile *, OksPipeline *)
Definition kernel.cpp:3574
static std::ostream & warning_msg(const char *)
Definition kernel.cpp:568
bool cmp_str8n(const char *s1, const char s2[9])
Definition cstring.hpp:70
bool cmp_str7n(const char *s1, const char s2[8])
Definition cstring.hpp:62
static long get_file_length(std::ifstream &f)
Definition kernel.cpp:495
bool cmp_str4n(const char *s1, const char s2[4])
Definition cstring.hpp:38

◆ k_load_data() [2/2]

void dunedaq::oks::OksKernel::k_load_data ( OksFile * fp,
char format,
std::shared_ptr< OksXmlInputStream > xmls,
long file_length,
bool bind,
const OksFile * parent_h,
OksPipeline * pipeline )
private

Definition at line 3655 of file kernel.cpp.

3656{
3658
3659 fp->p_included_by = parent_h;
3660 check_read_only(fp);
3661
3662 try {
3663 if(!p_silence) {
3664 std::lock_guard lock(p_parallel_out_mutex);
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";
3667 if(parent_h == 0 && fp->get_full_file_name() != fp->get_short_file_name()) {
3668 std::cout << "(non-fully-qualified filename was \"" << fp->get_short_file_name() << "\")\n";
3669 }
3670 }
3671
3672 fp->update_status_of_file();
3673 add_data_file(fp);
3674
3675 {
3676 std::unique_ptr<OksPipeline> pipeline_guard(pipeline ? 0 : new OksPipeline(p_threads_pool_size));
3677
3678 OksPipeline * m_pipeline;
3679
3680 if(pipeline) {
3681 m_pipeline = pipeline;
3682 }
3683 else {
3684 m_pipeline = pipeline_guard.get();
3685 p_load_errors.clear();
3686 }
3687
3688 k_load_includes(*fp, m_pipeline);
3689
3690
3691 if(p_threads_pool_size > 1) {
3692 m_pipeline->addJob( new OksLoadObjectsJob( this, fp, xmls, format) );
3693 }
3694 else {
3695 OksLoadObjectsJob job(this, fp, xmls, format);
3696 job.run();
3697 }
3698 }
3699
3700 if(!pipeline) {
3701 if(!p_load_errors.is_empty()) {
3702 throw (FailedLoadFile("data file", fp->get_full_file_name(), p_load_errors.get_text()));
3703 }
3704
3705 if(bind) {
3707 }
3708 }
3709 }
3710 catch (FailedLoadFile&) {
3711 throw;
3712 }
3713 catch (exception& e) {
3714 throw (FailedLoadFile("data file", fp->get_full_file_name(), e));
3715 }
3716 catch (std::exception& e) {
3717 throw (FailedLoadFile("data file", fp->get_full_file_name(), e.what()));
3718 }
3719}
friend struct OksLoadObjectsJob
Definition kernel.hpp:587
void add_data_file(OksFile *)
Definition kernel.cpp:3772
void k_load_includes(const OksFile &, OksPipeline *)
Definition kernel.cpp:1885

◆ k_load_file()

OksFile * dunedaq::oks::OksKernel::k_load_file ( const std::string & name,
bool bind,
const OksFile * parent,
OksPipeline * pipeline )
private

Definition at line 1803 of file kernel.cpp.

1804{
1805 const char _fname[] = "k_load_file";
1806 std::string fname = make_fname(_fname, sizeof(_fname)-1, short_file_name, &bind, &parent_h);
1807
1808 OSK_VERBOSE_REPORT("ENTER " << fname)
1809
1810 std::string full_file_name;
1811
1812 try {
1813 full_file_name = get_file_path(short_file_name, parent_h);
1814 }
1815 catch (std::exception & e) {
1816 throw CanNotOpenFile("k_load_file", short_file_name, e.what());
1817 }
1818
1819 try {
1820
1821 // check if the file is already loaded
1822
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);
1825
1826 i = p_data_files.find(&full_file_name);
1827 if(i != p_data_files.end()) return i->second->check_parent(parent_h);
1828
1829 std::shared_ptr<std::ifstream> f(new std::ifstream(full_file_name.c_str()));
1830
1831 if(f->good()) {
1832 long file_length(get_file_length(*f));
1833
1834 if(!file_length) {
1835 throw std::runtime_error("k_load_file(): file is empty");
1836 }
1837
1838 // read file header and decide what to load
1839
1840 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(f));
1841
1842 OksFile * file_h = new OksFile(xmls, short_file_name, full_file_name, this);
1843
1844 if(file_h->p_oks_format.size() == 6 && cmp_str6n(file_h->p_oks_format.c_str(), "schema")) {
1845 k_load_schema(file_h, xmls, parent_h);
1846 }
1847 else {
1848 char format;
1849
1850 if(file_h->p_oks_format.size() == 4 && cmp_str4n(file_h->p_oks_format.c_str(), "data"))
1851 format = 'n';
1852 else if(file_h->p_oks_format.size() == 8 && cmp_str8n(file_h->p_oks_format.c_str(), "extended"))
1853 format = 'X';
1854 else if(file_h->p_oks_format.size() == 7 && cmp_str7n(file_h->p_oks_format.c_str(), "compact"))
1855 format = 'c';
1856 else {
1857 delete file_h;
1858 throw std::runtime_error("k_load_file(): failed to parse header");
1859 }
1860
1861 k_load_data(file_h, format, xmls, file_length, bind, parent_h, pipeline);
1862 }
1863
1864 OSK_VERBOSE_REPORT("LEAVE " << fname)
1865
1866 return file_h;
1867 }
1868 else {
1869 throw std::runtime_error("k_load_file(): cannot open file");
1870 }
1871 }
1872 catch (exception & e) {
1873 throw FailedLoadFile("file", full_file_name, e);
1874 }
1875 catch (std::exception & e) {
1876 throw FailedLoadFile("file", full_file_name, e.what());
1877 }
1878 catch (...) {
1879 throw FailedLoadFile("file", full_file_name, "caught unknown exception");
1880 }
1881}
OksFile * k_load_schema(const std::string &, const OksFile *)
Definition kernel.cpp:2311
bool cmp_str6n(const char *s1, const char s2[6])
Definition cstring.hpp:54

◆ k_load_includes()

void dunedaq::oks::OksKernel::k_load_includes ( const OksFile & f,
OksPipeline * pipeline )
private

Definition at line 1885 of file kernel.cpp.

1886{
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) {
1888 if(!(*i).empty()) {
1889 //if(f.get_repository() != OksFile::NoneRepository) {
1890 if(!get_user_repository_root().empty()) {
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\")");
1893 }
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\")");
1896 }
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\")");
1899 }
1900 }
1901
1902 try {
1903 k_load_file(*i, false, &f, pipeline);
1904 }
1905 catch (exception & e) {
1906 throw FailedLoadFile("include", *i, e);
1907 }
1908 catch (std::exception & e) {
1909 throw FailedLoadFile("include", *i, e.what());
1910 }
1911 }
1912 else {
1913 throw FailedLoadFile("include", *i, "empty filename");
1914 }
1915 }
1916}
OksFile * k_load_file(const std::string &name, bool bind, const OksFile *parent, OksPipeline *pipeline)
Definition kernel.cpp:1803

◆ k_load_schema() [1/2]

OksFile * dunedaq::oks::OksKernel::k_load_schema ( const std::string & short_file_name,
const OksFile * parent_h )
private

Definition at line 2311 of file kernel.cpp.

2312{
2313 const char _fname[] = "k_load_schema";
2314 std::string fname = make_fname(_fname, sizeof(_fname)-1, short_file_name, nullptr, &parent_h);
2315
2316 OSK_VERBOSE_REPORT("ENTER " << fname)
2317
2318 std::string full_file_name;
2319
2320 try {
2321 full_file_name = get_file_path(short_file_name, parent_h);
2322 }
2323 catch (std::exception & e) {
2324 throw CanNotOpenFile("k_load_schema", short_file_name, e.what());
2325 }
2326
2327 try {
2328 OksFile * fp = find_schema_file(full_file_name);
2329
2330 if(fp != 0) {
2331 if(p_verbose) {
2332 std::lock_guard lock(p_parallel_out_mutex);
2333 Oks::warning_msg(fname) << " The file was already loaded\n";
2334 }
2335 return fp->check_parent(parent_h);
2336 }
2337
2338 {
2339 std::shared_ptr<std::ifstream> f(new std::ifstream(full_file_name.c_str()));
2340
2341 if(!f->good()) {
2342 throw std::runtime_error("k_load_schema(): cannot open file");
2343 }
2344
2345 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(f));
2346
2347 fp = new OksFile(xmls, short_file_name, full_file_name, this);
2348
2349 if(fp->p_oks_format.empty()) {
2350 throw std::runtime_error("k_load_schema(): failed to read header of file");
2351 }
2352 else if(fp->p_oks_format != "schema") {
2353 throw std::runtime_error("k_load_schema(): file is not oks schema file");
2354 }
2355
2356 k_load_schema(fp, xmls, parent_h);
2357
2358 OSK_VERBOSE_REPORT("LEAVE " << fname)
2359
2360 return fp;
2361 }
2362 }
2363 catch (FailedLoadFile &) {
2364 throw; //forward
2365 }
2366 catch (exception & e) {
2367 throw FailedLoadFile("schema file", full_file_name, e);
2368 }
2369 catch (std::exception & e) {
2370 throw FailedLoadFile("schema file", full_file_name, e.what());
2371 }
2372 catch (...) {
2373 throw FailedLoadFile("schema file", full_file_name, "caught unknown exception");
2374 }
2375}

◆ k_load_schema() [2/2]

void dunedaq::oks::OksKernel::k_load_schema ( OksFile * fp,
std::shared_ptr< OksXmlInputStream > xmls,
const OksFile * parent_h )
private

Definition at line 2379 of file kernel.cpp.

2380{
2382
2383 fp->p_included_by = parent_h;
2384 check_read_only(fp);
2385
2386 try {
2387 if(!p_silence) {
2388 std::lock_guard lock(p_parallel_out_mutex);
2389 std::cout << (parent_h ? " * loading " : "Loading ") << fp->p_number_of_items << " classes from file \"" << fp->get_full_file_name() << "\"...\n";
2390 if(parent_h == 0 && fp->get_full_file_name() != fp->get_short_file_name()) {
2391 std::cout << "(non-fully-qualified filename was \"" << fp->get_short_file_name() << "\")\n";
2392 }
2393 }
2394
2395 k_load_includes(*fp, 0);
2396
2397 add_schema_file(fp);
2398
2399 std::list<OksClass *> set;
2400
2401 while(true) {
2402 OksClass *c = 0;
2403
2404 try {
2405 c = new OksClass(*xmls, this);
2406 }
2407 catch(EndOfXmlStream &) {
2408 delete c;
2409 break;
2410 }
2411
2412 if(c->get_name().empty()) {
2413 throw std::runtime_error("k_load_schema(): failed to read a class");
2414 }
2415
2416 OksClass::Map::const_iterator ic = p_classes.find(c->get_name().c_str());
2417 if(ic != p_classes.end()) {
2418 bool are_different = (*ic->second != *c);
2419
2420 c->p_transient = true;
2421 delete c;
2422 c = ic->second;
2423 if(p_allow_duplicated_classes && !are_different) {
2424 static bool ers_report = (getenv("OKS_KERNEL_ERS_REPORT_DUPLICATED_CLASSES") != nullptr);
2425 if(ers_report) {
2426 ers::warning(kernel::ClassAlreadyDefined(ERS_HERE,c->get_name(),fp->get_full_file_name(),c->p_file->get_full_file_name()));
2427 }
2428 else {
2429 const char _fname[] = "k_load_schema";
2430 std::lock_guard lock(p_parallel_out_mutex);
2431 Oks::warning_msg(make_fname(_fname, sizeof(_fname)-1, fp->get_full_file_name(), nullptr, &parent_h))
2432 << " Class \"" << c->get_name() << "\" was already loaded from file \'" << c->get_file()->get_full_file_name() << "\'\n";
2433 }
2434 }
2435 else {
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());
2439 }
2440 }
2441 else {
2442 {
2443 std::unique_lock lock(p_schema_mutex); // protect schema and all objects from changes
2444 p_classes[c->get_name().c_str()] = c;
2445 }
2446 c->p_file = fp;
2447 if(OksClass::create_notify_fn) set.push_back(c);
2448 }
2449 }
2450
2451 fp->p_size = xmls->get_position();
2452
2454
2456 for(std::list<OksClass *>::iterator i2 = set.begin(); i2 != set.end(); ++i2)
2457 (*OksClass::create_notify_fn)(*i2);
2458
2460 std::set<OksClass *> set2;
2461
2462 for(std::list<OksClass *>::iterator i2 = set.begin(); i2 != set.end(); ++i2) {
2463 OksClass * c = *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()) {
2467 (*OksClass::change_notify_fn)(*i3, OksClass::ChangeSuperClassesList, (const void *)(&(c->p_name)));
2468 set2.insert(*i3);
2469 }
2470 }
2471 }
2472 }
2473 }
2474
2475 fp->update_status_of_file();
2476 }
2477 catch (exception & e) {
2478 throw FailedLoadFile("schema file", fp->get_full_file_name(), e);
2479 }
2480 catch (std::exception & e) {
2481 throw FailedLoadFile("schema file", fp->get_full_file_name(), e.what());
2482 }
2483 catch (...) {
2484 throw FailedLoadFile("schema file", fp->get_full_file_name(), "caught unknown exception");
2485 }
2486}
void add_schema_file(OksFile *)
Definition kernel.cpp:3778
std::shared_mutex p_schema_mutex
Definition kernel.hpp:2050
Monitoring thread not set

◆ k_preload_includes()

bool dunedaq::oks::OksKernel::k_preload_includes ( OksFile * file_h,
std::set< OksFile * > & new_files,
bool allow_schema_extension )
private

Definition at line 2082 of file kernel.cpp.

2083{
2084 bool found_include_changes(false);
2085
2086 try {
2087 std::shared_ptr<std::ifstream> file(new std::ifstream(fp->get_full_file_name().c_str()));
2088
2089 if(!file->good()) {
2090 throw std::runtime_error(std::string("k_preload_includes(): cannot open file \"") + fp->get_full_file_name() + '\"');
2091 }
2092
2093 // keep included files
2094
2095 std::set<std::string> included;
2096
2097 if(fp->p_list_of_include_files.size()) {
2098 for(std::list<std::string>::iterator i = fp->p_list_of_include_files.begin(); i != fp->p_list_of_include_files.end(); ++i) {
2099 included.insert(*i);
2100 }
2101 }
2102
2103 // get size of file and check that it is not empty
2104
2105 file->seekg(0, std::ios::end);
2106
2107 long file_length = static_cast<std::streamoff>(file->tellg());
2108
2109 if(file_length == 0) {
2110 throw std::runtime_error(std::string("k_preload_includes(): file \"") + fp->get_full_file_name() + "\" is empty");
2111 }
2112
2113 file->seekg(0, std::ios::beg);
2114
2115 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(file));
2116
2117 {
2118 OksFile fp2(xmls, fp->get_short_file_name(), fp->get_full_file_name(), this);
2119 fp2.p_included_by = fp->p_included_by;
2120 p_preload_file_info[fp] = new OksFile(*fp);
2121 *fp = fp2;
2122
2123 if(fp->p_oks_format.empty()) {
2124 throw std::runtime_error(std::string("k_preload_includes(): failed to read header of file \"") + fp->get_full_file_name() + '\"');
2125 }
2126 else if(fp->p_oks_format == "schema") {
2127 TLOG_DEBUG(2) << "skip reload of schema file \'" << fp->get_full_file_name() << '\'';
2128 return false;
2129 }
2130 else if(fp->p_oks_format != "data" && fp->p_oks_format != "extended" && fp->p_oks_format != "compact") {
2131 throw std::runtime_error(std::string("k_preload_includes(): file \"") + fp->get_full_file_name() + "\" is not valid oks file");
2132 }
2133 }
2134
2135 if(fp->p_list_of_include_files.size()) {
2136 TLOG_DEBUG(3) << "check \'include\' of the file \'" << fp->get_full_file_name() << '\'';
2137
2138 if(included.size() != fp->p_list_of_include_files.size()) found_include_changes = true;
2139
2140 for(std::list<std::string>::iterator i = fp->p_list_of_include_files.begin(); i != fp->p_list_of_include_files.end(); ++i) {
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...";
2144 }
2145 else {
2146 TLOG_DEBUG(3) << "the file \'" << *i << "\' was not previously included by \'" << fp->get_full_file_name() << '\'';
2147
2148 found_include_changes = true;
2149
2150 std::string full_file_name;
2151
2152 try {
2153 full_file_name = get_file_path(*i, fp);
2154 }
2155 catch (std::exception & e) {
2156 throw CanNotOpenFile("k_preload_includes", *i, e.what());
2157 }
2158
2159 OksFile::Map::const_iterator j = p_schema_files.find(&full_file_name);
2160 if(j != p_schema_files.end()) {
2161 TLOG_DEBUG(3) << "the include \'" << *i << "\' is already loaded schema file \'" << j->first << '\'';
2162 continue;
2163 }
2164
2165 j = p_data_files.find(&full_file_name);
2166 if(j != p_data_files.end()) {
2167 TLOG_DEBUG(3) << "the include \'" << *i << "\' is already loaded data file \'" << j->first << '\'';
2168 continue;
2169 }
2170
2171 if(OksFile * f = create_file_info(*i, full_file_name)) {
2172 if(f->p_oks_format == "schema") {
2173 std::string new_schema_full_file_name = f->get_full_file_name();
2174 delete f;
2175 if(p_schema_files.find(&new_schema_full_file_name) != p_schema_files.end()) {
2176 TLOG_DEBUG(3) << "the include \'" << *i << "\' is a schema file, that was already loaded";
2177 continue;
2178 }
2179 else {
2180 if(allow_schema_extension) {
2181 TLOG_DEBUG(3) << "the include \'" << *i << "\' is new schema file, loading...";
2182 k_load_schema(*i, fp);
2183 continue;
2184 }
2185 else {
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());
2189 }
2190 }
2191 }
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...";
2194 add_data_file(f);
2195 p_preload_added_files.push_back(f);
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();
2201 }
2202 else {
2203 delete f;
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());
2207 }
2208 }
2209 else {
2210 throw std::runtime_error("k_load_file(): cannot open file");
2211 }
2212 }
2213 }
2214 }
2215 }
2216 catch (exception & e) {
2217 throw FailedLoadFile("data file", fp->get_full_file_name(), e);
2218 }
2219 catch (std::exception & e) {
2220 throw FailedLoadFile("data file", fp->get_full_file_name(), e.what());
2221 }
2222
2223 return found_include_changes;
2224}
OksFile * create_file_info(const std::string &short_file_name, const std::string &file_name)
Creates OKS file descriptor.
Definition kernel.cpp:1573
bool k_preload_includes(OksFile *file_h, std::set< OksFile * > &new_files, bool allow_schema_extension)
Definition kernel.cpp:2082

◆ k_remove()

void dunedaq::oks::OksKernel::k_remove ( OksClass * c)
private

Definition at line 4493 of file kernel.cpp.

4494{
4495 TLOG_DEBUG(4) << "enter for class \"" << c->get_name() << '\"';
4496
4497 if(OksClass::delete_notify_fn) (*OksClass::delete_notify_fn)(c);
4498
4499 p_classes.erase(c->get_name().c_str());
4500}

◆ k_rename_data()

void dunedaq::oks::OksKernel::k_rename_data ( OksFile * pf,
const std::string & short_name,
const std::string & long_name )
private

Definition at line 4115 of file kernel.cpp.

4116{
4117 remove_data_file(pf);
4118 pf->rename(short_name, long_name);
4119 add_data_file(pf);
4120}

◆ k_rename_repository_file()

void dunedaq::oks::OksKernel::k_rename_repository_file ( OksFile * file_h,
const std::string & new_name )
private

Definition at line 4867 of file kernel.cpp.

4868{
4869 if (file_h->p_oks_format == "schema")
4870 {
4871 remove_schema_file(file_h);
4872 file_h->rename(new_name);
4873 add_schema_file(file_h);
4874 }
4875 else
4876 {
4877 remove_data_file(file_h);
4878 file_h->rename(new_name);
4879 add_data_file(file_h);
4880 }
4881}

◆ k_rename_schema()

void dunedaq::oks::OksKernel::k_rename_schema ( OksFile * pf,
const std::string & short_name,
const std::string & long_name )
private

Definition at line 2751 of file kernel.cpp.

2752{
2754 pf->rename(short_name, long_name);
2755 add_schema_file(pf);
2756}

◆ k_save_data()

void dunedaq::oks::OksKernel::k_save_data ( OksFile * pf,
bool ignoreBadObjects = false,
OksFile * fh = nullptr,
const OksObject::FSet * objects = nullptr,
bool force_defaults = false )
private

Definition at line 3854 of file kernel.cpp.

3855{
3856 const char _fname[] = "k_save_data";
3857 std::string fname = make_fname(_fname, sizeof(_fname)-1, pf->p_full_name, nullptr, nullptr);
3858
3860 OSK_VERBOSE_REPORT("ENTER " << fname)
3861
3862 std::string tmp_file_name;
3863
3864 if(!fh) fh = pf;
3865
3866 try {
3867
3868 // calculate number of objects in file and check objects
3869
3870 size_t numberOfObjects = 0;
3871
3872 if(objects) {
3873 numberOfObjects = objects->size();
3874
3875 if(!ignoreBadObjects) {
3876 std::string errors;
3877
3878 for(OksObject::FSet::const_iterator i = objects->begin(); i != objects->end(); ++i) {
3879 errors += (*i)->report_dangling_references();
3880 }
3881
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());
3886 }
3887 }
3888 }
3889 else {
3890 // get list of all includes
3891
3892 std::set<OksFile *> includes;
3893 pf->get_all_include_files(this, includes);
3894
3895 OSK_VERBOSE_REPORT("Test consistency of objects in file \"" << pf->p_full_name << '\"')
3896
3897 bool found_bad_object = false;
3898
3899 for(OksObject::Set::iterator i = p_objects.begin(); i != p_objects.end(); ++i) {
3900 if((*i)->file == fh) {
3901 numberOfObjects++;
3902 if(!ignoreBadObjects || !p_silence) {
3903 if((*i)->is_consistent(includes, "WARNING") == false) {
3904 found_bad_object = true;
3905 }
3906 if((*i)->is_duplicated() == true) {
3907 if(!p_silence) {
3908 Oks::error_msg(fname) << " The file contains duplicated object " << *i << std::endl;
3909 }
3910 found_bad_object = true;
3911 }
3912 }
3913 }
3914 }
3915
3916 if(found_bad_object && ignoreBadObjects == false) {
3917 throw std::runtime_error("the file contains inconsistent/duplicated objects or misses includes");
3918 }
3919 }
3920
3921
3922 // lock the file, if it is not locked already
3923
3924 if(pf->is_locked() == false) {
3925 pf->lock();
3926 }
3927
3928
3929 // check if it possible to open the non-existent file in write mode
3930
3931 {
3932 // check first if file already exists
3933
3934 std::fstream f(pf->p_full_name.c_str(), std::ios::in);
3935
3936 if(!f) {
3937
3938 // no check for non-existent file
3939
3940 std::fstream f2(pf->p_full_name.c_str(), std::ios::out);
3941
3942 if(!f2) {
3943 std::ostringstream text;
3944 text << "cannot open file \'" << pf->p_full_name << "\' for writing";
3945 throw std::runtime_error(text.str().c_str());
3946 }
3947 }
3948 }
3949
3950
3951 tmp_file_name = get_tmp_file(pf->p_full_name);
3952
3953 long file_len = 0;
3954
3955 {
3956 std::ofstream f(tmp_file_name.c_str());
3957
3958 f.exceptions ( std::ostream::failbit | std::ostream::badbit );
3959
3960 if(!f) {
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());
3964 }
3965 else {
3966 if(!p_silence) {
3967 std::lock_guard lock(p_parallel_out_mutex);
3968 std::cout << "Saving " << numberOfObjects << " objects " << (force_defaults ? "with enforced default values " : "") << "to data file \"" << pf->p_full_name << "\"...\n";
3969 }
3970 }
3971
3972
3973 // set header parameters
3974
3975 OksXmlOutputStream xmls(f);
3976
3977 pf->p_number_of_items = numberOfObjects;
3978 pf->p_oks_format = "data";
3979
3980 pf->write(xmls);
3981
3982 if(!p_objects.empty()) {
3983 for(OksClass::Map::const_iterator i = p_classes.begin(); i != p_classes.end() && f.good(); ++i) {
3984 OksObject::SMap sorted;
3985
3986 for(OksObject::Map::const_iterator j = i->second->p_objects->begin(); j != i->second->p_objects->end(); ++j) {
3987 if(j->second->file == fh || (objects && (objects->find(j->second) != objects->end()))) {
3988 sorted[j->first] = j->second;
3989 }
3990 }
3991
3992 for(OksObject::SMap::iterator j = sorted.begin(); j != sorted.end(); ++j) {
3993 j->second->put(xmls, force_defaults);
3994 xmls.put_raw('\n');
3995 }
3996 }
3997 }
3998
3999 xmls.put_last_tag("oks-data", sizeof("oks-data")-1);
4000 file_len = f.tellp();
4001
4002 f.close();
4003 }
4004
4005
4006 // check that the written file is OK
4007 // FIXME: can be removed later, if exceptions work well enough
4008
4009 {
4010 long written_len = 0;
4011
4012 std::shared_ptr<std::ifstream> f(new std::ifstream(tmp_file_name.c_str()));
4013
4014 if(*f) {
4015 f->seekg(0, std::ios::end);
4016 written_len = static_cast<std::streamoff>(f->tellg());
4017 }
4018
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());
4024 }
4025 }
4026
4027
4028 // remember file's mode
4029
4030 struct stat buf;
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());
4035 }
4036
4037
4038 // rename temporal file
4039
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());
4044 }
4045
4046 tmp_file_name.erase(0);
4047
4048
4049 if(pf != p_active_data) {
4050 try {
4051 pf->unlock();
4052 }
4053 catch(exception& ex) {
4054 throw std::runtime_error(ex.what());
4055 }
4056 }
4057 pf->p_is_updated = false;
4058 pf->update_status_of_file();
4059
4060
4061 // get mode for new file
4062
4063 struct stat buf2;
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());
4068 }
4069
4070
4071 // set file's mode if needed
4072
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());
4078 }
4079 }
4080
4081 // set file's group if needed (in case of problems report error, but do not throw exception)
4082
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) {
4085 ers::warning(kernel::SetGroupIdFailed(ERS_HERE, buf.st_gid, pf->p_full_name.c_str(), code, strerror(errno)));
4086 }
4087 }
4088
4089 }
4090
4091 catch (exception & e) {
4092 if(pf != p_active_data) { try { pf->unlock();} catch(...) {} }
4093 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
4094 throw CanNotWriteToFile("k_save_data", "data file", pf->p_full_name, e);
4095 }
4096 catch (std::exception & e) {
4097 if(pf != p_active_data) { try { pf->unlock();} catch(...) {} }
4098 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
4099 throw CanNotWriteToFile("k_save_data", "data file", pf->p_full_name, e.what());
4100 }
4101 catch (...) {
4102 if(pf != p_active_data) { try { pf->unlock();} catch(...) {} }
4103 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
4104 throw CanNotWriteToFile("k_save_data", "data file", pf->p_full_name, "unknown");
4105 }
4106
4107 OSK_VERBOSE_REPORT("LEAVE " << fname)
4108}
const OksObject::Set & objects() const
Get objects.
Definition kernel.hpp:1795
static std::string get_tmp_file(const std::string &file_name)
Generates temporal file name.
Definition kernel.cpp:670
std::map< const std::string *, OksObject *, SortById > SMap
Definition object.hpp:865
Unknown serialization type<< t,((char) t)) template< typename T > inline std::string datatype_to_string() { return "Unknown";} namespace serialization { template< typename T > struct is_serializable :std::false_type {};enum SerializationType { kMsgPack };inline SerializationType from_string(const std::string s) { if(s=="msgpack") return kMsgPack;throw UnknownSerializationTypeString(ERS_HERE, s);} constexpr uint8_t serialization_type_byte(SerializationType stype) { switch(stype) { case kMsgPack:return 'M';default:throw UnknownSerializationTypeEnum(ERS_HERE);} } constexpr SerializationType DEFAULT_SERIALIZATION_TYPE=kMsgPack;template< class T > std::vector< uint8_t > serialize(const T &obj, SerializationType stype=DEFAULT_SERIALIZATION_TYPE) { switch(stype) { case kMsgPack:{ msgpack::sbuffer buf;msgpack::pack(buf, obj);std::vector< uint8_t > ret(buf.size()+1);ret[0]=serialization_type_byte(stype);std::copy(buf.data(), buf.data()+buf.size(), ret.begin()+1);return ret;} default:throw UnknownSerializationTypeEnum(ERS_HERE);} } template< class T, typename CharType=unsigned char > T deserialize(const std::vector< CharType > &v) { switch(v[0]) { case serialization_type_byte(kMsgPack):{ try { msgpack::object_handle oh=msgpack::unpack(const_cast< char * >(reinterpret_cast< const char * >(v.data()+1)), v.size() - 1,[](msgpack::type::object_type, std::size_t, void *) -> bool

◆ k_save_schema()

void dunedaq::oks::OksKernel::k_save_schema ( OksFile * pf,
bool force = false,
OksFile * fh = 0,
const OksClass::Map * classes = 0 )
private

Definition at line 2598 of file kernel.cpp.

2599{
2600 const char _fname[] = "k_save_schema";
2601 std::string fname = make_fname(_fname, sizeof(_fname)-1, pf->p_full_name, nullptr, nullptr);
2602
2604 OSK_VERBOSE_REPORT("ENTER " << fname)
2605
2606 std::string tmp_file_name;
2607
2608 if(!fh) fh = pf;
2609
2610 try {
2611
2612 // lock the file, if it is not locked already
2613
2614 if(pf->is_locked() == false) {
2615 pf->lock();
2616 }
2617
2618
2619 // calculate number of classes, going into the schema file
2620
2621 size_t numberOfClasses = 0;
2622
2623 if(classes) {
2624 numberOfClasses = classes->size();
2625 }
2626 else if(!p_classes.empty()) {
2627 for(OksClass::Map::iterator i = p_classes.begin(); i != p_classes.end(); ++i) {
2628 if(i->second->p_file == fh) numberOfClasses++;
2629 }
2630 }
2631
2632
2633 // create temporal file to store the schema
2634
2635 tmp_file_name = get_tmp_file(pf->p_full_name);
2636
2637 {
2638 std::ofstream f(tmp_file_name.c_str());
2639 f.exceptions ( std::ostream::failbit | std::ostream::badbit );
2640
2641 if(!f) {
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());
2645 }
2646 else {
2647 if(!p_silence)
2648 std::cout << "Saving " << numberOfClasses << " classes to schema file \"" << pf->p_full_name << "\"...\n";
2649 }
2650
2651
2652 OksXmlOutputStream xmls(f);
2653
2654
2655 // write oks xml file header
2656
2657 pf->p_number_of_items = numberOfClasses;
2658 pf->p_oks_format = "schema";
2659
2660 pf->write(xmls);
2661
2662
2663 // write oks classes
2664
2665 std::ostringstream errors;
2666 bool found_errors = false;
2667
2668 if (classes)
2669 {
2670 for (auto & i : *classes)
2671 {
2672 found_errors |= i.second->check_relationships(errors, false);
2673 i.second->save(xmls);
2674 }
2675 }
2676 else
2677 {
2678 for (auto & i : p_classes)
2679 {
2680 if (i.second->p_file == fh)
2681 {
2682 found_errors |= i.second->check_relationships(errors, false);
2683 i.second->save(xmls);
2684 }
2685 }
2686 }
2687
2688 if(found_errors)
2689 {
2690 kernel::BindError ex(ERS_HERE, errors.str());
2691
2692 if(force == false)
2693 {
2694 throw std::runtime_error(ex.what());
2695 }
2696 else if(p_silence == false)
2697 {
2698 ers::warning(ex);
2699 }
2700 }
2701
2702 // close oks xml file
2703
2704 xmls.put_last_tag("oks-schema", sizeof("oks-schema")-1);
2705
2706
2707 // flush the buffers
2708
2709 f.close();
2710 }
2711
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());
2716 }
2717
2718 tmp_file_name.erase(0);
2719
2720 if(pf != p_active_schema) {
2721 try {
2722 pf->unlock();
2723 }
2724 catch(exception& ex) {
2725 throw std::runtime_error(ex.what());
2726 }
2727 }
2728 pf->p_is_updated = false;
2729 pf->update_status_of_file();
2730
2731 }
2732 catch (exception & ex) {
2733 if(pf != p_active_schema) { try { pf->unlock();} catch(...) {} }
2734 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
2735 throw CanNotWriteToFile("k_save_schema", "schema file", pf->p_full_name, ex);
2736 }
2737 catch (std::exception & ex) {
2738 if(pf != p_active_schema) { try { pf->unlock();} catch(...) {} }
2739 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
2740 throw CanNotWriteToFile("k_save_schema", "schema file", pf->p_full_name, ex.what());
2741 }
2742
2743 OSK_VERBOSE_REPORT("LEAVE " << fname)
2744}
const OksClass::Map & classes() const
Get classes.
Definition kernel.hpp:1772

◆ k_set_active_data()

void dunedaq::oks::OksKernel::k_set_active_data ( OksFile * fp)

Set active OKS data file.

Non thread-safe version of the set_active_data() method;

Exceptions
Throwoks::exception in case of problems.

Definition at line 4290 of file kernel.cpp.

4291{
4292 TLOG_DEBUG(4) << "enter for file " << (void *)fp;
4293
4294
4295 // check if active data is different from given file
4296
4297 if(p_active_data == fp) return;
4298
4299
4300 // first unlock current active data
4301
4302 if(p_active_data && p_active_data->is_updated() == false) {
4303 try {
4304 p_active_data->unlock();
4305 }
4306 catch(exception& ex) {
4307 throw CanNotSetActiveFile("data", fp->get_full_file_name(), ex);
4308 }
4309 }
4310
4311
4312 // exit, if file is (null)
4313
4314 if(!fp) {
4315 p_active_data = 0;
4316 return;
4317 }
4318
4319 try {
4320 fp->lock();
4321 p_active_data = fp;
4322 }
4323 catch(exception& ex) {
4324 throw CanNotSetActiveFile("data", fp->get_full_file_name(), ex);
4325 }
4326
4327 TLOG_DEBUG(4) << "leave for file " << (void *)fp;
4328}

◆ k_set_active_schema()

void dunedaq::oks::OksKernel::k_set_active_schema ( OksFile * file_h)

Set active OKS schema file. Non thread-safe version of the set_active_schema() method;.

Exceptions
Throwoks::exception in case of problems.

Definition at line 2915 of file kernel.cpp.

2916{
2917 TLOG_DEBUG(4) << "enter for file " << (void *)f;
2918
2919 // check if active schema is different from given file
2920
2921 if(p_active_schema == f) return;
2922
2923
2924 // unlock current active schema, if it was saved
2925
2926 if(p_active_schema && p_active_schema->is_updated() == false) {
2927 try {
2928 p_active_schema->unlock();
2929 }
2930 catch(exception& ex) {
2931 throw CanNotSetActiveFile("schema", f->get_full_file_name(), ex);
2932 }
2933 }
2934
2935
2936 // exit, if file is (null)
2937
2938 if(!f) {
2939 p_active_schema = 0;
2940 return;
2941 }
2942
2943 try {
2944 f->lock();
2946 }
2947 catch(exception& ex) {
2948 throw CanNotSetActiveFile("schema", f->get_full_file_name(), ex);
2949 }
2950
2951 TLOG_DEBUG(4) << "exit for file " << (void *)f;
2952}

◆ load_data()

OksFile * dunedaq::oks::OksKernel::load_data ( const std::string & name,
bool bind = true )

Load OKS data file.

The method loads OKS data file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

By default, after the the data file is loaded, the kernel tries to resolve links between objects. This can be rather cpu consuming operation and it is not scalable for sequential load of many files. In this case it is recommended to change the default bind parameter to false for all but last loading data file.

Parameters
namename of the file to be loaded
bindif true (by default), resolve links between objects
Returns
Return pointer to the OKS file descriptor.
Exceptions
Throwoks::exception in case of problems.

Definition at line 3564 of file kernel.cpp.

3565{
3566 std::unique_lock lock(p_kernel_mutex);
3567 return k_load_data(short_file_name, bind, 0, 0);
3568}

◆ load_file()

OksFile * dunedaq::oks::OksKernel::load_file ( const std::string & name,
bool bind = true )

Load OKS database file.

The method loads OKS schema or data xml file. It parses the file's xml header to detect the file type and calls appropriate load_schema() or load_data() method.

The method is thread-safe. The user may not have the OKS kernel lock set in the thread which calls this method.

The parameters of the method are:

Parameters
namename of the file to be loaded
bindif true, bind objects after load (applicable to data files only)
Returns
Return pointer to the OKS file descriptor.
Exceptions
Throwoks::exception in case of problems.

Definition at line 1793 of file kernel.cpp.

1794{
1795 std::unique_lock lock(p_kernel_mutex);
1796 return k_load_file(short_file_name, bind, 0, 0);
1797}

◆ load_schema()

OksFile * dunedaq::oks::OksKernel::load_schema ( const std::string & name,
const OksFile * parent = 0 )

Load OKS schema file.

The method loads OKS schema file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

The method parameters are:

Parameters
namename of the file to be loaded
parentdescriptor of the parent file (if defined, the name can be relative to the parent file)
Returns
Return pointer to the OKS file descriptor.
Exceptions
Throwoks::exception in case of problems.

Definition at line 2302 of file kernel.cpp.

2303{
2304 std::unique_lock lock(p_kernel_mutex);
2305 return k_load_schema(short_file_name, parent_h);
2306}

◆ new_data()

OksFile * dunedaq::oks::OksKernel::new_data ( const std::string & name,
const std::string & logical_name = "",
const std::string & type = "" )

Create OKS data file.

The method creates new OKS data file and makes it active.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

The method parameters are:

Parameters
namename of the new data file
logical_nameuser-defined logical name of the file (any string passed to the OKS file xml header)
typeuser-defined type of the file (any string passed to the OKS file xml header)
Returns
Return pointer to the OKS file descriptor.
Exceptions
Throwoks::exception in case of problems.

Definition at line 3723 of file kernel.cpp.

3724{
3725 const char _fname[] = "new_data";
3726 std::string fname = make_fname(_fname, sizeof(_fname)-1, s, nullptr, nullptr);
3727 OSK_VERBOSE_REPORT("ENTER " << fname)
3728
3729 if(!s.length()) {
3730 throw CanNotOpenFile("new_data", s, "file name is empty");
3731 }
3732
3733 std::string file_name(s);
3734
3735 try {
3736
3737 Oks::substitute_variables(file_name);
3738
3739 test_file_existence(file_name, p_silence, fname, "data");
3740
3741 file_name = get_file_path(s, nullptr, false);
3742
3743 std::unique_lock lock(p_kernel_mutex);
3744
3745 if(find_data_file(file_name) != 0) {
3746 throw std::runtime_error("the file is already loaded");
3747 }
3748
3749 OksFile * file_h = new OksFile(file_name, logical_name, type, "data", this);
3750
3751 file_h->p_short_name = s;
3752
3753 k_set_active_data(file_h);
3754
3756
3757 }
3758 catch (exception & e) {
3759 throw CanNotCreateFile("new_data", "data file", file_name, e);
3760 }
3761 catch (std::exception & e) {
3762 throw CanNotCreateFile("new_data", "data file", file_name, e.what());
3763 }
3764
3765 OSK_VERBOSE_REPORT("LEAVE " << fname)
3766
3767 return p_active_data;
3768}
void k_set_active_data(OksFile *)
Set active OKS data file.
Definition kernel.cpp:4290
static void test_file_existence(const std::string &file_name, bool silence, const std::string &fname, const char *msg)
Definition kernel.cpp:1600

◆ new_schema()

OksFile * dunedaq::oks::OksKernel::new_schema ( const std::string & name)

Create OKS schema file.

The method creates new OKS schema file and makes it active.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
namename of the new schema file
Returns
Return pointer to the OKS file descriptor
Exceptions
Throwoks::exception in case of problems.

Definition at line 2490 of file kernel.cpp.

2491{
2492 const char _fname[] = "new_schema";
2493 std::string fname = make_fname(_fname, sizeof(_fname)-1, s, nullptr, nullptr);
2494 OSK_VERBOSE_REPORT("ENTER " << fname)
2495
2496 if(!s.length()) {
2497 throw CanNotOpenFile("new_schema", s, "file name is empty");
2498 }
2499
2500 std::string file_name(s);
2501
2502 try {
2503
2504 Oks::substitute_variables(file_name);
2505
2506 test_file_existence(file_name, p_silence, fname, "schema");
2507
2508 file_name = get_file_path(s, nullptr, false);
2509
2510 std::unique_lock lock(p_kernel_mutex);
2511
2512 if(find_schema_file(file_name) != 0) {
2513 throw std::runtime_error("the file is already loaded");
2514 }
2515
2516 OksFile * file_h = new OksFile(file_name, "", "", "schema", this);
2517
2518 file_h->p_short_name = s;
2519
2520 k_set_active_schema(file_h);
2521
2523
2525
2526 }
2527 catch (std::exception & e) {
2528 throw CanNotCreateFile("new_schema", "schema file", file_name, e.what());
2529 }
2530 catch (...) {
2531 throw CanNotCreateFile("new_schema", "schema file", file_name, "caught unknown exception");
2532 }
2533
2534 OSK_VERBOSE_REPORT("LEAVE " << fname)
2535
2536 return p_active_schema;
2537}
void k_set_active_schema(OksFile *file_h)
Set active OKS schema file. Non thread-safe version of the set_active_schema() method;.
Definition kernel.cpp:2915

◆ number_of_classes()

size_t dunedaq::oks::OksKernel::number_of_classes ( ) const
inline

Get number of classes.

Returns
The method returns number of classes loaded in-memory.

Definition at line 1781 of file kernel.hpp.

1781{return p_classes.size();}

◆ number_of_objects()

size_t dunedaq::oks::OksKernel::number_of_objects ( ) const
inline

Get number of objects.

The method returns number of objects loaded in-memory.

Definition at line 1804 of file kernel.hpp.

1804{return p_objects.size();}

◆ objects()

const OksObject::Set & dunedaq::oks::OksKernel::objects ( ) const
inline

Get objects.

In multi-threaded environment to iterate through the set it could be necessary to acquire at least read oks kernel lock before calling the method to be sure that another thread does not modify the set of objects (i.e. destroy or create objects, open or close oks data files).

Returns
The method returns const reference on set of all objects loaded in-memory.

Definition at line 1795 of file kernel.hpp.

1795{return p_objects;}

◆ read_repository_version()

std::string dunedaq::oks::OksKernel::read_repository_version ( )

Read and return current repository version.

Exceptions
Throwoks::exception in case of problems.

Definition at line 5514 of file kernel.cpp.

5515{
5516 std::unique_lock lock(p_kernel_mutex);
5517
5518 if (OksKernel::get_repository_root().empty())
5519 throw RepositoryOperationFailed("status", "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5520
5521 if (get_user_repository_root().empty())
5522 throw RepositoryOperationFailed("status", "the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5523
5524 std::string cmd("oks-version.sh");
5525
5526 cmd.append(" -u ");
5527 cmd.append(get_user_repository_root());
5528
5529 CommandOutput cmd_out("oks-status", this, cmd);
5530 cmd_out.check_command_status(system(cmd.c_str()));
5531
5532 std::string output = cmd_out.cat2str();
5533
5534 static std::string version_prefix("oks version ");
5535 std::string version = cmd_out.last_str();
5536 std::string::size_type pos = version.find(version_prefix);
5537
5538 if (pos == 0)
5539 p_repository_version = version.substr(version_prefix.size());
5540 else
5541 {
5542 std::ostringstream text;
5543 text << "cannot read oks version from oks-version.sh output: \"" << output << '\"';
5544 throw RepositoryOperationFailed("get version", text.str().c_str());
5545 }
5546
5547 return p_repository_version;
5548}

◆ registrate_all_classes()

void dunedaq::oks::OksKernel::registrate_all_classes ( bool skip_registered = false)

The method rebuilds all classes taking into account inheritance.

Parameters
skip_registeredskip registration of already processed classes (used to improve performance)
Exceptions
Throwoks::exception in case of problems.

Definition at line 4504 of file kernel.cpp.

4505{
4506 std::unique_lock lock(p_schema_mutex); // protect schema and all objects from changes
4507
4508 if(size_t num_of_classes = p_classes.size()) {
4509 OksClass ** table = new OksClass * [num_of_classes];
4510 size_t array_size = num_of_classes * sizeof(OksClass*) / sizeof(wchar_t); // is used by wmemset() to init above array with NULLs
4511
4512 OksClass::Map::iterator i = p_classes.begin();
4513 unsigned long idx(0);
4514
4515 for(; i != p_classes.end(); ++i) i->second->registrate_class(skip_registered);
4516
4517 // create lists of sub-classes
4518 // note: do not use unscalable OksClass::create_sub_classes()
4519 for(i = p_classes.begin(); i != p_classes.end(); ++i) {
4520 OksClass * c(i->second);
4521
4522 if(!c->p_all_sub_classes) c->p_all_sub_classes = new OksClass::FList();
4523 else c->p_all_sub_classes->clear();
4524
4525 c->p_id = idx++;
4526 }
4527
4528 for(i = p_classes.begin(); i != p_classes.end(); ++i) {
4529 OksClass * c(i->second);
4530 if(const OksClass::FList * scl = c->p_all_super_classes) {
4531 for(OksClass::FList::const_iterator j = scl->begin(); j != scl->end(); ++j) {
4532 (*j)->p_all_sub_classes->push_back(c);
4533 }
4534 }
4535 }
4536
4538 for(i = p_classes.begin(); i != p_classes.end(); ++i) {
4539 OksClass *c(i->second);
4540 if(!c->get_is_abstract()) {
4541 if(const OksClass::FList * spc = c->all_super_classes()) {
4542 if(!spc->empty()) {
4543 wmemset(reinterpret_cast<wchar_t *>(table), 0, array_size); // [re-]set table by NULLs
4544 for(OksClass::FList::const_iterator j1 = spc->begin(); j1 != spc->end(); ++j1) {
4545 if(const OksClass::FList * sbc = (*j1)->all_sub_classes()) {
4546 for(OksClass::FList::const_iterator j2 = sbc->begin(); j2 != sbc->end(); ++j2) {
4547 OksClass *c2(*j2);
4548 if((c2 != c) && !c2->get_is_abstract()) {
4549 table[c2->p_id] = c2;
4550 }
4551 }
4552 }
4553 }
4554
4555 unsigned int count(0);
4556 for(unsigned int x = 0; x < num_of_classes; ++x) {
4557 if(table[x]) count++;
4558 }
4559
4560 if(count) {
4561 std::vector<OksClass *> * cih;
4562 if(!c->p_inheritance_hierarchy) {
4563 cih = c->p_inheritance_hierarchy = new std::vector<OksClass *>();
4564 }
4565 else {
4566 cih = c->p_inheritance_hierarchy;
4567 cih->clear();
4568 }
4569
4570 cih->reserve(count);
4571
4572 for(unsigned int x = 0; x < num_of_classes; ++x) {
4573 if(table[x]) cih->push_back(table[x]);
4574 }
4575 }
4576 }
4577 }
4578 }
4579 }
4580
4581#ifndef ERS_NO_DEBUG
4582 if(ers::debug_level() >= 2) {
4583 std::ostringstream s;
4584
4585 for(i = p_classes.begin(); i != p_classes.end(); ++i) {
4586 if(std::vector<OksClass *> * cis = i->second->p_inheritance_hierarchy) {
4587 s << " - class \'" << i->second->get_name() << "\' shares IDs with " << cis->size() << " classes: ";
4588 OksClass::Set sorted;
4589 for(std::vector<OksClass *>::const_iterator j = cis->begin(); j != cis->end(); ++j) {
4590 sorted.insert(*j);
4591 }
4592 for(OksClass::Set::const_iterator j = sorted.begin(); j != sorted.end(); ++j) {
4593 if(j != sorted.begin()) s << ", ";
4594 s << '\'' << (*j)->get_name() << '\'';
4595 }
4596 s << std::endl;
4597 }
4598 }
4599
4600 TLOG_DEBUG(2) << "Schema inheritance hierarchy used to test objects with equal IDs:\n" << s.str();
4601 }
4602#endif
4603 }
4604
4605 delete [] table;
4606
4608 }
4609}
std::set< OksClass *, SortByName > Set
Definition class.hpp:227
void k_check_bind_classes_status() const noexcept
Definition kernel.cpp:5715
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...
Definition kernel.hpp:770
bool get_allow_duplicated_objects_mode() const
Get status of duplicated objects mode. The method returns true, if the duplicated objects mode is swi...
Definition kernel.hpp:746
int debug_level()
Definition ers.hpp:77

◆ reload_data()

void dunedaq::oks::OksKernel::reload_data ( std::set< OksFile * > & files,
bool allow_schema_extension = true )

Reload OKS data files.

The method reloads data files. The non-modified objects are not changed in-memory. The objects which were removed in the file are removed in-memory. New objects created in the file are created in-memory. The values of an object' relationships and attributes changed in the file are changed in memory, the address of such object in-memory is not changed.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

The method invokes notification on changes if there is an appropriate subscription.

The method parameters are:

Parameters
filesset of pointer to the OKS data file descriptors returned by a kernel method
allow_schema_extensionif true, new schema files can be included in modified data files
Exceptions
Throwoks::exception in case of problems.

Definition at line 3216 of file kernel.cpp.

3217{
3218 std::map<OksFile *, std::vector<std::string> > included;
3219
3220 std::set<OksFile *>::const_iterator i;
3221
3222 bool check_includes(false);
3223 bool found_schema_files(false);
3224 std::string file_names;
3225
3226 std::unique_lock lock(p_kernel_mutex);
3227
3228 for(std::set<OksFile *>::const_iterator fi = files_h.begin(); fi != files_h.end();) {
3229 if(_find_file(p_schema_files, *fi)) {
3230 found_schema_files = true;
3231 }
3232 else if(!_find_file(p_data_files, *fi)) {
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++);
3235 continue;
3236 }
3237
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('\"');
3242 ++fi;
3243 }
3244
3245 try {
3246
3247 // throw exception on schema_files
3248
3249 if(found_schema_files) {
3250 throw std::runtime_error("Reload of modified schema files is not supported");
3251 }
3252
3253 // exit, if there are no files to reload (e.g. dangling refs.)
3254
3255 if(files_h.empty()) return;
3256
3257
3258 // unlock any locked file
3259 // build container of objects which can be updated (and removed, if not reloaded)
3260
3261 ReloadObjects reload_objects;
3262
3263 for(i = files_h.begin(); i != files_h.end(); ++i) {
3264 if((*i)->is_locked()) {
3265 if(p_active_data == (*i)) { p_active_data = 0; }
3266 (*i)->unlock();
3267 }
3268
3269 for(OksObject::Set::const_iterator oi = p_objects.begin(); oi != p_objects.end(); ++oi) {
3270 if((*oi)->file == *i) reload_objects.put(*oi);
3271 }
3272 }
3273
3274
3275 // preload includes of modified files
3276
3277 {
3278 std::set<OksFile *> new_files;
3279
3280 for(i = files_h.begin(); i != files_h.end(); ++i) {
3281 try {
3282 check_includes |= k_preload_includes(*i, new_files, allow_schema_extension);
3283 }
3284 catch(...) {
3286 throw;
3287 }
3288 }
3289
3291
3292 if(!new_files.empty()) {
3293 TLOG_DEBUG(2) << new_files.size() << " new files will be loaded";
3294 }
3295
3296 for(i = new_files.begin(); i != new_files.end(); ++i) {
3297 files_h.insert(*i);
3298 }
3299 }
3300
3301 // build list of files to be closed:
3302 // close files which are no more referenced by others
3303 // this may happen if there are changes in the list of includes
3304
3305 std::set<OksFile *> files_to_be_closed;
3306
3307 if(check_includes) {
3308 size_t num_of_closing_files = 0;
3309
3310 while(true) {
3311
3312 // build list of good (i.e. "included") files
3313 // rebuild the list, if at least one file was excluded
3314
3315 std::map<std::string, OksFile *> good_files;
3316
3317 for(OksFile::Map::iterator j = p_data_files.begin(); j != p_data_files.end(); ++j) {
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) {
3320 try {
3321 good_files[get_file_path(*l, j->second)] = j->second;
3322 }
3323 catch (...) {
3324 }
3325 }
3326 }
3327 }
3328
3329 for(OksFile::Map::iterator i = p_data_files.begin(); i != p_data_files.end(); ) {
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();
3333 OksFile * f2 = i->second;
3334 ++i;
3335
3336 f2->p_included_by = 0;
3337
3338 // search for a file which could include given one
3339
3340 std::map<std::string, OksFile *>::const_iterator j = good_files.find(s);
3341
3342 if(j != good_files.end()) {
3343 f2->p_included_by = j->second;
3344 }
3345 else {
3346 files_to_be_closed.insert(f2);
3347
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);
3351 }
3352 }
3353
3354 if (files_h.erase(f2)) {
3355 TLOG_DEBUG(2) << "skip reload of updated file \'" << f2->get_full_file_name() << " since it will be closed";
3356 }
3357
3358 TLOG_DEBUG(3) << "file \'" << f2->get_full_file_name() << " will be closed";
3359 }
3360 }
3361 else {
3362 ++i;
3363 }
3364 }
3365
3366 if(num_of_closing_files == files_to_be_closed.size()) {
3367 break;
3368 }
3369 else {
3370 num_of_closing_files = files_to_be_closed.size();
3371 }
3372 }
3373 }
3374 else {
3375 TLOG_DEBUG(2) << "no changes in the list of includes";
3376 }
3377
3378 // remove exclusive RCRs (will be restored when read, if object was not changed)
3379
3380 {
3381 for(std::map< const OksClass *, map_str_t<OksObject *> * >::const_iterator cx = reload_objects.data.begin(); cx != reload_objects.data.end(); ++cx) {
3382 const OksClass * c(cx->first);
3383 if(c->p_all_relationships && !c->p_all_relationships->empty()) {
3384 const unsigned int atts_num(c->number_of_all_attributes());
3385 for(map_str_t<OksObject *>::const_iterator j = cx->second->begin(); j != cx->second->end(); ++j) {
3386 OksObject * obj = j->second;
3387 OksData * d(obj->data + atts_num);
3388
3389 for(std::list<OksRelationship *>::iterator i = c->p_all_relationships->begin(); i != c->p_all_relationships->end(); ++i, ++d) {
3390 OksRelationship * r = *i;
3391 if(r->get_is_composite() && r->get_is_exclusive()) {
3392 if(d->type == OksData::object_type && d->data.OBJECT) {
3393 if(!is_dangling(d->data.OBJECT)) {
3394 d->data.OBJECT->remove_RCR(obj, r);
3395 }
3396 }
3397 else if(d->type == OksData::list_type && d->data.LIST) {
3398 for(OksData::List::iterator i2 = d->data.LIST->begin(); i2 != d->data.LIST->end(); ++i2) {
3399 OksData *d2(*i2);
3400 if(d2->type == OksData::object_type && d2->data.OBJECT) {
3401 if(!is_dangling(d2->data.OBJECT)) {
3402 d2->data.OBJECT->remove_RCR(obj, r);
3403 }
3404 }
3405 }
3406 }
3407 }
3408 }
3409 }
3410 }
3411 }
3412 }
3413
3414 // need to allow "duplicated_objects_via_inheritance_mode", since the objects with the same ID can be created and removed
3415
3416 bool duplicated_objs_mode = get_test_duplicated_objects_via_inheritance_mode();
3418
3419
3420 // read objects
3421
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()));
3424
3425 std::shared_ptr<OksXmlInputStream> xmls(new OksXmlInputStream(f));
3426
3427 OksFile fp(xmls, (*i)->get_short_file_name(), (*i)->get_full_file_name(), this);
3428 char format = (fp.p_oks_format == "data" ? 'n' : ((fp.p_oks_format == "extended") ? 'X': 'c'));
3429
3430 if(!p_silence) {
3431 std::lock_guard lock(p_parallel_out_mutex);
3432 std::cout << " * reading data file \"" << (*i)->get_full_file_name() << "\"..." << std::endl;
3433 }
3434
3435 {
3436 OksAliasTable alias_table;
3437 ReadFileParams read_params( *i, *xmls, ((format == 'X') ? 0 : &alias_table), this, format, &reload_objects );
3438
3439 try {
3440 while(OksObject::read(read_params)) { ; }
3441 }
3442 catch(FailedCreateObject & ex) {
3444 throw ex;
3445 }
3446 }
3447
3448 (*i)->update_status_of_file();
3449 (*i)->p_is_updated = false;
3450 }
3451
3453
3454
3455 // remove objects which were not re-read
3456
3457 OksObject::FSet oset;
3458
3459 {
3460 for(std::map< const OksClass *, map_str_t<OksObject *> * >::const_iterator cx = reload_objects.data.begin(); cx != reload_objects.data.end(); ++cx) {
3461 for(map_str_t<OksObject *>::const_iterator ox = cx->second->begin(); ox != cx->second->end(); ++ox) {
3462 oset.insert(ox->second);
3463 }
3464 }
3465
3466#ifndef ERS_NO_DEBUG
3467 if(ers::debug_level() >= 3) {
3468 std::ostringstream text;
3469 text << "there are " << oset.size() << " removed objects:\n";
3470
3471 for(OksObject::FSet::iterator x = oset.begin(); x != oset.end(); ++x) {
3472 text << " - object " << *x << std::endl;
3473 TLOG_DEBUG(3) << text.str();
3474 }
3475 }
3476#endif
3477
3478 {
3479 OksObject::FSet refs;
3480 unbind_all_rels(oset, refs);
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 *** ";
3484 (*p_change_object_notify_fn)(*x2, p_change_object_notify_param);
3485 }
3486 }
3487 }
3488 }
3489
3490 for(OksObject::FSet::iterator ox = oset.begin(); ox != oset.end(); ++ox) {
3491 OksObject * o = *ox;
3492
3493 if(is_dangling(o)) {
3494 TLOG_DEBUG(4) << "skip dangling object " << (void *)o;
3495 continue;
3496 }
3497
3498 TLOG_DEBUG(3) << "*** remove non-reloaded object " << o << " => " << (void *)o << " ***";
3499
3500 delete o;
3501 }
3502
3503
3504 for(std::set<OksFile *>::const_iterator x = files_to_be_closed.begin(); x != files_to_be_closed.end(); ++x) {
3505 k_close_data(*x, true);
3506 }
3507
3509
3510
3511 // check that created objects do not have duplicated IDs within inheritance hierarchy
3512
3513 if (duplicated_objs_mode == true)
3514 {
3515 for (auto& o : reload_objects.created)
3516 {
3517 o->check_ids();
3518 }
3519 }
3520 }
3521 catch (exception & e) {
3522 throw FailedReloadFile(file_names, e);
3523 }
3524 catch (std::exception & e) {
3525 throw FailedReloadFile(file_names, e.what());
3526 }
3527}
std::map< std::string, T > map_str_t
Definition kernel.hpp:591
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...
Definition kernel.hpp:761
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...
Definition kernel.cpp:4408
std::unordered_set< OksObject *, oks::hash_obj_ptr, oks::equal_obj_ptr > FSet
Definition object.hpp:871
static OksObject * read(const oks::ReadFileParams &)
Definition object.cpp:368
static bool _find_file(const OksFile::Map &files, const OksFile *f)
Definition kernel.cpp:3172
msgpack::object obj

◆ remove_data_file()

void dunedaq::oks::OksKernel::remove_data_file ( OksFile * f)
private

Definition at line 3784 of file kernel.cpp.

3785{
3786 p_data_files.erase(&f->p_full_name);
3787}

◆ remove_repository_dir()

void dunedaq::oks::OksKernel::remove_repository_dir ( const std::string & dir)

Remove repository search directory.

The method removes from the search list directory with given name. The method is not thread-safe.

Parameters
dirdirectory name (must be fully qualified name)

Definition at line 1429 of file kernel.cpp.

1430{
1431 std::unique_lock lock(p_kernel_mutex);
1432
1433 std::list<std::string>::iterator i = std::find(p_repository_dirs.begin(), p_repository_dirs.end(), dir);
1434 if(i != p_repository_dirs.end()) {
1435 if(p_verbose) {
1436 std::cout << " * remove repository search directory \'" << dir << "\'\n";
1437 }
1438 p_repository_dirs.erase(i);
1439 }
1440}

◆ remove_schema_file()

void dunedaq::oks::OksKernel::remove_schema_file ( OksFile * f)
private

Definition at line 3790 of file kernel.cpp.

3791{
3792 p_schema_files.erase(&f->p_full_name);
3793}

◆ remove_user_repository_dir()

void dunedaq::oks::OksKernel::remove_user_repository_dir ( )
private

Definition at line 4946 of file kernel.cpp.

4947{
4949 {
4953 }
4954}
static void remove(const std::string &path)
Definition kernel.cpp:83
void erase(const std::string &path)
Definition kernel.cpp:103

◆ reset_cwd()

void dunedaq::oks::OksKernel::reset_cwd ( )
inlinestatic

Reset current working dir in case of chdir() call.

Definition at line 1719 of file kernel.hpp.

1719{ s_cwd = 0;}

◆ restore_preload_file_info()

void dunedaq::oks::OksKernel::restore_preload_file_info ( )
private

Definition at line 3541 of file kernel.cpp.

3542{
3543 for(std::vector<OksFile *>::iterator j = p_preload_added_files.begin(); j != p_preload_added_files.end(); ++j) {
3544 TLOG_DEBUG( 1 ) << "remove file " << (*j)->get_full_file_name() ;
3545 remove_data_file(*j);
3546 delete *j;
3547 }
3548
3549 for(OksFile::Map::iterator i = p_data_files.begin(); i != p_data_files.end(); ++i) {
3550 std::map<const OksFile *, OksFile *>::iterator j = p_preload_file_info.find(i->second);
3551 if(j != p_preload_file_info.end()) {
3552 TLOG_DEBUG( 1 ) << "restore file " << i->second->get_full_file_name() ;
3553 (*i->second) = (*j->second);
3554 }
3555 }
3556
3558}

◆ save_all_data()

void dunedaq::oks::OksKernel::save_all_data ( bool force_defaults = false)

Save all OKS data files.

The method saves all OKS data files which were created or loaded by the OKS kernel. The files are saved in the same format (extended or compact), in which they were saved last time.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Exceptions
Throwoks::exception in case of problems.

Definition at line 4165 of file kernel.cpp.

4166{
4167 TLOG_DEBUG(4) << "enter";
4168
4169 {
4170 std::shared_lock lock(p_kernel_mutex);
4171
4172 for(OksFile::Map::iterator i = p_data_files.begin(); i != p_data_files.end(); ++i) {
4173 if(check_read_only(i->second) == false) {
4174 k_save_data(i->second, false, nullptr, nullptr, force_defaults);
4175 }
4176 else {
4177 TLOG_DEBUG(2) << "skip read-only data file \'" << *(i->first) << '\'';
4178 }
4179 }
4180 }
4181
4182 TLOG_DEBUG(4) << "exit";
4183}

◆ save_all_schema()

void dunedaq::oks::OksKernel::save_all_schema ( )

Save all OKS schema files.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

The method saves all OKS schema files which were created or loaded by the OKS kernel.

Exceptions
Throwoks::exception in case of problems.

Definition at line 2799 of file kernel.cpp.

2800{
2801 OSK_VERBOSE_REPORT("ENTER OksKernel::save_all_schema()")
2802
2803 {
2804 std::shared_lock lock(p_kernel_mutex);
2805
2806 for(OksFile::Map::iterator i = p_schema_files.begin(); i != p_schema_files.end(); ++i) {
2807 if(check_read_only(i->second) == false) {
2808 k_save_schema(i->second);
2809 }
2810 else {
2811 TLOG_DEBUG(2) << "skip read-only schema file \'" << *(i->first) << '\'';
2812 }
2813
2814 }
2815
2816 }
2817
2818 OSK_VERBOSE_REPORT("LEAVE OksKernel::save_all_schema()")
2819}

◆ save_as_data()

void dunedaq::oks::OksKernel::save_as_data ( const std::string & new_name,
OksFile * file_h )

Save OKS data file under new name.

The method changes the name of given OKS data file and saves it.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
new_namenew name of the data file
file_ha pointer to the OKS data file descriptor returned by a kernel method
Exceptions
Throwoks::exception in case of problems.

Definition at line 4123 of file kernel.cpp.

4124{
4125 const char _fname[] = "save_as_data";
4126 std::string fname = make_fname(_fname, sizeof(_fname)-1, new_name, nullptr, &pf);
4127 OSK_VERBOSE_REPORT("ENTER " << fname)
4128
4129 try {
4130
4131 if(!new_name.length()) {
4132 throw std::runtime_error("the new filename is empty");
4133 }
4134
4135 std::unique_lock lock(p_kernel_mutex);
4136
4137 std::string old_short_name = pf->p_short_name;
4138 std::string old_full_name = pf->p_full_name;
4139 std::string old_format = pf->p_oks_format;
4140
4141 k_rename_data(pf, new_name, new_name);
4142
4143 try {
4144 k_save_data(pf);
4145 }
4146 catch (...) {
4147 k_rename_data(pf, old_short_name, old_full_name);
4148 pf->p_oks_format = old_format;
4149 throw;
4150 }
4151
4152 }
4153 catch (exception & ex) {
4154 throw CanNotWriteToFile("k_save_as_data", "data file", new_name, ex);
4155 }
4156 catch (std::exception & ex) {
4157 throw CanNotWriteToFile("k_save_as_data", "data file", new_name, ex.what());
4158 }
4159
4160 OSK_VERBOSE_REPORT("LEAVE " << fname)
4161}
void k_rename_data(OksFile *, const std::string &short_name, const std::string &long_name)
Definition kernel.cpp:4115

◆ save_as_schema()

void dunedaq::oks::OksKernel::save_as_schema ( const std::string & name,
OksFile * file_h )

Save OKS schema file under new name.

The method changes the name of given OKS schema file and saves it.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
namenew name of the schema file
file_ha pointer to the OKS schema file descriptor returned by a kernel method
Exceptions
Throwoks::exception in case of problems.

Definition at line 2760 of file kernel.cpp.

2761{
2762 const char _fname[] = "save_as_schema";
2763 std::string fname = make_fname(_fname, sizeof(_fname)-1, new_name, nullptr, &pf);
2764 OSK_VERBOSE_REPORT("ENTER " << fname)
2765
2766 try {
2767
2768 if(!new_name.length()) {
2769 throw std::runtime_error("the new filename is empty");
2770 }
2771
2772 std::string old_short_name = pf->p_short_name;
2773 std::string old_full_name = pf->p_full_name;
2774
2775 std::unique_lock lock(p_kernel_mutex);
2776
2777 k_rename_schema(pf, new_name, new_name);
2778
2779 try {
2780 k_save_schema(pf);
2781 }
2782 catch (...) {
2783 k_rename_schema(pf, old_short_name, old_full_name);
2784 throw;
2785 }
2786
2787 }
2788 catch (exception & ex) {
2789 throw CanNotWriteToFile("k_save_as_schema", "schema file", pf->p_full_name, ex);
2790 }
2791 catch (std::exception & ex) {
2792 throw CanNotWriteToFile("k_save_as_schema", "schema file", pf->p_full_name, ex.what());
2793 }
2794
2795 OSK_VERBOSE_REPORT("LEAVE " << fname)
2796}
void k_rename_schema(OksFile *, const std::string &short_name, const std::string &long_name)
Definition kernel.cpp:2751

◆ save_data() [1/2]

void dunedaq::oks::OksKernel::save_data ( OksFile * file_h,
bool ignore_bad_objects = false,
OksFile * true_file_h = nullptr,
bool force_defaults = false )

Save OKS data file.

The method saves given OKS data file. By default the format of data file is compact. To save the file in the extended format set parameter extended_format to true.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS data file descriptor
ignore_bad_objectssave the file if it has inconsistent objects or misses includes
true_file_ha pointer to the real OKS data file descriptor owning objects (used for backup)
Exceptions
Throwoks::exception in case of problems.

Definition at line 3799 of file kernel.cpp.

3800{
3801 std::shared_lock lock(p_kernel_mutex);
3802 k_save_data(pf, ignoreBadObjects, true_file_h, nullptr, force_defaults);
3803}

◆ save_data() [2/2]

void dunedaq::oks::OksKernel::save_data ( OksFile * file_h,
const OksObject::FSet & objects )

Save objects into given OKS data file.

The method saves explicitly mentioned objects into given OKS data file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to an external OKS data file descriptor
objectsset of objects to be saved into this data file
Exceptions
Throwoks::exception in case of problems.

Definition at line 3806 of file kernel.cpp.

3807{
3808 std::shared_lock lock(p_kernel_mutex);
3809 k_save_data(file_h, false, 0, &objects);
3810}

◆ save_schema() [1/2]

void dunedaq::oks::OksKernel::save_schema ( OksFile * file_h,
bool force,
const OksClass::Map & classes )

Save classes into given OKS schema file.

The method saves explicit set of classes into given OKS schema file. This is used to merge schema files by RDB server.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to an external OKS schema file descriptor
forceif true, ignore problems if possible (e.g. dangling references)
classesset of classes to be saved
Exceptions
Throwoks::exception in case of problems.

Definition at line 2551 of file kernel.cpp.

2552{
2553 std::shared_lock lock(p_kernel_mutex);
2554 k_save_schema(file_h, force, 0, &classes);
2555}

◆ save_schema() [2/2]

void dunedaq::oks::OksKernel::save_schema ( OksFile * file_h,
bool force = false,
OksFile * true_file_h = 0 )

Save OKS schema file.

The method saves given OKS schema file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS schema file descriptor returned by a kernel method
forceif true, ignore problems if possible (e.g. dangling references)
true_file_ha pointer to the real OKS data file descriptor owning classes (used for backup)
Exceptions
Throwoks::exception in case of problems.

Definition at line 2543 of file kernel.cpp.

2544{
2545 std::shared_lock lock(p_kernel_mutex);
2546 k_save_schema(pf, force, fh);
2547}

◆ schema_files()

const OksFile::Map & dunedaq::oks::OksKernel::schema_files ( ) const
inline

Get all schema files.

The method returns all schema files which were created or loaded by the OKS kernel.

Returns
Return const reference on map of the OKS schema file descriptors.

The method is thread-safe.

Definition at line 1228 of file kernel.hpp.

1228{return p_schema_files;}

◆ set_active_data()

void dunedaq::oks::OksKernel::set_active_data ( OksFile * file_h)

Set active OKS data file.

The method makes given OKS data file active. Any created object will go to the active data file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS data file descriptor returned by a kernel method
Exceptions
Throwoks::exception in case of problems.

Definition at line 4283 of file kernel.cpp.

4284{
4285 std::unique_lock lock(p_kernel_mutex);
4287}

◆ set_active_schema()

void dunedaq::oks::OksKernel::set_active_schema ( OksFile * file_h)

Set active OKS schema file.

The method makes given OKS schema file active. Any created class will go to the active schema file.

The method is thread-safe. The user must not have the OKS kernel lock set in the thread which calls this method.

Parameters
file_ha pointer to the OKS schema file descriptor returned by a kernel method
Exceptions
Throwoks::exception in case of problems.

Definition at line 2908 of file kernel.cpp.

2909{
2910 std::unique_lock lock(p_kernel_mutex);
2912}

◆ set_allow_duplicated_classes_mode()

void dunedaq::oks::OksKernel::set_allow_duplicated_classes_mode ( const bool b)
inline

Set status of duplicated classes mode. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' or 'false' to switch 'Off'.

The duplicated classes mode can also be switched 'On' using the "OKS_KERNEL_ALLOW_DUPLICATED_CLASSES" environment variable set to any value except 'no'.

Definition at line 782 of file kernel.hpp.

◆ set_allow_duplicated_objects_mode()

void dunedaq::oks::OksKernel::set_allow_duplicated_objects_mode ( const bool b)
inline

Set status of duplicated objects mode. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' or 'false' to switch 'Off'.

The duplicated objects mode can also be switched 'On' using the "OKS_KERNEL_ALLOW_DUPLICATED_OBJECTS" environment variable set to any value except 'no'.

Definition at line 794 of file kernel.hpp.

◆ set_profiling_mode()

void dunedaq::oks::OksKernel::set_profiling_mode ( const bool b)

Set status of profiling mode. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' or 'false' to switch 'Off'.

The profiling mode can also be switched 'On' using the "OKS_KERNEL_PROFILING" environment variable set to any value except 'no'.

Definition at line 1444 of file kernel.cpp.

1445{
1446 if(p_profiling == b) return;
1447
1448 p_profiling = b;
1449
1450#ifndef ERS_NO_DEBUG
1451 if(p_profiling == true) {
1452 if(!profiler) profiler = new OksProfiler();
1453 }
1454 else {
1455 if(profiler) {
1456 delete profiler;
1457 profiler = 0;
1458 }
1459 }
1460#endif
1461}

◆ set_silence_mode()

void dunedaq::oks::OksKernel::set_silence_mode ( const bool b)
inline

Set status of silence mode. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' or 'false' to switch 'Off'.

The silence mode can also be switched 'On' using the "OKS_KERNEL_SILENCE" environment variable set to any value except 'no'.

Definition at line 703 of file kernel.hpp.

703{p_silence = b;}

◆ set_skip_string_range()

void dunedaq::oks::OksKernel::set_skip_string_range ( const bool b)
inlinestatic

Set status of string range validator. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' (i.e. to bypass the test) or 'false' to switch 'Off' (i.e. to force the test).

The skip max length check mode can also be switched 'On' using the "OKS_KERNEL_SKIP_STRING_RANGE" environment variable set to any value except 'no'.

Definition at line 816 of file kernel.hpp.

◆ set_test_duplicated_objects_via_inheritance_mode()

void dunedaq::oks::OksKernel::set_test_duplicated_objects_via_inheritance_mode ( const bool b)
inline

Set status of test inherited duplicated objects mode. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' or 'false' to switch 'Off'.

When the mode is switched 'On', the OKS kernel does not allow objects with equal IDs withing the same class inheritance hierarchy.

The test inherited duplicated objects mode can also be switched 'On' using the "OKS_KERNEL_TEST_DUPLICATED_OBJECTS_VIA_INHERITANCE" environment variable set to any value except 'no'.

Definition at line 761 of file kernel.hpp.

◆ set_use_strict_repository_paths()

void dunedaq::oks::OksKernel::set_use_strict_repository_paths ( bool flag)
inlinestatic

Set flag to use strict-repository-paths check.

Definition at line 1727 of file kernel.hpp.

1728 {
1730 }

◆ set_user_repository_root()

void dunedaq::oks::OksKernel::set_user_repository_root ( const std::string & path,
const std::string & version = "" )

Set user OKS repository root.

Used by OKS and RDB tools only!

Definition at line 394 of file kernel.cpp.

395{
396 if(get_repository_root().empty()) {
397 TLOG_DEBUG( 1) << "Failed to set user-repository-root:\n\tcaused by: repository-root is not set" ;
399 return;
400 }
401
402 if(path.empty()) {
404 return;
405 }
406
407 std::string s;
408 s = path;
409
410 try {
411 Oks::real_path(s, false);
412 }
413 catch(exception& ex) {
414 TLOG_DEBUG( 1) << "Failed to set user-repository-root = \'" << s << "\':\n\tcaused by: " << ex.what() ;
415 }
416
417 for(std::string::size_type idx = s.size()-1; idx > 0 && s[idx] == '/' ; idx--) {
418 s.erase(idx);
419 }
420
421 p_allow_repository = true;
422
425
426 // is used for backup restore by RDB
427 if (!version.empty())
429}

◆ set_verbose_mode()

void dunedaq::oks::OksKernel::set_verbose_mode ( const bool b)
inline

Set status of verbose mode. To switch 'On'/'Off' use the method's parameter:

Parameters
b- set 'true' to switch 'On' or 'false' to switch 'Off'.

The verbose mode can also be switched 'On' using the "OKS_KERNEL_VERBOSE" environment variable set to any value except 'no'.

Definition at line 682 of file kernel.hpp.

682{p_verbose = b;}

◆ subscribe_change_class()

void dunedaq::oks::OksKernel::subscribe_change_class ( void(* )(OksClass *, OksClass::ChangeType, const void *))
inline

Subscribe on class changing.

The method subscribes user-provided callback function on changes of existing oks class. The callback function is called when a class is changed and its arguments are the pointer to the changed class, the type of change and the change parameter.

Parameters
fuser callback function

Definition at line 2211 of file kernel.hpp.

2212{
2214}

◆ subscribe_change_object()

void dunedaq::oks::OksKernel::subscribe_change_object ( OksObject::notify_obj f,
void * p )
inline

Subscribe on object changing.

The method subscribes user-provided callback function on changing of existing oks object. The callback function is called when an object is changed.

Parameters
cb_fuser callback function
parameterparameter to be passed to the user callback function

Definition at line 2188 of file kernel.hpp.

◆ subscribe_create_class()

void dunedaq::oks::OksKernel::subscribe_create_class ( void(* )(OksClass *))
inline

Subscribe on class creation.

The method subscribes user-provided callback function on creation of new oks class. The callback function is called when a new class is created and its argument is the pointer to the new class.

Parameters
fuser callback function

Definition at line 2204 of file kernel.hpp.

2205{
2207}

◆ subscribe_create_object()

void dunedaq::oks::OksKernel::subscribe_create_object ( OksObject::notify_obj f,
void * p )
inline

Subscribe on object creation.

The method subscribes user-provided callback function on creation of new oks object. The callback function is called when a new object is created (except when it is read from file using load_data() method).

Parameters
cb_fuser callback function
parameterparameter to be passed to the user callback function

Inline methods for class OksKernel

Definition at line 2180 of file kernel.hpp.

◆ subscribe_delete_class()

void dunedaq::oks::OksKernel::subscribe_delete_class ( void(* )(OksClass *))
inline

Subscribe on class destroying.

The method subscribes user-provided callback function on destroying of existing oks class. The callback function is called when a class is destroying (e.g. schema file containing the class is closed) and its argument is the pointer to the destroying class.

Parameters
fuser callback function

Definition at line 2218 of file kernel.hpp.

2219{
2221}

◆ subscribe_delete_object()

void dunedaq::oks::OksKernel::subscribe_delete_object ( OksObject::notify_obj f,
void * p )
inline

Subscribe on object deleting.

The method subscribes user-provided callback function on destroying of existing oks object. The callback function is called when an object is destroying (e.g. data file containing the object is closed) and its argument is the pointer to the destroying object.

Parameters
cb_fuser callback function
parameterparameter to be passed to the user callback function

Definition at line 2196 of file kernel.hpp.

◆ tag_repository()

void dunedaq::oks::OksKernel::tag_repository ( const std::string & tag)

Tag current state of repository.

The method assigns a tag to current state of repository.

Parameters
tagthe tag
Exceptions
Throwoks::exception in case of problems.

Definition at line 5207 of file kernel.cpp.

5208{
5209 std::unique_lock lock(p_kernel_mutex);
5210
5211 if (OksKernel::get_repository_root().empty())
5212 throw RepositoryOperationFailed("tag", "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5213
5214 if (get_user_repository_root().empty())
5215 throw RepositoryOperationFailed("tag", "the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5216
5217 std::string cmd("oks-tag.sh");
5218
5219 if (get_verbose_mode())
5220 cmd.append(" -v");
5221
5222 cmd.append(" -u ");
5223 cmd.append(get_user_repository_root());
5224
5225 if(tag.empty() || std::all_of(tag.begin(), tag.end(), [](char c) { return std::isspace(c); }))
5226 throw RepositoryOperationFailed("tag", "the tag may not be empty");
5227
5228 cmd.append(" -t \'");
5229 cmd.append(tag);
5230 cmd.append("\' -c \'");
5231 cmd.append(get_repository_version());
5232 cmd.push_back('\'');
5233
5234 auto start_usage = std::chrono::steady_clock::now();
5235
5236 if (!p_silence)
5237 {
5238 std::lock_guard lock(p_parallel_out_mutex);
5239 log_timestamp() << "[OKS tag] => " << cmd << std::endl;
5240 }
5241
5242 CommandOutput cmd_out("oks-tag", this, cmd);
5243 cmd_out.check_command_status(system(cmd.c_str()));
5244
5245 if (!p_silence)
5246 {
5247 std::lock_guard lock(p_parallel_out_mutex);
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;
5250 }
5251}

◆ test_parent()

bool dunedaq::oks::OksKernel::test_parent ( OksFile * file,
OksFile::IMap::iterator & i )
private

Definition at line 1948 of file kernel.cpp.

1949{
1950 OksFile * parent(i->first);
1951 OksFile::Set& includes(i->second);
1952
1953 if(includes.find(file) != includes.end()) {
1954 if(file->p_included_by != parent) {
1955 TLOG_DEBUG( 1 ) << "new parent of file " << file->get_full_file_name() << " is " << parent->get_full_file_name() ;
1956 file->p_included_by = parent;
1957 }
1958
1959 return true;
1960 }
1961
1962 return false;
1963}
std::unordered_set< OksFile *, oks::hash_file_ptr, oks::equal_file_ptr > Set
Definition file.hpp:374

◆ unbind_all_rels()

void dunedaq::oks::OksKernel::unbind_all_rels ( const OksObject::FSet & rm_objs,
OksObject::FSet & updated ) const
private

Unbind all references on given oks objects. The method unbinds all relationships referencing given objects.

Parameters
rm_objsobjects to be destroyed
updatedreturn updated objects (i.e. containing unbind references)

Definition at line 4408 of file kernel.cpp.

4409{
4410 const OksClass::Map& all_classes(classes());
4411
4412 for(OksClass::Map::const_iterator i = all_classes.begin(); i != all_classes.end(); ++i) {
4413 OksClass * c(i->second);
4414 if(const OksObject::Map * objs = i->second->objects()) {
4415 for(OksObject::Map::const_iterator j = objs->begin(); j != objs->end(); ++j) {
4416 OksObject *o(j->second);
4417 unsigned short l1 = c->number_of_all_attributes();
4418 unsigned short l2 = l1 + c->number_of_all_relationships();
4419
4420 while(l1 < l2) {
4421 OksDataInfo odi(l1, (OksRelationship *)0);
4422 OksData * d(o->GetRelationshipValue(&odi));
4423
4424 if(d->type == OksData::object_type) {
4425 if(rm_objs.find(d->data.OBJECT) != rm_objs.end()) {
4426 updated.insert(o);
4427 const OksClass * __c(d->data.OBJECT->GetClass());
4428 const OksString& __id(d->data.OBJECT->GetId());
4429 d->Set(__c,__id);
4430 TLOG_DEBUG(5) << "set relationship of " << o << ": " << *d;
4431 }
4432 }
4433 else if(d->type == OksData::list_type) {
4434 for(OksData::List::const_iterator li = d->data.LIST->begin(); li != d->data.LIST->end(); ++li) {
4435 OksData * lid(*li);
4436 if(lid->type == OksData::object_type) {
4437 if(rm_objs.find(lid->data.OBJECT) != rm_objs.end()) {
4438 updated.insert(o);
4439 const OksClass * __c(lid->data.OBJECT->GetClass());
4440 const OksString& __id(lid->data.OBJECT->GetId());
4441 lid->Set(__c,__id);
4442 TLOG_DEBUG(5) << "set relationship of " << o << ": " << *d;
4443 }
4444 }
4445 }
4446 }
4447 ++l1;
4448 }
4449 }
4450 }
4451 }
4452}
std::map< const char *, OksClass *, SortStr > Map
Definition class.hpp:238

◆ undefine()

void dunedaq::oks::OksKernel::undefine ( OksObject * o)
inlineprivate

Definition at line 2154 of file kernel.hpp.

2154{ if(!p_objects.empty()) { std::lock_guard lock(p_objects_mutex); p_objects.erase(o); } }

◆ unset_repository_created()

void dunedaq::oks::OksKernel::unset_repository_created ( )

Set repository created flag to false to avoid created repository removal in destructor;.

Definition at line 4957 of file kernel.cpp.

◆ update_repository() [1/2]

void dunedaq::oks::OksKernel::update_repository ( const std::string & hash_val,
RepositoryUpdateType update_type )
inline

Update user repository files from origin by hash.

The method performs GIT update of files in local user directory.

Parameters
hash_valSHA or "origin/master"
update_typeaction in case of conflicts (discard changes, try to merge changes, cancel)
Exceptions
Throwoks::exception in case of problems.

Definition at line 1613 of file kernel.hpp.

1614 {
1615 update_repository("hash", hash_val, update_type);
1616 }
void update_repository(const std::string &hash_val, RepositoryUpdateType update_type)
Update user repository files from origin by hash.
Definition kernel.hpp:1613

◆ update_repository() [2/2]

void dunedaq::oks::OksKernel::update_repository ( const std::string & param,
const std::string & val,
RepositoryUpdateType update_type )

Update user repository files from origin.

The method performs GIT update of files in local user directory. Pass parameters to the oks-git-update.sh script.

Parameters
param"tag", "date" or "hash"
valSHA or "origin/master"
update_typeaction in case of conflicts (discard changes, try to merge changes, cancel)
Exceptions
Throwoks::exception in case of problems.

Definition at line 4999 of file kernel.cpp.

5000{
5001 std::unique_lock lock(p_kernel_mutex);
5002
5003 if (OksKernel::get_repository_root().empty())
5004 throw RepositoryOperationFailed("update", "the repository-root is not set (check environment variable TDAQ_DB_REPOSITORY)");
5005
5006 if (get_user_repository_root().empty())
5007 throw RepositoryOperationFailed("update", "the user-repository-root is not set (check environment variable TDAQ_DB_USER_REPOSITORY)");
5008
5009 std::string cmd("oks-update.sh");
5010
5011 if (get_verbose_mode())
5012 cmd.append(" -v");
5013
5014 cmd.append(" -u ");
5015 cmd.append(get_user_repository_root());
5016
5017 if (update_type == OksKernel::DiscardChanges)
5018 cmd.append(" --force");
5019 else if (update_type == OksKernel::MergeChanges)
5020 cmd.append(" --merge");
5021
5022 if (!param.empty())
5023 {
5024 cmd.append(" --");
5025 cmd.append(param);
5026 cmd.push_back(' ');
5027 cmd.push_back('\"');
5028 cmd.append(val);
5029 cmd.push_back('\"');
5030 }
5031
5032 auto start_usage = std::chrono::steady_clock::now();
5033
5034 if (!p_silence) {
5035 std::lock_guard lock(p_parallel_out_mutex);
5036 log_timestamp() << "[OKS update] => " << cmd << std::endl;
5037 }
5038
5039 CommandOutput cmd_out("oks-update", this, cmd);
5040 cmd_out.check_command_status(system(cmd.c_str()));
5041
5042 p_repository_update_ts = std::time(0);
5043
5044 static std::string version_prefix("update oks version ");
5045 std::string version = cmd_out.last_str();
5046 std::string::size_type pos = version.find(version_prefix);
5047
5048 if(pos == 0)
5049 p_repository_version = version.substr(version_prefix.size());
5050 else
5051 throw RepositoryOperationFailed("commit", "cannot read oks version");
5052
5053 if (!p_silence)
5054 {
5055 std::lock_guard lock(p_parallel_out_mutex);
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;
5058 }
5059}

◆ OksClass

friend class OksClass
friend

Definition at line 585 of file kernel.hpp.

◆ OksData

friend struct OksData
friend

Definition at line 588 of file kernel.hpp.

◆ OksFile

friend class OksFile
friend

Definition at line 584 of file kernel.hpp.

◆ OksLoadObjectsJob

friend struct OksLoadObjectsJob
friend

Definition at line 587 of file kernel.hpp.

◆ OksObject

friend class OksObject
friend

Definition at line 586 of file kernel.hpp.

◆ operator<<

std::ostream & operator<< ( std::ostream & s,
OksKernel & k )
friend

Definition at line 1496 of file kernel.cpp.

1498{
1500
1501 s << "OKS KERNEL DUMP:\n" << "OKS VERSION: " << k.GetVersion() << std::endl;
1502
1503 if (!k.p_schema_files.empty())
1504 {
1505 s << " Loaded schema:\n";
1506
1507 for (const auto& i : k.p_schema_files)
1508 s << " " << i.second->get_full_file_name() << std::endl;
1509
1510 if (!k.p_data_files.empty())
1511 {
1512 s << " Loaded data:\n";
1513
1514 for (const auto& j : k.p_data_files)
1515 s << " " << j.second->get_full_file_name() << std::endl;
1516 }
1517 else
1518 s << " No loaded data files\n";
1519
1520 if (!k.p_classes.empty())
1521 {
1522 s << " The classes:\n";
1523
1524 for (const auto& j : k.p_classes)
1525 s << *j.second;
1526 }
1527 }
1528 else
1529 s << " No loaded schema files\n";
1530
1531 s << "END OF OKS KERNEL DUMP.\n";
1532
1533 return s;
1534}

Member Data Documentation

◆ p_active_data

OksFile* dunedaq::oks::OksKernel::p_active_data
private

Definition at line 2059 of file kernel.hpp.

◆ p_active_schema

OksFile* dunedaq::oks::OksKernel::p_active_schema
private

Definition at line 2058 of file kernel.hpp.

◆ p_allow_duplicated_classes

bool dunedaq::oks::OksKernel::p_allow_duplicated_classes
private

Definition at line 2028 of file kernel.hpp.

◆ p_allow_duplicated_objects

bool dunedaq::oks::OksKernel::p_allow_duplicated_objects
private

Definition at line 2029 of file kernel.hpp.

◆ p_allow_repository

bool dunedaq::oks::OksKernel::p_allow_repository
private

Definition at line 2027 of file kernel.hpp.

◆ p_bind_classes_status

std::string dunedaq::oks::OksKernel::p_bind_classes_status
mutableprivate

Definition at line 2082 of file kernel.hpp.

◆ p_bind_objects_status

std::string dunedaq::oks::OksKernel::p_bind_objects_status
private

Definition at line 2081 of file kernel.hpp.

◆ p_change_object_notify_fn

OksObject::notify_obj dunedaq::oks::OksKernel::p_change_object_notify_fn
private

Definition at line 2166 of file kernel.hpp.

◆ p_change_object_notify_param

void* dunedaq::oks::OksKernel::p_change_object_notify_param
private

Definition at line 2167 of file kernel.hpp.

◆ p_classes

OksClass::Map dunedaq::oks::OksKernel::p_classes
private

Definition at line 2071 of file kernel.hpp.

◆ p_close_all

bool dunedaq::oks::OksKernel::p_close_all
private

Definition at line 2061 of file kernel.hpp.

◆ p_count

unsigned long dunedaq::oks::OksKernel::p_count = 0
staticprivate

Definition at line 2073 of file kernel.hpp.

◆ p_create_object_notify_fn

OksObject::notify_obj dunedaq::oks::OksKernel::p_create_object_notify_fn
private

Definition at line 2163 of file kernel.hpp.

◆ p_create_object_notify_param

void* dunedaq::oks::OksKernel::p_create_object_notify_param
private

Definition at line 2164 of file kernel.hpp.

◆ p_data_files

OksFile::Map dunedaq::oks::OksKernel::p_data_files
private

Definition at line 2056 of file kernel.hpp.

◆ p_delete_object_notify_fn

OksObject::notify_obj dunedaq::oks::OksKernel::p_delete_object_notify_fn
private

Definition at line 2169 of file kernel.hpp.

◆ p_delete_object_notify_param

void* dunedaq::oks::OksKernel::p_delete_object_notify_param
private

Definition at line 2170 of file kernel.hpp.

◆ p_kernel_mutex

std::shared_mutex dunedaq::oks::OksKernel::p_kernel_mutex
mutableprivate

Definition at line 2047 of file kernel.hpp.

◆ p_load_errors

LoadErrors dunedaq::oks::OksKernel::p_load_errors
private

Definition at line 2084 of file kernel.hpp.

◆ p_objects

OksObject::Set dunedaq::oks::OksKernel::p_objects
private

Definition at line 2077 of file kernel.hpp.

◆ p_objects_mutex

std::mutex dunedaq::oks::OksKernel::p_objects_mutex
mutableprivate

Definition at line 2048 of file kernel.hpp.

◆ p_objects_refs_mutex

std::mutex dunedaq::oks::OksKernel::p_objects_refs_mutex
private

Definition at line 2049 of file kernel.hpp.

◆ p_parallel_out_mutex

std::mutex dunedaq::oks::OksKernel::p_parallel_out_mutex
staticprivate

Definition at line 2051 of file kernel.hpp.

◆ p_preload_added_files

std::vector<OksFile *> dunedaq::oks::OksKernel::p_preload_added_files
private

Definition at line 2087 of file kernel.hpp.

◆ p_preload_file_info

std::map<const OksFile *, OksFile *> dunedaq::oks::OksKernel::p_preload_file_info
private

Definition at line 2086 of file kernel.hpp.

◆ p_profiling

bool dunedaq::oks::OksKernel::p_profiling
private

Definition at line 2026 of file kernel.hpp.

◆ p_repository_checkout_ts

std::time_t dunedaq::oks::OksKernel::p_repository_checkout_ts
private

Definition at line 2041 of file kernel.hpp.

◆ p_repository_dirs

std::list<std::string> dunedaq::oks::OksKernel::p_repository_dirs
private

Definition at line 2066 of file kernel.hpp.

◆ p_repository_mapping_dir

std::string dunedaq::oks::OksKernel::p_repository_mapping_dir
staticprivate

Definition at line 2036 of file kernel.hpp.

◆ p_repository_root

std::string dunedaq::oks::OksKernel::p_repository_root
staticprivate

Definition at line 2035 of file kernel.hpp.

◆ p_repository_update_ts

std::time_t dunedaq::oks::OksKernel::p_repository_update_ts
private

Definition at line 2042 of file kernel.hpp.

◆ p_repository_version

std::string dunedaq::oks::OksKernel::p_repository_version
private

Definition at line 2040 of file kernel.hpp.

◆ p_schema_files

OksFile::Map dunedaq::oks::OksKernel::p_schema_files
private

Definition at line 2055 of file kernel.hpp.

◆ p_schema_mutex

std::shared_mutex dunedaq::oks::OksKernel::p_schema_mutex
private

Definition at line 2050 of file kernel.hpp.

◆ p_silence

bool dunedaq::oks::OksKernel::p_silence
private

Definition at line 2024 of file kernel.hpp.

◆ p_skip_string_range

bool dunedaq::oks::OksKernel::p_skip_string_range = false
staticprivate

Definition at line 2032 of file kernel.hpp.

◆ p_test_duplicated_objects_via_inheritance

bool dunedaq::oks::OksKernel::p_test_duplicated_objects_via_inheritance
private

Definition at line 2030 of file kernel.hpp.

◆ p_threads_pool_size

int dunedaq::oks::OksKernel::p_threads_pool_size = 0
staticprivate

Definition at line 2079 of file kernel.hpp.

◆ p_use_strict_repository_paths

bool dunedaq::oks::OksKernel::p_use_strict_repository_paths = true
staticprivate

Definition at line 2033 of file kernel.hpp.

◆ p_user_repository_root

std::string dunedaq::oks::OksKernel::p_user_repository_root
private

Definition at line 2037 of file kernel.hpp.

◆ p_user_repository_root_created

bool dunedaq::oks::OksKernel::p_user_repository_root_created
private

Definition at line 2039 of file kernel.hpp.

◆ p_user_repository_root_inited

bool dunedaq::oks::OksKernel::p_user_repository_root_inited
private

Definition at line 2038 of file kernel.hpp.

◆ p_verbose

bool dunedaq::oks::OksKernel::p_verbose
private

Definition at line 2025 of file kernel.hpp.

◆ profiler

OksProfiler* dunedaq::oks::OksKernel::profiler
private

Definition at line 2075 of file kernel.hpp.

◆ s_cwd

char * dunedaq::oks::OksKernel::s_cwd = nullptr
staticprivate

Definition at line 2068 of file kernel.hpp.


The documentation for this class was generated from the following files: