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 576 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 586 of file kernel.hpp.

Member Enumeration Documentation

◆ RepositoryUpdateType

Enumerator
DiscardChanges 
MergeChanges 
NoChanges 

Definition at line 1590 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 733 of file kernel.cpp.

733 :
734 p_silence (sm),
735 p_verbose (vm),
736 p_profiling (tm),
737 p_allow_repository (allow_repository),
743 p_active_schema (nullptr),
744 p_active_data (nullptr),
745 p_close_all (false),
746 profiler (nullptr),
753{
754 OSK_VERBOSE_REPORT("Enter OksKernel::OksKernel(" << sm << ", " << vm << ", " << tm << ')')
755
756 struct __InitFromEnv__ {
757 const char * name;
758 bool& value;
759 } vars[] = {
760 {"OKS_KERNEL_VERBOSE", p_verbose },
761 {"OKS_KERNEL_SILENCE", p_silence },
762 {"OKS_KERNEL_PROFILING", p_profiling },
763 {"OKS_KERNEL_ALLOW_REPOSITORY", p_allow_repository },
764 {"OKS_KERNEL_ALLOW_DUPLICATED_CLASSES", p_allow_duplicated_classes },
765 {"OKS_KERNEL_ALLOW_DUPLICATED_OBJECTS", p_allow_duplicated_objects },
766 {"OKS_KERNEL_TEST_DUPLICATED_OBJECTS_VIA_INHERITANCE", p_test_duplicated_objects_via_inheritance },
767 {"OKS_KERNEL_SKIP_STRING_RANGE", p_skip_string_range }
768 };
769
770 for(unsigned int i = 0; i < sizeof(vars) / sizeof(__InitFromEnv__); ++i) {
771 if(char * s = getenv(vars[i].name)) {
772 vars[i].value = (strcmp(s, "no")) ? true : false;
773 }
774 }
775
776 {
777 const char * oks_db_root = getenv("OKS_DB_ROOT");
778
779 if (oks_db_root == nullptr || *oks_db_root == 0)
780 oks_db_root = getenv("DUNEDAQ_DB_PATH");
781 else
783
784 OSK_VERBOSE_REPORT("database root = \'" << oks_db_root << "\' (as defined by the OKS_DB_ROOT or DUNEDAQ_DB_PATH)");
785
786
787 // if not defined, set oks_db_root to empty string (to avoid std::string constructor crash when string is 0)
788
789 if (oks_db_root == nullptr)
790 oks_db_root = "";
791
792
793 // temporal set
794
795 Oks::Tokenizer t(oks_db_root, ":");
796 std::string token;
797
798 while (t.next(token))
800 }
801
802
803
804
805 {
806 std::unique_lock lock(p_kernel_mutex);
807
808 if(!p_count++) {
812 }
813
814 get_cwd();
815 }
816
817 {
818 static std::once_flag flag;
819
820 std::call_once(flag, []()
821 {
822 if (char * s = getenv("OKS_KERNEL_THREADS_POOL_SIZE"))
823 {
824 if (*s != '\0')
825 {
826 p_threads_pool_size = atoi(s);
827 if (p_threads_pool_size < 1)
829 }
830 }
831
833 {
834 errno = 0;
835 p_threads_pool_size = sysconf(_SC_NPROCESSORS_ONLN);
836 if (p_threads_pool_size == -1 && !errno)
837 {
838 Oks::error_msg("OksKernel::OksKernel()") << " sysconf(_SC_NPROCESSORS_ONLN) has failed with code " << errno << ": \'" << strerror(errno) << '\'' << std::endl;
840 }
841 }
842
845
846 TLOG_DEBUG(2) << "Threads pool size: " << p_threads_pool_size;
847 }
848 );
849
850 }
851
852 // process OKS server URL settings if any
853 if (p_allow_repository && !get_repository_root().empty())
854 {
855 if (get_user_repository_root().empty())
856 {
857 // parse specific version option if any
858 std::string param, val;
859
860 if (!version)
861 version = getenv("TDAQ_DB_VERSION");
862
863 if (version)
864 {
865 if(*version)
866 {
867 if(const char * value = strchr(version, ':'))
868 {
869 param.assign(version, value-version);
870 val.assign(value+1);
871 }
872 else
873 Oks::error_msg("OksKernel::OksKernel") << "bad version value \"" << version << "\" expecting parameter:value format (check TDAQ_DB_VERSION variable)" << std::endl;
874 }
875 }
876
877 try
878 {
879 std::string tmp_dirname = OksKernel::create_user_repository_dir();
880
881 set_user_repository_root(tmp_dirname);
884
885 if (branch_name.empty())
886 if (const char *var = getenv("TDAQ_DB_BRANCH"))
887 branch_name = var;
888
889 k_checkout_repository(param, val, branch_name);
890 }
891 catch(exception& ex)
892 {
893 Oks::error_msg("OksKernel::OksKernel") << "cannot check out user repository: " << ex.what() << std::endl;
894 }
895 }
896 else
897 {
898 if(!p_silence)
899 {
900 try
901 {
902 std::lock_guard lock(p_parallel_out_mutex);
903 std::cout << "attach to repository \"" << get_user_repository_root() << "\" version " << read_repository_version() << std::endl;
904 }
905 catch(exception& ex)
906 {
907 Oks::error_msg("OksKernel::OksKernel") << "cannot read user repository version: " << ex.what() << std::endl;
908 }
909 }
910 }
911 }
912
913#ifndef ERS_NO_DEBUG
914 if(p_profiling)
915 profiler = (OksProfiler *) new OksProfiler();
916#endif
917}
void insert(const std::string &path)
Definition kernel.cpp:91
static NotifyFN create_notify_fn
Definition class.hpp:966
static NotifyFN delete_notify_fn
Definition class.hpp:968
static ChangeNotifyFN change_notify_fn
Definition class.hpp:967
OksObject::notify_obj p_change_object_notify_fn
Definition kernel.hpp:2161
const std::string & get_user_repository_root() const
Get user OKS repository root.
Definition kernel.cpp:370
static bool p_use_strict_repository_paths
Definition kernel.hpp:2028
static std::mutex p_parallel_out_mutex
Definition kernel.hpp:2046
void set_user_repository_root(const std::string &path, const std::string &version="")
Set user OKS repository root.
Definition kernel.cpp:389
OksProfiler * profiler
Definition kernel.hpp:2070
std::string create_user_repository_dir()
Definition kernel.cpp:2225
OksObject::notify_obj p_delete_object_notify_fn
Definition kernel.hpp:2164
void * p_delete_object_notify_param
Definition kernel.hpp:2165
static int p_threads_pool_size
Definition kernel.hpp:2074
static unsigned long p_count
Definition kernel.hpp:2068
std::string read_repository_version()
Read and return current repository version.
Definition kernel.cpp:5509
std::string p_user_repository_root
Definition kernel.hpp:2032
static bool p_skip_string_range
Definition kernel.hpp:2027
static const std::string & get_repository_root()
Get OKS repository root.
Definition kernel.cpp:304
void * p_change_object_notify_param
Definition kernel.hpp:2162
static const char * get_cwd()
Definition kernel.cpp:689
std::shared_mutex p_kernel_mutex
Definition kernel.hpp:2042
bool p_test_duplicated_objects_via_inheritance
Definition kernel.hpp:2025
OksObject::notify_obj p_create_object_notify_fn
Definition kernel.hpp:2158
std::string insert_repository_dir(const std::string &dir, bool push_back=true)
Insert repository search directory.
Definition kernel.cpp:1398
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:4880
void * p_create_object_notify_param
Definition kernel.hpp:2159
static std::ostream & error_msg(const char *)
Definition kernel.cpp:556
caught dunedaq::conffwk::Exception exception
#define OSK_VERBOSE_REPORT(MSG)
Definition defs.hpp:88
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
const std::string strerror(int error)
Convert C error number to string.
Definition kernel.cpp:114
static GitFoldersHolder s_git_folders
Definition kernel.cpp:110

◆ 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 919 of file kernel.cpp.

919 :
920 p_silence (src.p_silence),
921 p_verbose (src.p_verbose),
922 p_profiling (src.p_profiling),
923 p_allow_repository (src.p_allow_repository),
924 p_allow_duplicated_classes (src.p_allow_duplicated_classes),
925 p_allow_duplicated_objects (src.p_allow_duplicated_objects),
926 p_test_duplicated_objects_via_inheritance (src.p_test_duplicated_objects_via_inheritance),
927 p_user_repository_root (src.p_user_repository_root),
928 p_user_repository_root_inited (src.p_user_repository_root_inited),
930 p_repository_version (src.p_repository_version),
931 p_repository_checkout_ts (src.p_repository_checkout_ts),
932 p_repository_update_ts (src.p_repository_update_ts),
933 p_active_schema (nullptr),
934 p_active_data (nullptr),
935 p_close_all (false),
936 profiler (nullptr),
943{
944
945 {
946 std::unique_lock lock(p_kernel_mutex);
947 p_count++;
948 }
949
950 if (copy_repository && p_user_repository_root_inited)
951 {
952 try
953 {
958 k_copy_repository(src.p_user_repository_root, p_user_repository_root);
959 }
960 catch(exception& ex)
961 {
962 Oks::error_msg("OksKernel::OksKernel") << "cannot copy user repository: " << ex.what() << std::endl;
964 throw;
965 }
966
968 }
969
970
971 // copy repository directories
972 for (const auto& i : src.p_repository_dirs)
973 p_repository_dirs.push_back(i);
974
975
976 // copy schema and data files
977 {
978 const OksFile::Map * src_files[2] = { &src.p_schema_files, &src.p_data_files };
979 OksFile::Map * dst_files[2] = { &p_schema_files, &p_data_files };
980
981 for (int i = 0; i < 2; ++i)
982 {
983 for (const auto& j : *src_files[i])
984 {
985 OksFile * f = new OksFile(*j.second);
986 f->p_kernel = this;
987 (*dst_files[i])[&f->p_full_name] = f;
988 }
989 }
990 }
991
992 // search a class in map is not efficient, if there are many such operations; use array with class index for fast search
993 OksClass ** c_table = new OksClass * [src.p_classes.size()];
994 unsigned int idx(0);
995
996
997 // copy classes: first iteration to define class names and simple properties
998 for(const auto& i : src.p_classes) {
999 const OksClass& src_c(*i.second);
1000 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
1001
1002 c->p_kernel = this;
1003 p_classes[c->get_name().c_str()] = c;
1004
1005 const_cast<OksClass&>(src_c).p_id = idx++;
1006 c->p_id = src_c.p_id;
1007 c_table[c->p_id] = c;
1008
1009 c->p_abstract = src_c.p_abstract;
1010 c->p_to_be_deleted = src_c.p_to_be_deleted;
1011 c->p_instance_size = src_c.p_instance_size;
1012 c->p_file = (*p_schema_files.find(&src_c.p_file->p_full_name)).second;
1013 c->p_objects = (src_c.p_objects ? new OksObject::Map() : nullptr);
1014
1015
1016 // copy super-classes
1017 if (const std::list<std::string *> * scls = src_c.p_super_classes)
1018 {
1019 c->p_super_classes = new std::list<std::string *>();
1020
1021 for (const auto& j : *scls)
1022 c->p_super_classes->push_back(new std::string(*j));
1023 }
1024
1025
1026 // copy direct attributes
1027 if (const std::list<OksAttribute *> * attrs = src_c.p_attributes)
1028 {
1029 c->p_attributes = new std::list<OksAttribute *>();
1030
1031 for (const auto& j : *attrs)
1032 {
1033 OksAttribute * a = new OksAttribute(j->p_name, c);
1034
1035 a->p_range = j->p_range;
1036 a->p_data_type = j->p_data_type;
1037 a->p_multi_values = j->p_multi_values;
1038 a->p_no_null = j->p_no_null;
1039 a->p_init_value = j->p_init_value;
1040 a->p_init_data = j->p_init_data;
1041 a->p_format = j->p_format;
1042 a->p_description = j->p_description;
1043
1044 if (j->p_enumerators)
1045 a->p_enumerators = new std::vector<std::string>(*j->p_enumerators);
1046
1047 c->p_attributes->push_back(a);
1048 }
1049 }
1050
1051
1052 // copy direct relationships
1053 if (const std::list<OksRelationship *> * rels = src_c.p_relationships)
1054 {
1055 c->p_relationships = new std::list<OksRelationship *>();
1056
1057 for (const auto& j : *rels)
1058 {
1059 OksRelationship * r = new OksRelationship(j->p_name, c);
1060
1061 r->p_rclass = j->p_rclass;
1062 r->p_low_cc = j->p_low_cc;
1063 r->p_high_cc = j->p_high_cc;
1064 r->p_composite = j->p_composite;
1065 r->p_exclusive = j->p_exclusive;
1066 r->p_dependent = j->p_dependent;
1067 r->p_description = j->p_description;
1068
1069 c->p_relationships->push_back(r);
1070 }
1071 }
1072
1073
1074 // copy direct methods
1075 if (const std::list<OksMethod *> * mets = src_c.p_methods)
1076 {
1077 c->p_methods = new std::list<OksMethod *>();
1078
1079 for (const auto& j : *mets)
1080 {
1081 OksMethod * m = new OksMethod(j->p_name, j->p_description, c);
1082
1083 if (const std::list<OksMethodImplementation *> * impls = j->p_implementations)
1084 {
1085 m->p_implementations = new std::list<OksMethodImplementation *>();
1086
1087 for (const auto& x : *impls)
1088 m->p_implementations->push_back(new OksMethodImplementation(x->get_language(), x->get_prototype(), x->get_body(), m));
1089 }
1090
1091 c->p_methods->push_back(m);
1092 }
1093 }
1094 }
1095
1096
1097 // copy classes: second iteration to resolve pointers to classes
1098
1099 for (const auto& i : src.p_classes)
1100 {
1101 OksClass * c = c_table[i.second->p_id];
1102
1103 // link p_class_type of relationship
1104 if (const std::list<OksRelationship *> * rels = i.second->p_relationships)
1105 {
1106 for (const auto& j : *rels)
1107 c->find_relationship(j->get_name())->p_class_type = (j->p_class_type ? c_table[j->p_class_type->p_id] : nullptr);
1108 }
1109
1110 // copy all super- and sub- classes
1111 if (const OksClass::FList * spcls = i.second->p_all_super_classes)
1112 {
1113 c->p_all_super_classes = new OksClass::FList();
1114
1115 for (const auto& j : *spcls)
1116 c->p_all_super_classes->push_back(c_table[j->p_id]);
1117 }
1118
1119 if (const OksClass::FList * sbcls = i.second->p_all_sub_classes)
1120 {
1121 c->p_all_sub_classes = new OksClass::FList();
1122
1123 for (const auto& j : *sbcls)
1124 c->p_all_sub_classes->push_back(c_table[j->p_id]);
1125 }
1126
1127 // create oks object layout information
1128 c->p_data_info = new OksDataInfo::Map();
1129 size_t instance_size = 0;
1130
1131 // copy all attributes
1132 if (const std::list<OksAttribute *> * attrs = i.second->p_all_attributes)
1133 {
1134 c->p_all_attributes = new std::list<OksAttribute *>();
1135
1136 for (const auto& j : *attrs)
1137 {
1138 OksAttribute * a = (c_table[j->p_class->p_id])->find_direct_attribute(j->get_name());
1139 c->p_all_attributes->push_back(a);
1140 (*c->p_data_info)[a->get_name()] = new OksDataInfo(instance_size++, a);
1141 }
1142 }
1143
1144 // copy all relationships
1145 if (const std::list<OksRelationship *> * rels = i.second->p_all_relationships)
1146 {
1147 c->p_all_relationships = new std::list<OksRelationship *>();
1148
1149 for (const auto& j : *rels)
1150 {
1151 OksRelationship * r = (c_table[j->p_class->p_id])->find_direct_relationship(j->get_name());
1152 c->p_all_relationships->push_back(r);
1153 (*c->p_data_info)[r->get_name()] = new OksDataInfo(instance_size++, r);
1154 }
1155 }
1156
1157 // copy all methods
1158 if (const std::list<OksMethod *> * mets = i.second->p_all_methods)
1159 {
1160 c->p_all_methods = new std::list<OksMethod *>();
1161
1162 for (const auto& j : *mets)
1163 c->p_all_methods->push_back((c_table[j->p_class->p_id])->find_direct_method(j->get_name()));
1164 }
1165
1166 // copy inheritance hierarchy
1167 if (const std::vector<OksClass *> * ih = i.second->p_inheritance_hierarchy)
1168 {
1169 c->p_inheritance_hierarchy = new std::vector<OksClass *>();
1170 c->p_inheritance_hierarchy->reserve(ih->size());
1171
1172 for (const auto& j : *ih)
1173 c->p_inheritance_hierarchy->push_back(c_table[j->p_id]);
1174 }
1175 }
1176
1177
1178 // copy objects
1179
1180 if(!src.p_objects.empty()) {
1181
1182 // search an object in a class is not efficien, if there are many such operations
1183 // use array with class index for fast search
1184
1185 OksObject ** o_table = new OksObject * [src.p_objects.size()];
1186 idx = 0;
1187
1188 // first iteration: create objects with attributes
1189
1190 for(OksObject::Set::const_iterator i = src.p_objects.begin(); i != src.p_objects.end(); ++i, ++idx) {
1191 OksObject * src_o(*i);
1192 src_o->p_user_data = reinterpret_cast<void *>(idx);
1193
1194 OksClass * c = c_table[src_o->uid.class_id->p_id];
1195
1196 OksObject * o = new OksObject(
1197 c,
1198 src_o->uid.object_id,
1199 src_o->p_user_data,
1200 src_o->p_int32_id,
1201 src_o->p_duplicated_object_id_idx,
1202 (*p_data_files.find(&src_o->file->p_full_name)).second
1203 );
1204
1205 o_table[idx] = o;
1206 (*c->p_objects)[&o->uid.object_id] = o;
1207 p_objects.insert(o);
1208
1209 if(size_t num_of_attrs = c->number_of_all_attributes()) {
1210 const OksData * src_data = src_o->data;
1211 OksData * dst_data = o->data;
1212
1213 std::list<OksAttribute *>::const_iterator ia_dst = c->all_attributes()->begin();
1214 std::list<OksAttribute *>::const_iterator ia_src = src_o->uid.class_id->all_attributes()->begin();
1215
1216 for(size_t j = 0; j < num_of_attrs; ++j) {
1217 *dst_data = *src_data;
1218
1219 OksAttribute * a_dst(*ia_dst);
1220
1221 // process in a special way CLASS type (reference on class)
1222
1223 if(a_dst->get_data_type() == OksData::class_type) {
1224 if(a_dst->get_is_multi_values() == false) {
1225 dst_data->data.CLASS = c_table[src_data->data.CLASS->p_id];
1226 }
1227 else {
1228 OksData::List::iterator li_dst = dst_data->data.LIST->begin();
1229 OksData::List::iterator li_src = src_data->data.LIST->begin();
1230
1231 while(li_dst != dst_data->data.LIST->end()) {
1232 (*li_dst)->data.CLASS = c_table[(*li_src)->data.CLASS->p_id];
1233 ++li_dst;
1234 ++li_src;
1235 }
1236 }
1237 }
1238
1239 // process in a special way ENUM type (reference on attribute's data)
1240
1241 else if(a_dst->get_data_type() == OksData::enum_type) {
1242 OksAttribute * a_src(*ia_src);
1243 const std::string * p_enumerators_first(&((*(a_src->p_enumerators))[0]));
1244
1245 if(a_dst->get_is_multi_values() == false) {
1246 unsigned long dx = src_data->data.ENUMERATION - p_enumerators_first;
1247 dst_data->data.ENUMERATION = &((*(a_dst->p_enumerators))[dx]);
1248 }
1249 else {
1250 OksData::List::iterator li_dst = dst_data->data.LIST->begin();
1251 OksData::List::iterator li_src = src_data->data.LIST->begin();
1252
1253 while(li_dst != dst_data->data.LIST->end()) {
1254 unsigned long dx = (*li_src)->data.ENUMERATION - p_enumerators_first;
1255 (*li_dst)->data.ENUMERATION = &((*(a_dst->p_enumerators))[dx]);
1256 ++li_dst;
1257 ++li_src;
1258 }
1259 }
1260 }
1261
1262 src_data++;
1263 dst_data++;
1264
1265 ia_dst++;
1266 ia_src++;
1267 }
1268 }
1269 }
1270
1271
1272 // second iteration: link relationships of objects
1273
1274 for(const auto& src_o : src.p_objects) {
1275 OksClass * c = c_table[src_o->uid.class_id->p_id];
1276 OksObject * o(o_table[reinterpret_cast<unsigned long>(src_o->p_user_data)]);
1277
1278 if(size_t num_of_rels = c->number_of_all_relationships()) {
1279 const OksData * src_data(src_o->data + c->number_of_all_attributes());
1280 OksData * dst_data(o->data + c->number_of_all_attributes());
1281
1282 for(size_t j = 0; j < num_of_rels; ++j) {
1283 dst_data->type = src_data->type;
1284 switch(src_data->type) {
1285 case OksData::list_type:
1286 dst_data->data.LIST = new OksData::List();
1287 for(const auto& x : *src_data->data.LIST) {
1288 OksData *d = new OksData();
1289
1290 if(x->type == OksData::object_type)
1291 {
1292 if(const OksObject * o2 = x->data.OBJECT)
1293 {
1294 d->Set(o_table[reinterpret_cast<unsigned long>(o2->p_user_data)]);
1295 }
1296 else
1297 {
1298 d->Set((OksObject *)nullptr);
1299 }
1300 }
1301 else if(x->type == OksData::uid_type)
1302 {
1303 d->Set(c_table[x->data.UID.class_id->p_id], *x->data.UID.object_id);
1304 }
1305 else if(x->type == OksData::uid2_type)
1306 {
1307 d->Set(*x->data.UID2.class_id, *x->data.UID2.object_id);
1308 }
1309 else
1310 {
1311 ers::error(kernel::InternalError(ERS_HERE, "unexpected data type in relationship list"));
1312 }
1313
1314 dst_data->data.LIST->push_back(d);
1315 }
1316 break;
1317
1319 if(const OksObject * o2 = src_data->data.OBJECT) {
1320 dst_data->data.OBJECT = o_table[reinterpret_cast<unsigned long>(o2->p_user_data)];
1321 }
1322 else {
1323 dst_data->data.OBJECT = 0;
1324 }
1325 break;
1326
1327 case OksData::uid_type:
1328 dst_data->data.UID.class_id = c_table[src_data->data.UID.class_id->p_id];
1329 dst_data->data.UID.object_id = new OksString(*src_data->data.UID.object_id);
1330 break;
1331
1332 case OksData::uid2_type:
1333 dst_data->data.UID2.class_id = new OksString(*src_data->data.UID2.class_id);
1334 dst_data->data.UID2.object_id = new OksString(*src_data->data.UID2.object_id);
1335 break;
1336
1337 default:
1338 ers::error(kernel::InternalError(ERS_HERE, "unexpected data type in relationship"));
1339 break;
1340 }
1341
1342 src_data++;
1343 dst_data++;
1344 }
1345 }
1346
1347 if (const std::list<OksRCR *> * src_rcrs = src_o->p_rcr)
1348 {
1349 o->p_rcr = new std::list<OksRCR *>();
1350
1351 for (const auto& j : *src_rcrs)
1352 o->p_rcr->push_back(
1353 new OksRCR(
1354 o_table[reinterpret_cast<unsigned long>(j->obj->p_user_data)],
1355 (c_table[j->relationship->p_class->p_id])->find_direct_relationship(j->relationship->get_name())
1356 )
1357 );
1358 }
1359 else
1360 {
1361 o->p_rcr = nullptr;
1362 }
1363 }
1364
1365 delete [] o_table;
1366 }
1367
1368 delete [] c_table;
1369
1370 // rename all files
1371 if (copy_repository && p_user_repository_root_inited)
1372 {
1373 OksFile::Map * files_map[2] = { &p_schema_files, &p_data_files };
1374
1375 for (int i = 0; i < 2; ++i)
1376 {
1377 std::vector<OksFile *> files;
1378
1379 for (auto& f : *files_map[i])
1380 files.push_back(f.second);
1381
1382 files_map[i]->clear();
1383
1384 for (auto& f : files)
1385 {
1386 std::string name = p_user_repository_root;
1387 name.push_back('/');
1388 name.append(f->get_repository_name());
1389 f->rename(name);
1390 (*files_map[i])[&f->p_full_name] = f;
1391 }
1392 }
1393 }
1394}
#define ERS_HERE
std::list< OksClass *, boost::fast_pool_allocator< OksClass * > > FList
Definition class.hpp:235
std::map< const std::string *, OksFile *, SortByName > Map
Definition file.hpp:367
friend class OksClass
Definition kernel.hpp:580
std::string p_repository_version
Definition kernel.hpp:2035
std::time_t p_repository_checkout_ts
Definition kernel.hpp:2036
OksClass::Map p_classes
Definition kernel.hpp:2066
OksFile::Map p_schema_files
Definition kernel.hpp:2050
friend struct OksData
Definition kernel.hpp:583
std::list< std::string > p_repository_dirs
Definition kernel.hpp:2061
void remove_user_repository_dir()
Definition kernel.cpp:4941
std::time_t p_repository_update_ts
Definition kernel.hpp:2037
void k_copy_repository(const std::string &source, const std::string &destination)
Definition kernel.cpp:4959
friend class OksFile
Definition kernel.hpp:579
friend class OksObject
Definition kernel.hpp:581
OksObject::Set p_objects
Definition kernel.hpp:2072
OksFile::Map p_data_files
Definition kernel.hpp:2051
std::unordered_map< const std::string *, OksObject *, oks::hash_str, oks::equal_str > Map
Definition object.hpp:865
static bool real_path(std::string &, bool ignore_errors)
Definition kernel.cpp:594
void error(const Issue &issue)
Definition ers.hpp:81
std::map< std::string, OksDataInfo * > Map
Declare map of pointers to OksDataInfo (unsorted by name)
Definition object.hpp:346
std::list< OksData *, boost::fast_pool_allocator< OksData * > > List
Definition object.hpp:455

◆ ~OksKernel()

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

Definition at line 1459 of file kernel.cpp.

1460{
1461 {
1464
1467
1468 std::unique_lock lock(p_kernel_mutex);
1469
1470 p_classes.erase(p_classes.begin(), p_classes.end());
1471
1472 --p_count;
1473
1474 if(p_count == 0) {
1475 std::lock_guard scoped_lock(s_get_cwd_mutex);
1476 delete [] s_cwd;
1477 s_cwd = nullptr;
1478 }
1479
1481 }
1482
1483#ifndef ERS_NO_DEBUG
1484 if(p_profiling) std::cout << *profiler << std::endl;
1485#endif
1486
1487 OSK_VERBOSE_REPORT("LEAVE OksKernel::~OksKernel()")
1488}
static char * s_cwd
Definition kernel.hpp:2063
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:733
void close_all_data()
Close all OKS data files.
Definition kernel.cpp:4243
void close_all_schema()
Close all OKS schema files.
Definition kernel.cpp:2883
#define OSK_PROFILING(FID, K)
Definition defs.hpp:97
static std::mutex s_get_cwd_mutex
Definition kernel.cpp:52

Member Function Documentation

◆ add_data_file()

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

Definition at line 3767 of file kernel.cpp.

3768{
3769 p_data_files[&f->p_full_name] = f;
3770}

◆ add_schema_file()

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

Definition at line 3773 of file kernel.cpp.

3774{
3775 p_schema_files[&f->p_full_name] = f;
3776}

◆ 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 3808 of file kernel.cpp.

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

◆ 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 2554 of file kernel.cpp.

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

◆ 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 4361 of file kernel.cpp.

4362{
4363 std::unique_lock lock(p_kernel_mutex);
4365}

◆ 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 1532 of file kernel.cpp.

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

◆ 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 1767 of file kernel.hpp.

1767{return p_classes;}

◆ clear_preload_file_info()

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

Definition at line 3525 of file kernel.cpp.

3526{
3527 for(std::map<const OksFile *, OksFile *>::iterator i = p_preload_file_info.begin(); i != p_preload_file_info.end(); ++i) {
3528 delete i->second;
3529 }
3530
3531 p_preload_file_info.clear();
3532 p_preload_added_files.clear();
3533}
std::vector< OksFile * > p_preload_added_files
Definition kernel.hpp:2082
std::map< const OksFile *, OksFile * > p_preload_file_info
Definition kernel.hpp:2081

◆ 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 4243 of file kernel.cpp.

4244{
4245 TLOG_DEBUG(4) << "enter";
4246
4247 {
4248 std::unique_lock lock(p_kernel_mutex);
4249
4250 p_close_all = true;
4251
4252 while(!p_data_files.empty()) {
4253 k_close_data(p_data_files.begin()->second, false);
4254 }
4255
4256 if(!p_objects.empty()) {
4257 for(OksObject::Set::iterator i = p_objects.begin(); i != p_objects.end(); ++i) {
4258 delete *i;
4259 }
4260
4261 p_objects.clear();
4262
4263 for(OksClass::Map::const_iterator i = p_classes.begin(); i != p_classes.end(); ++i) {
4264 if(i->second->p_objects) {
4265 delete i->second->p_objects;
4266 i->second->p_objects = 0;
4267 }
4268 }
4269 }
4270
4271 p_close_all = false;
4272 }
4273
4274 TLOG_DEBUG(4) << "exit";
4275}
void k_close_data(OksFile *, bool)
Definition kernel.cpp:4192

◆ 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 2883 of file kernel.cpp.

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

◆ 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 4183 of file kernel.cpp.

4184{
4185 std::unique_lock lock(p_kernel_mutex);
4186 k_close_data(fp, unbind);
4187}

◆ 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 2820 of file kernel.cpp.

2821{
2822 std::unique_lock lock(p_kernel_mutex);
2823 k_close_schema(pf);
2824}

◆ 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 5057 of file kernel.cpp.

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

◆ 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 1568 of file kernel.cpp.

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

◆ 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 4327 of file kernel.cpp.

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

◆ 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 2950 of file kernel.cpp.

2951{
2952 std::string fname("OksKernel::create_list_of_schema_classes(");
2953 fname.append(pf->get_full_file_name());
2954 fname.push_back('\'');
2955
2957 OSK_VERBOSE_REPORT("ENTER " << fname)
2958
2959 std::list<OksClass *> * clist = nullptr;
2960
2961 if(!p_classes.empty()) {
2962 for(OksClass::Map::const_iterator i = p_classes.begin(); i != p_classes.end(); ++i) {
2963 if(pf == i->second->p_file) {
2964 if(!clist && !(clist = new std::list<OksClass *>())) {
2965 return 0;
2966 }
2967
2968 clist->push_back(i->second);
2969 }
2970 }
2971 }
2972
2973 OSK_VERBOSE_REPORT("LEAVE " << fname)
2974
2975 return clist;
2976}

◆ 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 3009 of file kernel.cpp.

3010{
3011 std::shared_lock lock(p_kernel_mutex);
3012
3014}
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:2981

◆ 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 3001 of file kernel.cpp.

3002{
3003 std::shared_lock lock(p_kernel_mutex);
3004
3006}

◆ create_user_repository_dir()

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

Definition at line 2225 of file kernel.cpp.

2226{
2227 if (const char * path = getenv("TDAQ_DB_USER_REPOSITORY_PATH"))
2228 return path;
2229
2230 // create user repository directory if necessary
2231 std::string user_repo;
2232
2233 if (const char * user_repo_base = getenv("TDAQ_DB_USER_REPOSITORY_ROOT"))
2234 user_repo = user_repo_base;
2235 else
2236 user_repo = get_temporary_dir();
2237
2238 user_repo.push_back('/');
2239 if (const char * user_repo_pattern = getenv("TDAQ_DB_USER_REPOSITORY_PATTERN"))
2240 user_repo.append(user_repo_pattern);
2241 else
2242 user_repo.append("oks.XXXXXX");
2243
2244 std::unique_ptr<char[]> dir_template(new char[user_repo.size() + 1]);
2245 strcpy(dir_template.get(), user_repo.c_str());
2246
2247 if (char * tmp_dirname = mkdtemp(dir_template.get()))
2248 {
2249 return tmp_dirname;
2250 }
2251
2252 throw CanNotCreateRepositoryDir("make_user_repository_dir", user_repo);
2253}

◆ 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 1493 of file kernel.hpp.

1493{return p_data_files;}

◆ define()

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

Definition at line 2148 of file kernel.hpp.

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

◆ 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 4451 of file kernel.cpp.

4452{
4453 OksClass::Map::const_iterator i = p_classes.find(name);
4454 return (i != p_classes.end() ? i->second : 0);
4455}

◆ 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 1814 of file kernel.hpp.

1814{ 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:1814

◆ 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 2287 of file kernel.cpp.

2288{
2289 return find_file(s, p_data_files);
2290}
OksFile * find_file(const std::string &s, const OksFile::Map &files) const
Definition kernel.cpp:2257

◆ find_file()

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

Definition at line 2257 of file kernel.cpp.

2258{
2259 try {
2260 std::string at = get_file_path(s, nullptr);
2261 OksFile::Map::const_iterator i = files.find(&at);
2262 if(i != files.end()) return (*i).second;
2263 }
2264 catch (...) {
2265 // return 0;
2266 }
2267
2268 // search files included as relative to parent
2269 for(const auto& f : files)
2270 {
2271 if (s == f.second->get_short_file_name())
2272 {
2273 return f.second;
2274 }
2275 }
2276
2277 return nullptr;
2278}
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:1660

◆ 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 2281 of file kernel.cpp.

2282{
2283 return find_file(s, p_schema_files);
2284}

◆ 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 1481 of file kernel.hpp.

1481{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 1210 of file kernel.hpp.

1210{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 4675 of file kernel.cpp.

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

◆ 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 730 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 741 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 2007 of file kernel.hpp.

2007{ return p_bind_classes_status; }
std::string p_bind_classes_status
Definition kernel.hpp:2077

◆ 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 1995 of file kernel.hpp.

1995{ return p_bind_objects_status; }
std::string p_bind_objects_status
Definition kernel.hpp:2076

◆ get_cwd()

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

Definition at line 689 of file kernel.cpp.

690{
691 std::lock_guard scoped_lock(s_get_cwd_mutex);
692
693 if (!s_cwd)
694 {
695 errno = 0;
696 long size = pathconf(".", _PC_PATH_MAX);
697 if (errno)
698 {
699 Oks::error_msg("OksKernel::OksKernel") << "pathconf(\".\", _PC_PATH_MAX) has failed with code " << errno << ": \'" << strerror(errno) << '\'' << std::endl;
700 }
701 else
702 {
703 if (size == -1)
704 {
705 size = PATH_MAX;
706 }
707 s_cwd = new char[size];
708 if (!getcwd(s_cwd, (size_t) size))
709 {
710 Oks::error_msg("OksKernel::OksKernel") << "getcwd() has failed with code " << errno << ": \'" << strerror(errno) << '\'' << std::endl;
711 delete[] s_cwd;
712 s_cwd = 0;
713 }
714 }
715
716 if (!s_cwd)
717 {
718 s_cwd = new char[2];
719 s_cwd[0] = '/';
720 s_cwd[1] = 0;
721 }
722
723 TLOG_DEBUG(1) << "Current working dir: \'" << s_cwd << '\'';
724 }
725
726 return s_cwd;
727}
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 447 of file kernel.cpp.

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

◆ 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 1660 of file kernel.cpp.

1661{
1662 strict_paths &= p_use_strict_repository_paths;
1663
1664 const char _fname[] = "get_file_path";
1665 std::string fname;
1666
1667 TLOG_DEBUG(2) << "ENTER " << make_fname(_fname, sizeof(_fname)-1, s, nullptr, &file_h);
1668
1669 std::list<std::string> tested_files;
1670
1671 // check absolute path or path relative to working directory
1672 bool is_absolute_path = false;
1673
1674 std::string s2(s);
1676 fname = make_fname(_fname, sizeof(_fname) - 1, s2, nullptr, &file_h);
1677
1678 // test if file has an absolute path
1679 if (s2[0] == '/')
1680 is_absolute_path = true;
1681
1682 // continue only if the file is an absolute path or it is not included
1683 if (is_absolute_path || file_h == 0)
1684 {
1685 if (!is_absolute_path && s_cwd && *s_cwd)
1686 {
1687 std::string s3 = s_cwd;
1688 s3.push_back('/');
1689 s2 = s3 + s2;
1690 }
1691
1692 if (Oks::real_path(s2, true))
1693 {
1694 if (!get_user_repository_root().empty() && strict_paths)
1695 {
1696 if (!get_repository_mapping_dir().empty() && s2.find(get_repository_mapping_dir()) == 0)
1697 {
1698 s2.erase(0, get_repository_mapping_dir().size()+1);
1700 }
1701 else if (s2.find(get_user_repository_root()) == 0)
1702 {
1703 // presumably from explicitly set TDAQ_DB_USER_REPOSITORY created externally
1704 TLOG_DEBUG(2) << fname << " returns external \'" << s2 << "\' (an absolute filename or relative to CWD=\'" << s_cwd << "\')";
1705 return s2;
1706 }
1707
1708 std::ostringstream text;
1709 text << fname << " file does not belong to oks git repository\n"
1710 "provide file repository name, or unset TDAQ_DB_REPOSITORY and try again with the DUNEDAQ_DB_PATH environment variable";
1711 throw std::runtime_error(text.str().c_str());
1712 }
1713 else
1714 {
1715 TLOG_DEBUG(2) << fname << " returns \'" << s2 << "\' (an absolute filename or relative to CWD=\'" << s_cwd << "\')";
1716 return s2;
1717 }
1718 }
1719 else
1720 {
1721 if (is_absolute_path)
1722 {
1723 const char _test_name[] = "an absolute file name";
1724 tested_files.push_back(mk_name_and_test(s2, _test_name, sizeof(_test_name) - 1));
1725 }
1726 else
1727 {
1728 const char _test_name[] = "relative to current working directory";
1729 tested_files.push_back(mk_name_and_test(s2, _test_name, sizeof(_test_name) - 1));
1730 }
1731 }
1732 }
1733
1734 if( !get_user_repository_root().empty())
1735 {
1737 }
1738
1740 {
1741 // check paths relative to OKS database root directories
1742 if (!is_absolute_path)
1743 for (auto & i : p_repository_dirs)
1744 {
1745 TEST_PATH_TOKEN(i, s, "DUNEDAQ_DB_PATH")
1746 }
1747
1748 // check non-absolute path relative to parent file if any
1749 if (file_h && !is_absolute_path)
1750 {
1751 std::string s2(file_h->get_full_file_name());
1752 std::string::size_type pos = s2.find_last_of('/');
1753
1754 if (pos != std::string::npos)
1755 {
1756 s2.erase(pos + 1);
1757 s2.append(s);
1759
1760 if (Oks::real_path(s2, true))
1761 {
1762 TLOG_DEBUG(2) << fname << " returns \'" << s2 << "\' (filename relative to parent file)";
1763 return s2;
1764 }
1765 else
1766 {
1767 const char _test_name[] = "relative to parent file";
1768 tested_files.push_back(mk_name_and_test(s2, _test_name, sizeof(_test_name) - 1));
1769 }
1770 }
1771 }
1772 }
1773
1774 TLOG_DEBUG(2) << fname << " throw exception (file was not found)";
1775
1776 std::ostringstream text;
1777 text << fname << " found no readable file among " << tested_files.size() << " tested:\n";
1778 for (auto & i : tested_files)
1779 text << i << std::endl;
1780
1781 throw std::runtime_error(text.str().c_str());
1782}
static const std::string & get_repository_mapping_dir()
Get OKS repository name.
Definition kernel.cpp:350
static void substitute_variables(std::string &)
Definition kernel.cpp:570
#define TEST_PATH_TOKEN(path, file, msg)
Definition kernel.cpp:1644
std::string mk_name_and_test(const std::string &name, const char *test, size_t test_len)
Definition kernel.cpp:1635

◆ get_host_name()

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

Get hostname of given process.

Definition at line 429 of file kernel.cpp.

430{
431 static std::string s_host_name;
432 static std::once_flag flag;
433
434 std::call_once(flag, []()
435 {
437
438 if (s_host_name.empty())
439 s_host_name = "unknown.host";
440 }
441 );
442
443 return s_host_name;
444}
static const std::string & full_local_name()
fully qualified local host name
Definition Host.cpp:211
static const LocalHost * instance()
pointer to the singleton local host
Definition Host.cpp:221

◆ 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 1914 of file kernel.cpp.

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

◆ 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 3017 of file kernel.cpp.

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

◆ 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 820 of file kernel.hpp.

820{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 708 of file kernel.hpp.

708{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 1584 of file kernel.hpp.

1585 {
1587 }

◆ 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 1545 of file kernel.hpp.

1545{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 350 of file kernel.cpp.

351{
352 static std::once_flag flag;
353
354 std::call_once(flag, []()
355 {
356 if (const char * s = getenv("OKS_REPOSITORY_MAPPING_DIR"))
357 {
360 }
361 }
362 );
363
365}
static std::string p_repository_mapping_dir
Definition kernel.hpp:2031

◆ 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 304 of file kernel.cpp.

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

◆ 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 1646 of file kernel.hpp.

1647 {
1648 return get_repository_versions_diff("", "");
1649 }

◆ get_repository_version()

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

Definition at line 936 of file kernel.hpp.

937 {
939 }

◆ 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 5329 of file kernel.cpp.

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

◆ 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 5486 of file kernel.cpp.

5487{
5488 std::string command_line;
5489
5490 if(!since.empty())
5491 {
5492 command_line.append(" --since ");
5493 command_line.append(replace_datetime_spaces(since));
5494 }
5495
5496 if(!until.empty())
5497 {
5498 command_line.append(" --until ");
5499 command_line.append(replace_datetime_spaces(until));
5500 }
5501
5502 command_line.append(" origin/master");
5503
5504 return get_repository_versions(skip_irrelevant, command_line);
5505}
std::vector< OksRepositoryVersion > get_repository_versions(bool skip_irrelevant, const std::string &command_line)
Return repository versions.
Definition kernel.cpp:5329
static std::string replace_datetime_spaces(const std::string &in)
Definition kernel.cpp:5477

◆ 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 5450 of file kernel.cpp.

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

◆ 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 5249 of file kernel.cpp.

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

◆ 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 686 of file kernel.hpp.

686{return p_silence;}

◆ get_skip_string_range()

static 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 799 of file kernel.hpp.

799{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 765 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 665 of file kernel.cpp.

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

◆ 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 5546 of file kernel.cpp.

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

◆ get_user_name()

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

Get username of given process.

Definition at line 468 of file kernel.cpp.

469{
470 static std::string s_user_name;
471 static std::once_flag flag;
472
473 std::call_once(flag, []()
474 {
475 OksSystem::User myself;
476 s_user_name = myself.name_safe();
477
478 if (s_user_name.empty())
479 s_user_name = "unknown.user";
480 }
481 );
482
483 return s_user_name;
484}
const std::string & name_safe() const
username - no exception
Definition User.cpp:204

◆ 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 370 of file kernel.cpp.

371{
373 {
374 OksKernel * k(const_cast<OksKernel*>(this));
376 if(const char * s = getenv("TDAQ_DB_USER_REPOSITORY")) {
377 if(s[0] != 0) {
378 k->set_user_repository_root(s);
379 }
380 }
381 k->p_user_repository_root_inited = true;
382 }
383 }
384
386}

◆ 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 665 of file kernel.hpp.

665{return p_verbose;}

◆ GetOksProfiler()

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

Definition at line 614 of file kernel.hpp.

614{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 297 of file kernel.cpp.

298{
299 return "862f2957270";
300}

◆ 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 1398 of file kernel.cpp.

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

◆ 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 4638 of file kernel.cpp.

4639{
4642
4643 bool not_found = true;
4644
4645 {
4646 if(!p_classes.empty()) {
4647 for(OksClass::Map::const_iterator i = p_classes.begin(); i != p_classes.end(); ++i) {
4648 if(i->second == c) {
4649 not_found = false;
4650 break;
4651 }
4652 }
4653 }
4654 }
4655
4656 if(p_verbose) {
4657 std::string fname("OksKernel::is_dangling(");
4658
4659 if(not_found)
4660 fname += "?class?) returns true";
4661 else {
4662 fname += '\"';
4663 fname += c->get_name();
4664 fname += "\") returns false";
4665 }
4666
4667 OSK_VERBOSE_REPORT("LEAVE " << fname.c_str())
4668 }
4669
4670 return not_found;
4671}
bool is_dangling(OksClass *class_ptr) const
Check pointer on oks class.
Definition kernel.cpp:4638

◆ 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 4607 of file kernel.cpp.

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

◆ is_user_repository_created()

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

Definition at line 942 of file kernel.hpp.

943 {
945 }

◆ k_add()

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

Definition at line 4459 of file kernel.cpp.

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

◆ k_bind_objects()

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

Definition at line 4368 of file kernel.cpp.

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

◆ k_check_bind_classes_status()

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

Definition at line 5710 of file kernel.cpp.

5711{
5712 std::ostringstream out;
5713
5714 for (auto & c : p_classes)
5715 c.second->check_relationships(out, true);
5716
5717 p_bind_classes_status = out.str();
5718}
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 4880 of file kernel.cpp.

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

◆ 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 1961 of file kernel.cpp.

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

◆ k_close_data()

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

Definition at line 4192 of file kernel.cpp.

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

◆ k_close_schema()

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

Definition at line 2829 of file kernel.cpp.

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

◆ k_copy_repository()

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

Definition at line 4959 of file kernel.cpp.

4960{
4961 std::string cmd("oks-copy.sh");
4962
4963 if (get_verbose_mode())
4964 cmd.append(" -v");
4965
4966 cmd.append(" -s ");
4967 cmd.append(source);
4968
4969 cmd.append(" -d ");
4970 cmd.append(destination);
4971
4972 cmd.append(" -c ");
4973 cmd.append(get_repository_version());
4974
4975 auto start_usage = std::chrono::steady_clock::now();
4976
4977 if(!p_silence) {
4978 std::lock_guard lock(p_parallel_out_mutex);
4979 log_timestamp() << "[OKS copy] => " << cmd << std::endl;
4980 }
4981
4982 CommandOutput cmd_out("oks-copy", this, cmd);
4983 cmd_out.check_command_status(system(cmd.c_str()));
4984
4985 if(!p_silence) {
4986 std::lock_guard lock(p_parallel_out_mutex);
4987 std::cout << cmd_out.cat2str();
4988 log_timestamp() << "[OKS copy] => done in " << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now()-start_usage).count() / 1000. << " ms" << std::endl;
4989 }
4990}

◆ 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 3569 of file kernel.cpp.

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

◆ 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 3650 of file kernel.cpp.

3651{
3653
3654 fp->p_included_by = parent_h;
3655 check_read_only(fp);
3656
3657 try {
3658 if(!p_silence) {
3659 std::lock_guard lock(p_parallel_out_mutex);
3660 std::cout << (parent_h ? " * r" : "R") << "eading data file \"" << fp->get_full_file_name()
3661 << "\" in " << (format == 'n' ? "normal" : (format == 'X' ? "extended" : "compact")) << " format (" << file_length << " bytes)...\n";
3662 if(parent_h == 0 && fp->get_full_file_name() != fp->get_short_file_name()) {
3663 std::cout << "(non-fully-qualified filename was \"" << fp->get_short_file_name() << "\")\n";
3664 }
3665 }
3666
3667 fp->update_status_of_file();
3668 add_data_file(fp);
3669
3670 {
3671 std::unique_ptr<OksPipeline> pipeline_guard(pipeline ? 0 : new OksPipeline(p_threads_pool_size));
3672
3673 OksPipeline * m_pipeline;
3674
3675 if(pipeline) {
3676 m_pipeline = pipeline;
3677 }
3678 else {
3679 m_pipeline = pipeline_guard.get();
3681 }
3682
3683 k_load_includes(*fp, m_pipeline);
3684
3685
3686 if(p_threads_pool_size > 1) {
3687 m_pipeline->addJob( new OksLoadObjectsJob( this, fp, xmls, format) );
3688 }
3689 else {
3690 OksLoadObjectsJob job(this, fp, xmls, format);
3691 job.run();
3692 }
3693 }
3694
3695 if(!pipeline) {
3696 if(!p_load_errors.is_empty()) {
3697 throw (FailedLoadFile("data file", fp->get_full_file_name(), p_load_errors.get_text()));
3698 }
3699
3700 if(bind) {
3702 }
3703 }
3704 }
3705 catch (FailedLoadFile&) {
3706 throw;
3707 }
3708 catch (exception& e) {
3709 throw (FailedLoadFile("data file", fp->get_full_file_name(), e));
3710 }
3711 catch (std::exception& e) {
3712 throw (FailedLoadFile("data file", fp->get_full_file_name(), e.what()));
3713 }
3714}
friend struct OksLoadObjectsJob
Definition kernel.hpp:582
void add_data_file(OksFile *)
Definition kernel.cpp:3767
void k_load_includes(const OksFile &, OksPipeline *)
Definition kernel.cpp:1880
std::string get_text()
Definition kernel.cpp:3084

◆ 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 1798 of file kernel.cpp.

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

◆ k_load_includes()

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

Definition at line 1880 of file kernel.cpp.

1881{
1882 for(std::list<std::string>::const_iterator i = f.p_list_of_include_files.begin(); i != f.p_list_of_include_files.end(); ++i) {
1883 if(!(*i).empty()) {
1884 //if(f.get_repository() != OksFile::NoneRepository) {
1885 if(!get_user_repository_root().empty()) {
1886 if((*i)[0] == '/') {
1887 throw FailedLoadFile("include", *i, "inclusion of files with absolute pathname (like \"/foo/bar\") is not allowed by repository files; include files relative to repository root (like \"foo/bar\")");
1888 }
1889 else if((*i)[0] == '.') {
1890 throw FailedLoadFile("include", *i, "inclusion of files with file-related relative pathnames (like \"../foo/bar\" or \"./bar\") is not supported by repository files; include files relative to repository root (like \"foo/bar\")");
1891 }
1892 else if((*i).find('/') == std::string::npos) {
1893 throw FailedLoadFile("include", *i, "inclusion of files with file-related local pathnames (like \"bar\") is not supported by repository files; include files relative to repository root (like \"foo/bar\")");
1894 }
1895 }
1896
1897 try {
1898 k_load_file(*i, false, &f, pipeline);
1899 }
1900 catch (exception & e) {
1901 throw FailedLoadFile("include", *i, e);
1902 }
1903 catch (std::exception & e) {
1904 throw FailedLoadFile("include", *i, e.what());
1905 }
1906 }
1907 else {
1908 throw FailedLoadFile("include", *i, "empty filename");
1909 }
1910 }
1911}
OksFile * k_load_file(const std::string &name, bool bind, const OksFile *parent, OksPipeline *pipeline)
Definition kernel.cpp:1798

◆ 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 2306 of file kernel.cpp.

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

◆ 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 2374 of file kernel.cpp.

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

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

◆ k_remove()

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

Definition at line 4488 of file kernel.cpp.

4489{
4490 TLOG_DEBUG(4) << "enter for class \"" << c->get_name() << '\"';
4491
4492 if(OksClass::delete_notify_fn) (*OksClass::delete_notify_fn)(c);
4493
4494 p_classes.erase(c->get_name().c_str());
4495}

◆ 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 4110 of file kernel.cpp.

4111{
4112 remove_data_file(pf);
4113 pf->rename(short_name, long_name);
4114 add_data_file(pf);
4115}

◆ k_rename_repository_file()

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

Definition at line 4862 of file kernel.cpp.

4863{
4864 if (file_h->p_oks_format == "schema")
4865 {
4866 remove_schema_file(file_h);
4867 file_h->rename(new_name);
4868 add_schema_file(file_h);
4869 }
4870 else
4871 {
4872 remove_data_file(file_h);
4873 file_h->rename(new_name);
4874 add_data_file(file_h);
4875 }
4876}

◆ 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 2746 of file kernel.cpp.

2747{
2749 pf->rename(short_name, long_name);
2750 add_schema_file(pf);
2751}

◆ 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 3849 of file kernel.cpp.

3850{
3851 const char _fname[] = "k_save_data";
3852 std::string fname = make_fname(_fname, sizeof(_fname)-1, pf->p_full_name, nullptr, nullptr);
3853
3855 OSK_VERBOSE_REPORT("ENTER " << fname)
3856
3857 std::string tmp_file_name;
3858
3859 if(!fh) fh = pf;
3860
3861 try {
3862
3863 // calculate number of objects in file and check objects
3864
3865 size_t numberOfObjects = 0;
3866
3867 if(objects) {
3868 numberOfObjects = objects->size();
3869
3870 if(!ignoreBadObjects) {
3871 std::string errors;
3872
3873 for(OksObject::FSet::const_iterator i = objects->begin(); i != objects->end(); ++i) {
3874 errors += (*i)->report_dangling_references();
3875 }
3876
3877 if(!errors.empty()) {
3878 std::ostringstream text;
3879 text << "the file contains objects with dangling references:\n" << errors;
3880 throw std::runtime_error(text.str().c_str());
3881 }
3882 }
3883 }
3884 else {
3885 // get list of all includes
3886
3887 std::set<OksFile *> includes;
3888 pf->get_all_include_files(this, includes);
3889
3890 OSK_VERBOSE_REPORT("Test consistency of objects in file \"" << pf->p_full_name << '\"')
3891
3892 bool found_bad_object = false;
3893
3894 for(OksObject::Set::iterator i = p_objects.begin(); i != p_objects.end(); ++i) {
3895 if((*i)->file == fh) {
3896 numberOfObjects++;
3897 if(!ignoreBadObjects || !p_silence) {
3898 if((*i)->is_consistent(includes, "WARNING") == false) {
3899 found_bad_object = true;
3900 }
3901 if((*i)->is_duplicated() == true) {
3902 if(!p_silence) {
3903 Oks::error_msg(fname) << " The file contains duplicated object " << *i << std::endl;
3904 }
3905 found_bad_object = true;
3906 }
3907 }
3908 }
3909 }
3910
3911 if(found_bad_object && ignoreBadObjects == false) {
3912 throw std::runtime_error("the file contains inconsistent/duplicated objects or misses includes");
3913 }
3914 }
3915
3916
3917 // lock the file, if it is not locked already
3918
3919 if(pf->is_locked() == false) {
3920 pf->lock();
3921 }
3922
3923
3924 // check if it possible to open the non-existent file in write mode
3925
3926 {
3927 // check first if file already exists
3928
3929 std::fstream f(pf->p_full_name.c_str(), std::ios::in);
3930
3931 if(!f) {
3932
3933 // no check for non-existent file
3934
3935 std::fstream f2(pf->p_full_name.c_str(), std::ios::out);
3936
3937 if(!f2) {
3938 std::ostringstream text;
3939 text << "cannot open file \'" << pf->p_full_name << "\' for writing";
3940 throw std::runtime_error(text.str().c_str());
3941 }
3942 }
3943 }
3944
3945
3946 tmp_file_name = get_tmp_file(pf->p_full_name);
3947
3948 long file_len = 0;
3949
3950 {
3951 std::ofstream f(tmp_file_name.c_str());
3952
3953 f.exceptions ( std::ostream::failbit | std::ostream::badbit );
3954
3955 if(!f) {
3956 std::ostringstream text;
3957 text << "cannot create temporal file \'" << tmp_file_name << "\' to save data";
3958 throw std::runtime_error(text.str().c_str());
3959 }
3960 else {
3961 if(!p_silence) {
3962 std::lock_guard lock(p_parallel_out_mutex);
3963 std::cout << "Saving " << numberOfObjects << " objects " << (force_defaults ? "with enforced default values " : "") << "to data file \"" << pf->p_full_name << "\"...\n";
3964 }
3965 }
3966
3967
3968 // set header parameters
3969
3970 OksXmlOutputStream xmls(f);
3971
3972 pf->p_number_of_items = numberOfObjects;
3973 pf->p_oks_format = "data";
3974
3975 pf->write(xmls);
3976
3977 if(!p_objects.empty()) {
3978 for(OksClass::Map::const_iterator i = p_classes.begin(); i != p_classes.end() && f.good(); ++i) {
3979 OksObject::SMap sorted;
3980
3981 for(OksObject::Map::const_iterator j = i->second->p_objects->begin(); j != i->second->p_objects->end(); ++j) {
3982 if(j->second->file == fh || (objects && (objects->find(j->second) != objects->end()))) {
3983 sorted[j->first] = j->second;
3984 }
3985 }
3986
3987 for(OksObject::SMap::iterator j = sorted.begin(); j != sorted.end(); ++j) {
3988 j->second->put(xmls, force_defaults);
3989 xmls.put_raw('\n');
3990 }
3991 }
3992 }
3993
3994 xmls.put_last_tag("oks-data", sizeof("oks-data")-1);
3995 file_len = f.tellp();
3996
3997 f.close();
3998 }
3999
4000
4001 // check that the written file is OK
4002 // FIXME: can be removed later, if exceptions work well enough
4003
4004 {
4005 long written_len = 0;
4006
4007 std::shared_ptr<std::ifstream> f(new std::ifstream(tmp_file_name.c_str()));
4008
4009 if(*f) {
4010 f->seekg(0, std::ios::end);
4011 written_len = static_cast<std::streamoff>(f->tellg());
4012 }
4013
4014 if(written_len != file_len) {
4015 unlink(tmp_file_name.c_str());
4016 std::ostringstream text;
4017 text << "write error in file \'" << tmp_file_name << "\': " << written_len << " bytes been written instead of " << file_len;
4018 throw std::runtime_error(text.str().c_str());
4019 }
4020 }
4021
4022
4023 // remember file's mode
4024
4025 struct stat buf;
4026 if(int code = stat(pf->p_full_name.c_str(), &buf)) {
4027 std::ostringstream text;
4028 text << "cannot get information about file \'" << pf->p_full_name << "\': stat() failed with code " << code << ", reason = \'" << strerror(errno) << '\'';
4029 throw std::runtime_error(text.str().c_str());
4030 }
4031
4032
4033 // rename temporal file
4034
4035 if(int code = rename(tmp_file_name.c_str(), pf->p_full_name.c_str())) {
4036 std::ostringstream text;
4037 text << "cannot rename file \'" << tmp_file_name << "\' to \'" << pf->p_full_name << "\': rename() failed with code " << code << ", reason = \'" << strerror(errno) << '\'';
4038 throw std::runtime_error(text.str().c_str());
4039 }
4040
4041 tmp_file_name.erase(0);
4042
4043
4044 if(pf != p_active_data) {
4045 try {
4046 pf->unlock();
4047 }
4048 catch(exception& ex) {
4049 throw std::runtime_error(ex.what());
4050 }
4051 }
4052 pf->p_is_updated = false;
4053 pf->update_status_of_file();
4054
4055
4056 // get mode for new file
4057
4058 struct stat buf2;
4059 if(int code = stat(pf->p_full_name.c_str(), &buf2)) {
4060 std::ostringstream text;
4061 text << "cannot get information about file \'" << pf->p_full_name << "\': stat() failed with code " << code << ", reason = \'" << strerror(errno) << '\'';
4062 throw std::runtime_error(text.str().c_str());
4063 }
4064
4065
4066 // set file's mode if needed
4067
4068 if(buf.st_mode != buf2.st_mode) {
4069 if(int code = chmod(pf->p_full_name.c_str(), buf.st_mode) != 0) {
4070 std::ostringstream text;
4071 text << "cannot set protection mode for file \'" << pf->p_full_name << "\': chmod() failed with code " << code << ", reason = \'" << strerror(errno) << '\'';
4072 throw std::runtime_error(text.str().c_str());
4073 }
4074 }
4075
4076 // set file's group if needed (in case of problems report error, but do not throw exception)
4077
4078 if(buf.st_gid != buf2.st_gid) {
4079 if(int code = chown(pf->p_full_name.c_str(), (gid_t)(-1), buf.st_gid) != 0) {
4080 ers::warning(kernel::SetGroupIdFailed(ERS_HERE, buf.st_gid, pf->p_full_name.c_str(), code, strerror(errno)));
4081 }
4082 }
4083
4084 }
4085
4086 catch (exception & e) {
4087 if(pf != p_active_data) { try { pf->unlock();} catch(...) {} }
4088 if(!tmp_file_name.empty()) { unlink(tmp_file_name.c_str()); }
4089 throw CanNotWriteToFile("k_save_data", "data file", pf->p_full_name, e);
4090 }
4091 catch (std::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.what());
4095 }
4096 catch (...) {
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, "unknown");
4100 }
4101
4102 OSK_VERBOSE_REPORT("LEAVE " << fname)
4103}
const OksObject::Set & objects() const
Get objects.
Definition kernel.hpp:1790
static std::string get_tmp_file(const std::string &file_name)
Generates temporal file name.
Definition kernel.cpp:665
std::map< const std::string *, OksObject *, SortById > SMap
Definition object.hpp:860

◆ 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 2593 of file kernel.cpp.

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

◆ 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 4285 of file kernel.cpp.

4286{
4287 TLOG_DEBUG(4) << "enter for file " << (void *)fp;
4288
4289
4290 // check if active data is different from given file
4291
4292 if(p_active_data == fp) return;
4293
4294
4295 // first unlock current active data
4296
4297 if(p_active_data && p_active_data->is_updated() == false) {
4298 try {
4300 }
4301 catch(exception& ex) {
4302 throw CanNotSetActiveFile("data", fp->get_full_file_name(), ex);
4303 }
4304 }
4305
4306
4307 // exit, if file is (null)
4308
4309 if(!fp) {
4310 p_active_data = 0;
4311 return;
4312 }
4313
4314 try {
4315 fp->lock();
4316 p_active_data = fp;
4317 }
4318 catch(exception& ex) {
4319 throw CanNotSetActiveFile("data", fp->get_full_file_name(), ex);
4320 }
4321
4322 TLOG_DEBUG(4) << "leave for file " << (void *)fp;
4323}
void unlock()
Unlock OKS file.
Definition file.cpp:1143
bool is_updated() const
Return update status of OKS file.
Definition file.hpp:624

◆ 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 2910 of file kernel.cpp.

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

◆ 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 3559 of file kernel.cpp.

3560{
3561 std::unique_lock lock(p_kernel_mutex);
3562 return k_load_data(short_file_name, bind, 0, 0);
3563}

◆ 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 1788 of file kernel.cpp.

1789{
1790 std::unique_lock lock(p_kernel_mutex);
1791 return k_load_file(short_file_name, bind, 0, 0);
1792}

◆ 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 2297 of file kernel.cpp.

2298{
2299 std::unique_lock lock(p_kernel_mutex);
2300 return k_load_schema(short_file_name, parent_h);
2301}

◆ 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 3718 of file kernel.cpp.

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

◆ 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 2485 of file kernel.cpp.

2486{
2487 const char _fname[] = "new_schema";
2488 std::string fname = make_fname(_fname, sizeof(_fname)-1, s, nullptr, nullptr);
2489 OSK_VERBOSE_REPORT("ENTER " << fname)
2490
2491 if(!s.length()) {
2492 throw CanNotOpenFile("new_schema", s, "file name is empty");
2493 }
2494
2495 std::string file_name(s);
2496
2497 try {
2498
2499 Oks::substitute_variables(file_name);
2500
2501 test_file_existence(file_name, p_silence, fname, "schema");
2502
2503 file_name = get_file_path(s, nullptr, false);
2504
2505 std::unique_lock lock(p_kernel_mutex);
2506
2507 if(find_schema_file(file_name) != 0) {
2508 throw std::runtime_error("the file is already loaded");
2509 }
2510
2511 OksFile * file_h = new OksFile(file_name, "", "", "schema", this);
2512
2513 file_h->p_short_name = s;
2514
2515 k_set_active_schema(file_h);
2516
2518
2520
2521 }
2522 catch (std::exception & e) {
2523 throw CanNotCreateFile("new_schema", "schema file", file_name, e.what());
2524 }
2525 catch (...) {
2526 throw CanNotCreateFile("new_schema", "schema file", file_name, "caught unknown exception");
2527 }
2528
2529 OSK_VERBOSE_REPORT("LEAVE " << fname)
2530
2531 return p_active_schema;
2532}
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:2910

◆ 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 1776 of file kernel.hpp.

1776{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 1799 of file kernel.hpp.

1799{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 1790 of file kernel.hpp.

1790{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 5509 of file kernel.cpp.

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

◆ 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 4499 of file kernel.cpp.

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

◆ 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 3211 of file kernel.cpp.

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

◆ remove_data_file()

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

Definition at line 3779 of file kernel.cpp.

3780{
3781 p_data_files.erase(&f->p_full_name);
3782}

◆ 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 1424 of file kernel.cpp.

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

◆ remove_schema_file()

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

Definition at line 3785 of file kernel.cpp.

3786{
3787 p_schema_files.erase(&f->p_full_name);
3788}

◆ remove_user_repository_dir()

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

Definition at line 4941 of file kernel.cpp.

4942{
4944 {
4948 }
4949}
static void remove(const std::string &path)
Definition kernel.cpp:78
void erase(const std::string &path)
Definition kernel.cpp:98

◆ reset_cwd()

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

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

Definition at line 1714 of file kernel.hpp.

1714{ s_cwd = 0;}

◆ restore_preload_file_info()

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

Definition at line 3536 of file kernel.cpp.

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

◆ 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 4160 of file kernel.cpp.

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

◆ 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 2794 of file kernel.cpp.

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

◆ 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 4118 of file kernel.cpp.

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

◆ 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 2755 of file kernel.cpp.

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

◆ 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 3794 of file kernel.cpp.

3795{
3796 std::shared_lock lock(p_kernel_mutex);
3797 k_save_data(pf, ignoreBadObjects, true_file_h, nullptr, force_defaults);
3798}

◆ 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 3801 of file kernel.cpp.

3802{
3803 std::shared_lock lock(p_kernel_mutex);
3804 k_save_data(file_h, false, 0, &objects);
3805}

◆ 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 2546 of file kernel.cpp.

2547{
2548 std::shared_lock lock(p_kernel_mutex);
2549 k_save_schema(file_h, force, 0, &classes);
2550}

◆ 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 2538 of file kernel.cpp.

2539{
2540 std::shared_lock lock(p_kernel_mutex);
2541 k_save_schema(pf, force, fh);
2542}

◆ 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 1223 of file kernel.hpp.

1223{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 4278 of file kernel.cpp.

4279{
4280 std::unique_lock lock(p_kernel_mutex);
4282}

◆ 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 2903 of file kernel.cpp.

2904{
2905 std::unique_lock lock(p_kernel_mutex);
2907}

◆ 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 777 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 789 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 1439 of file kernel.cpp.

1440{
1441 if(p_profiling == b) return;
1442
1443 p_profiling = b;
1444
1445#ifndef ERS_NO_DEBUG
1446 if(p_profiling == true) {
1447 if(!profiler) profiler = new OksProfiler();
1448 }
1449 else {
1450 if(profiler) {
1451 delete profiler;
1452 profiler = 0;
1453 }
1454 }
1455#endif
1456}

◆ 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 698 of file kernel.hpp.

698{p_silence = b;}

◆ set_skip_string_range()

static 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 811 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 756 of file kernel.hpp.

◆ set_use_strict_repository_paths()

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

Set flag to use strict-repository-paths check.

Definition at line 1722 of file kernel.hpp.

1723 {
1725 }

◆ 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 389 of file kernel.cpp.

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

◆ 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 677 of file kernel.hpp.

677{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 2206 of file kernel.hpp.

2207{
2209}

◆ 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 2183 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 2199 of file kernel.hpp.

2200{
2202}

◆ 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 2175 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 2213 of file kernel.hpp.

2214{
2216}

◆ 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 2191 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 5202 of file kernel.cpp.

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

◆ test_parent()

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

Definition at line 1943 of file kernel.cpp.

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

◆ 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 4403 of file kernel.cpp.

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

◆ undefine()

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

Definition at line 2149 of file kernel.hpp.

2149{ 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 4952 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 1608 of file kernel.hpp.

1609 {
1610 update_repository("hash", hash_val, update_type);
1611 }
void update_repository(const std::string &hash_val, RepositoryUpdateType update_type)
Update user repository files from origin by hash.
Definition kernel.hpp:1608

◆ 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 4994 of file kernel.cpp.

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

Friends And Related Symbol Documentation

◆ OksClass

friend class OksClass
friend

Definition at line 580 of file kernel.hpp.

◆ OksData

friend struct OksData
friend

Definition at line 583 of file kernel.hpp.

◆ OksFile

friend class OksFile
friend

Definition at line 579 of file kernel.hpp.

◆ OksLoadObjectsJob

friend struct OksLoadObjectsJob
friend

Definition at line 582 of file kernel.hpp.

◆ OksObject

friend class OksObject
friend

Definition at line 581 of file kernel.hpp.

◆ operator<<

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

Definition at line 1491 of file kernel.cpp.

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

Member Data Documentation

◆ p_active_data

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

Definition at line 2054 of file kernel.hpp.

◆ p_active_schema

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

Definition at line 2053 of file kernel.hpp.

◆ p_allow_duplicated_classes

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

Definition at line 2023 of file kernel.hpp.

◆ p_allow_duplicated_objects

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

Definition at line 2024 of file kernel.hpp.

◆ p_allow_repository

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

Definition at line 2022 of file kernel.hpp.

◆ p_bind_classes_status

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

Definition at line 2077 of file kernel.hpp.

◆ p_bind_objects_status

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

Definition at line 2076 of file kernel.hpp.

◆ p_change_object_notify_fn

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

Definition at line 2161 of file kernel.hpp.

◆ p_change_object_notify_param

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

Definition at line 2162 of file kernel.hpp.

◆ p_classes

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

Definition at line 2066 of file kernel.hpp.

◆ p_close_all

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

Definition at line 2056 of file kernel.hpp.

◆ p_count

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

Definition at line 2068 of file kernel.hpp.

◆ p_create_object_notify_fn

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

Definition at line 2158 of file kernel.hpp.

◆ p_create_object_notify_param

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

Definition at line 2159 of file kernel.hpp.

◆ p_data_files

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

Definition at line 2051 of file kernel.hpp.

◆ p_delete_object_notify_fn

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

Definition at line 2164 of file kernel.hpp.

◆ p_delete_object_notify_param

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

Definition at line 2165 of file kernel.hpp.

◆ p_kernel_mutex

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

Definition at line 2042 of file kernel.hpp.

◆ p_load_errors

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

Definition at line 2079 of file kernel.hpp.

◆ p_objects

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

Definition at line 2072 of file kernel.hpp.

◆ p_objects_mutex

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

Definition at line 2043 of file kernel.hpp.

◆ p_objects_refs_mutex

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

Definition at line 2044 of file kernel.hpp.

◆ p_parallel_out_mutex

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

Definition at line 2046 of file kernel.hpp.

◆ p_preload_added_files

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

Definition at line 2082 of file kernel.hpp.

◆ p_preload_file_info

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

Definition at line 2081 of file kernel.hpp.

◆ p_profiling

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

Definition at line 2021 of file kernel.hpp.

◆ p_repository_checkout_ts

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

Definition at line 2036 of file kernel.hpp.

◆ p_repository_dirs

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

Definition at line 2061 of file kernel.hpp.

◆ p_repository_mapping_dir

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

Definition at line 2031 of file kernel.hpp.

◆ p_repository_root

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

Definition at line 2030 of file kernel.hpp.

◆ p_repository_update_ts

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

Definition at line 2037 of file kernel.hpp.

◆ p_repository_version

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

Definition at line 2035 of file kernel.hpp.

◆ p_schema_files

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

Definition at line 2050 of file kernel.hpp.

◆ p_schema_mutex

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

Definition at line 2045 of file kernel.hpp.

◆ p_silence

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

Definition at line 2019 of file kernel.hpp.

◆ p_skip_string_range

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

Definition at line 2027 of file kernel.hpp.

◆ p_test_duplicated_objects_via_inheritance

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

Definition at line 2025 of file kernel.hpp.

◆ p_threads_pool_size

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

Definition at line 2074 of file kernel.hpp.

◆ p_use_strict_repository_paths

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

Definition at line 2028 of file kernel.hpp.

◆ p_user_repository_root

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

Definition at line 2032 of file kernel.hpp.

◆ p_user_repository_root_created

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

Definition at line 2034 of file kernel.hpp.

◆ p_user_repository_root_inited

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

Definition at line 2033 of file kernel.hpp.

◆ p_verbose

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

Definition at line 2020 of file kernel.hpp.

◆ profiler

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

Definition at line 2070 of file kernel.hpp.

◆ s_cwd

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

Definition at line 2063 of file kernel.hpp.


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