MIDAS
Loading...
Searching...
No Matches
midas::odb Class Reference

#include <odbxx.h>

Collaboration diagram for midas::odb:

Classes

class  iterator
 

Public Types

enum  odb_source { ONLINE = 0 , STRING , FILE }
 

Public Member Functions

 odb ()
 
 ~odb ()
 
 odb (const odb &o)
 
odb operator= (odb &&o)=delete
 
template<typename T >
 odb (T v)
 
 odb (std::initializer_list< std::pair< const char *, midas::odb > > list)
 
template<typename T >
 odb (std::initializer_list< T > list)
 
template<typename T , size_t SIZE>
 odb (const std::array< T, SIZE > &arr)
 
template<size_t SIZE>
 odb (const std::array< std::string, SIZE > &arr)
 
 odb (const std::string &path, bool init_via_xml=false)
 
 odb (const char *s)
 
 odb (std::initializer_list< const char * > list)
 
template<typename T >
int detect_type (const T &)
 
template<typename T >
const T & operator= (const T &v)
 
template<typename T >
const std::vector< T > & operator= (const std::vector< T > &v)
 
template<typename T , size_t SIZE>
const std::array< T, SIZE > & operator= (const std::array< T, SIZE > &arr)
 
 operator std::string ()
 
template<typename T >
 operator std::vector< T > ()
 
 operator std::vector< std::string > ()
 
template<typename T , typename std::enable_if< std::is_same< T, uint8_t >::value||std::is_same< T, int8_t >::value||std::is_same< T, uint16_t >::value||std::is_same< T, int16_t >::value||std::is_same< T, uint32_t >::value||std::is_same< T, int32_t >::value||std::is_same< T, uint64_t >::value||std::is_same< T, int64_t >::value||std::is_same< T, bool >::value||std::is_same< T, float >::value||std::is_same< T, double >::value, T >::type * = nullptr>
 operator T ()
 
u_odboperator[] (int index)
 
odboperator[] (std::string str)
 
odboperator[] (const char *str)
 
template<typename T >
odboperator() (T v)
 
int get_last_index ()
 
void set_last_index (int i)
 
iterator begin () const
 
iterator end () const
 
template<typename T >
operator+ (T i)
 
template<typename T >
operator- (T i)
 
template<typename T >
operator* (const T i)
 
template<typename T >
operator/ (const T i)
 
odboperator++ ()
 
odb operator++ (int)
 
odboperator-- ()
 
odb operator-- (int)
 
odboperator+= (double d)
 
odboperator-= (double d)
 
odboperator*= (double d)
 
odboperator/= (double d)
 
void deep_copy (odb &d, const odb &s)
 
bool is_preserve_string_size () const
 
void set_preserve_string_size (bool f)
 
bool is_auto_refresh_read () const
 
void set_auto_refresh_read (bool f)
 
bool is_auto_refresh_write () const
 
void set_auto_refresh_write (bool f)
 
bool is_dirty () const
 
void set_dirty (bool f)
 
bool is_auto_create () const
 
void set_auto_create (bool f)
 
bool is_auto_enlarge_array () const
 
void set_auto_enlarge_array (bool f)
 
bool is_write_protect () const
 
void set_write_protect (bool f)
 
bool is_trigger_hotlink () const
 
void set_trigger_hotlink (bool f)
 
void odb_from_xml_remote (const std::string &str)
 
void odb_from_xml_string (const std::string &str, const std::string &subkey)
 
void odb_from_json_string (const std::string &str, const std::string &subkey)
 
void connect (const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults=false)
 
void connect (std::string str, bool write_defaults=false, bool delete_keys_not_in_defaults=false)
 
void connect_and_fix_structure (std::string path)
 
void read ()
 
void read (int index)
 
void write (int str_size=0)
 
void write (int index, int str_size)
 
std::string print ()
 
std::string dump ()
 
void print (std::string &s, int indent=0)
 
void dump (std::string &s, int indent=0)
 
void save (const std::string &filename)
 
void delete_key ()
 
int size ()
 
void resize (int size)
 
void resize (int size, bool b)
 
void watch (std::function< void(midas::odb &)> f)
 
void unwatch ()
 
void set (std::string str)
 
void set (std::string s, int i)
 
void set_odb (odb *o, int i)
 
void set_string_size (std::string s, int size)
 
bool is_subkey (std::string str)
 
HNDLE get_hkey ()
 
std::string get_full_path ()
 
std::string get_parent_path ()
 
int get_tid ()
 
int get_num_values ()
 
std::string get_name ()
 
odbitems ()
 
std::string s ()
 
void fix_order (std::vector< std::string > target_subkey_order)
 
void set_mode (int mode)
 
int get_mode ()
 
unsigned int get_last_written ()
 

Static Public Member Functions

static midas::odbodb_from_xml (PMXML_NODE node, odb *o)
 
static std::string node_to_string (const MJsonNode *node)
 
static midas::odbodb_from_json (const MJsonNode *node, std::string name, int tid, odb *o)
 
static void set_debug (bool flag)
 
static bool get_debug ()
 
static int create (const char *name, int type=TID_KEY)
 
static bool exists (const std::string &name)
 
static int delete_key (const std::string &name)
 
static void load (const std::string &filename, const std::string &odb_path)
 
static odb::odb_source get_odb_source ()
 
static void set_odb_source (odb::odb_source s)
 
static void set_odb_source (odb::odb_source s, std::string str)
 
static void odb_from_xml_string (const std::string &str)
 
static void odb_from_json_string (const std::string &str)
 
static bool is_connected_odb ()
 

Private Member Functions

void set_flags_recursively (uint32_t f)
 
void resize_mdata (int size)
 
template<typename T >
get ()
 
template<typename T >
void get (T &v)
 
void get (std::string &s, bool quotes=false, bool refresh=true)
 
u_odbget_mdata (int index=0)
 
odbget_subkey (std::string str)
 
int get_subkeys (std::vector< std::string > &name)
 
bool read_key (const std::string &path)
 
bool write_key (std::string &path, bool write_defaults)
 
void set_hkey (HNDLE hKey)
 
void set_flags (uint32_t f)
 
uint32_t get_flags ()
 
bool is_deleted () const
 
void set_deleted (bool f)
 
void set_tid (int tid)
 
void set_num_values (int n)
 
void set_name (std::string s)
 
void set_parent (midas::odb *p)
 
midas::odbget_parent ()
 

Static Private Member Functions

static void init_hdb ()
 
static midas::odbsearch_hkey (midas::odb *po, int hKey)
 
static void watch_callback (int hDB, int hKey, int index, void *info)
 
static void unwatch_all ()
 

Private Attributes

std::bitset< 9 > m_flags
 
int m_tid
 
u_odbm_data
 
std::string m_name
 
int m_num_values
 
int m_last_index
 
HNDLE m_hKey
 
std::function< void(midas::odb &)> m_watch_callback
 
midas::odbm_parent
 

Static Private Attributes

static thread_local odb_source s_odb_source = odb::ONLINE
 
static thread_local std::string s_odb_source_str = std::string("")
 
static thread_local odbs_odb = nullptr
 
static HNDLE s_hDB = 0
 
static bool s_debug = false
 
static bool s_connected_odb = false
 
static std::vector< midas::odbm_watch
 

Friends

std::ostream & operator<< (std::ostream &output, odb &o)
 
template<typename T >
bool operator== (const midas::odb &o, const T &d)
 
template<typename T >
bool operator== (const T &d, const midas::odb &o)
 
template<typename T >
bool operator!= (const midas::odb &o, const T &d)
 
template<typename T >
bool operator!= (const T &d, const midas::odb &o)
 
template<typename T >
bool operator< (const midas::odb &o, const T &d)
 
template<typename T >
bool operator< (const T &d, const midas::odb &o)
 
template<typename T >
bool operator<= (const midas::odb &o, const T &d)
 
template<typename T >
bool operator<= (const T &d, const midas::odb &o)
 
template<typename T >
bool operator> (const midas::odb &o, const T &d)
 
template<typename T >
bool operator> (const T &d, const midas::odb &o)
 
template<typename T >
bool operator>= (const midas::odb &o, const T &d)
 
template<typename T >
bool operator>= (const T &d, const midas::odb &o)
 

Detailed Description

Definition at line 410 of file odbxx.h.

Member Enumeration Documentation

◆ odb_source

Enumerator
ONLINE 
STRING 
FILE 

Definition at line 413 of file odbxx.h.

413 {
414 ONLINE = 0,
415 STRING,
416 FILE
417 };

Constructor & Destructor Documentation

◆ odb() [1/10]

midas::odb::odb ( )
inline

Definition at line 544 of file odbxx.h.

544 :
550 m_tid{0},
551 m_data{nullptr},
552 m_name{},
553 m_num_values{0},
554 m_last_index{-1},
555 m_hKey{},
556 m_parent{} {}
int m_num_values
Definition odbxx.h:469
int m_tid
Definition odbxx.h:463
u_odb * m_data
Definition odbxx.h:465
int m_last_index
Definition odbxx.h:471
std::bitset< 9 > m_flags
Definition odbxx.h:461
HNDLE m_hKey
Definition odbxx.h:473
std::string m_name
Definition odbxx.h:467
midas::odb * m_parent
Definition odbxx.h:477
@ AUTO_REFRESH_WRITE
Definition odbxx.h:395
@ TRIGGER_HOTLINK
Definition odbxx.h:402
@ AUTO_REFRESH_READ
Definition odbxx.h:394
@ AUTO_ENLARGE_ARRAY
Definition odbxx.h:398
@ AUTO_CREATE
Definition odbxx.h:397

◆ ~odb()

midas::odb::~odb ( )
inline

Definition at line 559 of file odbxx.h.

559 {
560 delete[] m_data;
561 }

◆ odb() [2/10]

midas::odb::odb ( const odb o)

Definition at line 307 of file odbxx.cxx.

307 : odb() {
308 m_tid = o.m_tid;
309 m_name = o.m_name;
310 m_num_values = o.m_num_values;
311 m_hKey = o.m_hKey;
312 m_watch_callback = o.m_watch_callback;
314 for (int i = 0; i < m_num_values; i++) {
316 m_data[i].set_parent(this);
317 if (m_tid == TID_STRING || m_tid == TID_LINK) {
318 // set_string() creates a copy of our string
319 m_data[i].set_string(o.m_data[i]);
320 } else if (m_tid == TID_KEY) {
321 // recursive call to create a copy of the odb object
322 midas::odb *po = o.m_data[i].get_podb();
323 midas::odb *pc = new midas::odb(*po);
324 pc->set_parent(this);
325 m_data[i].set(pc);
326 } else {
327 // simply pass basic types
328 m_data[i] = o.m_data[i];
329 m_data[i].set_parent(this);
330 }
331 }
332 }
std::function< void(midas::odb &)> m_watch_callback
Definition odbxx.h:475
void set_parent(midas::odb *p)
Definition odbxx.h:538
void set_tid(int tid)
Definition odbxx.h:105
void set_string(std::string s)
Definition odbxx.h:172
void set(T v)
Definition odbxx.h:142
void set_parent(odb *o)
Definition odbxx.h:102
odb * get_podb()
Definition odbxx.h:369
#define TID_KEY
Definition midas.h:349
#define TID_LINK
Definition midas.h:350
#define TID_STRING
Definition midas.h:346
INT i
Definition mdump.cxx:32
Here is the call graph for this function:

◆ odb() [3/10]

template<typename T >
midas::odb::odb ( v)
inline

Definition at line 571 of file odbxx.h.

571 :odb() {
572 m_num_values = 1;
573 m_data = new u_odb[1]{v};
574 m_tid = m_data[0].get_tid();
575 m_data[0].set_parent(this);
576 }
int get_tid()
Definition odbxx.h:107
Here is the call graph for this function:

◆ odb() [4/10]

midas::odb::odb ( std::initializer_list< std::pair< const char *, midas::odb > >  list)
inline

Definition at line 579 of file odbxx.h.

579 : odb() {
580 m_tid = TID_KEY;
581 m_num_values = list.size();
582 m_data = new u_odb[m_num_values];
583 int i = 0;
584 for (auto &element: list) {
585 // check if name exists already
586 for (int j=0 ; j<i ; j++) {
587 if (strcasecmp(element.first, m_data[j].get_odb().get_name().c_str()) == 0) {
588 if (element.first == m_data[j].get_odb().get_name().c_str()) {
589 mthrow("ODB key with name \"" + m_data[j].get_odb().get_name() + "\" exists already");
590 } else {
591 mthrow("ODB key \"" + std::string(element.first) + "\" exists already as \"" +
592 m_data[j].get_odb().get_name() + "\" (only case differs)");
593 }
594 }
595 }
596 auto o = new midas::odb(element.second);
597 o->set_name(element.first);
598 o->set_parent(this);
600 m_data[i].set_parent(this);
601 m_data[i].set(o);
602 i++;
603 }
604 }
std::string get_name()
Definition odbxx.h:1456
odb & get_odb()
Definition odbxx.h:375
INT element
Definition mchart.cxx:40
#define mthrow(arg)
Definition mexcept.h:24
INT j
Definition odbhist.cxx:40
static te_expr * list(state *s)
Definition tinyexpr.c:567
Here is the call graph for this function:

◆ odb() [5/10]

template<typename T >
midas::odb::odb ( std::initializer_list< T >  list)
inline

Definition at line 608 of file odbxx.h.

608 : odb() {
609 m_num_values = list.size();
610 m_data = new u_odb[m_num_values]{};
611 int i = 0;
612 for (auto &element : list) {
613 u_odb u(element);
614 m_data[i].set_tid(u.get_tid());
615 m_data[i].set_parent(this);
617 i++;
618 }
619 m_tid = m_data[0].get_tid();
620 }
Here is the call graph for this function:

◆ odb() [6/10]

template<typename T , size_t SIZE>
midas::odb::odb ( const std::array< T, SIZE > &  arr)
inline

Definition at line 624 of file odbxx.h.

624 : odb() {
626 m_data = new u_odb[m_num_values]{};
627 for (int i = 0; i < (int)SIZE; i++) {
628 u_odb u(arr[i]);
629 m_data[i].set_tid(u.get_tid());
630 m_data[i].set_parent(this);
631 m_data[i].set(arr[i]);
632 }
633 m_tid = m_data[0].get_tid();
634 }
#define SIZE
Here is the call graph for this function:

◆ odb() [7/10]

template<size_t SIZE>
midas::odb::odb ( const std::array< std::string, SIZE > &  arr)
inline

Definition at line 638 of file odbxx.h.

638 : odb() {
640 m_data = new u_odb[m_num_values]{};
641 for (int i = 0; i < (int)SIZE; i++) {
642 std::string * mystring = new std::string(arr[i]);
643 u_odb u(mystring);
644 m_data[i].set_tid(u.get_tid());
645 m_data[i].set_parent(this);
646 m_data[i].set(arr[i]);
647 }
648 m_tid = m_data[0].get_tid();
649 }
Here is the call graph for this function:

◆ odb() [8/10]

midas::odb::odb ( const std::string &  path,
bool  init_via_xml = false 
)
inline

Definition at line 652 of file odbxx.h.

652 : odb() {
653 if (path[0] == '/') {
654 // ODB path
655 if (s_odb_source == ONLINE) {
656 if (init_via_xml) {
657 if (!exists(path))
658 odb::create(path.c_str(), TID_KEY);
660 } else {
661 if (!read_key(path))
662 // create subdir if key does not exist
663 odb::create(path.c_str(), TID_KEY);
664
665 if (!read_key(path))
666 mthrow("ODB key \"" + path + "\" not found in ODB");
667
668 if (m_tid != TID_KEY)
669 read();
670 }
671 } else if (s_odb_source == STRING || s_odb_source == FILE) {
672
673 // split path
674 std::stringstream ss(path.substr(1));
675 std::string item;
676 std::vector<std::string> arr;
677 while (std::getline(ss, item, '/'))
678 arr.push_back(item);
679
680 // extract subkey from root odb
681 odb *o = s_odb;
682 for (size_t i = 0; i < arr.size(); i++)
683 o = &(*o)[arr[i]];
684
685 // do a deep copy from "o" to "this"
686 m_tid = o->m_tid;
687 m_tid = o->m_tid;
688 m_name = o->m_name;
689 m_num_values = o->m_num_values;
690 m_hKey = o->m_hKey;
691 m_watch_callback = o->m_watch_callback;
693 for (int i = 0; i < m_num_values; i++) {
695 m_data[i].set_parent(this);
696 if (m_tid == TID_STRING || m_tid == TID_LINK) {
697 // set_string() creates a copy of our string
698 m_data[i].set_string(o->m_data[i]);
699 } else if (m_tid == TID_KEY) {
700 // recursive call to create a copy of the odb object
701 auto *po= o->m_data[i].get_podb();
702 auto *pc = new midas::odb(*po);
703 pc->set_parent(this);
704 m_data[i].set(pc);
705 } else {
706 // simply pass basic types
707 m_data[i] = o->m_data[i];
708 m_data[i].set_parent(this);
709 }
710 }
711
712 } else
713 mthrow("Unknown ODB source: " + std::to_string(s_odb_source));
714
715 } else {
716 // simple string
717
718 // Construct object from initializer_list
719 m_num_values = 1;
720 m_data = new u_odb[1]{new std::string{path}};
721 m_tid = m_data[0].get_tid();
722 m_data[0].set_parent(this);
723 }
724 }
static bool exists(const std::string &name)
Definition odbxx.cxx:76
bool read_key(const std::string &path)
Definition odbxx.cxx:657
static thread_local odb_source s_odb_source
Definition odbxx.h:447
void odb_from_xml_remote(const std::string &str)
Definition odbxx.cxx:160
void read()
Definition odbxx.cxx:802
static thread_local odb * s_odb
Definition odbxx.h:450
static int create(const char *name, int type=TID_KEY)
Definition odbxx.cxx:140
Here is the call graph for this function:

◆ odb() [9/10]

midas::odb::odb ( const char *  s)
inline

Definition at line 727 of file odbxx.h.

727 : odb(std::string(s)) {
728 }
std::string s()
Definition odbxx.h:1459

◆ odb() [10/10]

midas::odb::odb ( std::initializer_list< const char * >  list)
inline

Definition at line 731 of file odbxx.h.

731 : odb() {
732 m_num_values = list.size();
733 m_data = new u_odb[m_num_values]{};
734 int i = 0;
735 for (auto &element : list) {
737 m_data[i].set_parent(this);
739 i++;
740 }
741 m_tid = m_data[0].get_tid();
742 }
Here is the call graph for this function:

Member Function Documentation

◆ begin()

iterator midas::odb::begin ( ) const
inline

Definition at line 1018 of file odbxx.h.

1018{ return iterator(m_data); }

◆ connect() [1/2]

void midas::odb::connect ( const std::string &  path,
const std::string &  name,
bool  write_defaults,
bool  delete_keys_not_in_defaults = false 
)

Definition at line 1377 of file odbxx.cxx.

1377 {
1378 init_hdb();
1379
1380 if (!name.empty())
1381 m_name = name;
1382 std::string path(p);
1383
1384 if (path.empty())
1385 mthrow("odb::connect() cannot be called with an empty ODB path");
1386
1387 if (path[0] != '/')
1388 mthrow("odb::connect(\"" + path + "\"): path must start with leading \"/\"");
1389
1390 if (path.back() != '/')
1391 path += "/";
1392
1393 path += m_name;
1394
1395 HNDLE hKey;
1396 int status = db_find_key(s_hDB, 0, path.c_str(), &hKey);
1397 bool key_exists = (status == DB_SUCCESS);
1398 bool created = false;
1399
1400 if (key_exists && delete_keys_not_in_defaults) {
1401 // Recurse down to delete keys as needed.
1402 // We need to do this recursively BEFORE calling read/read_key for the first time
1403 // to ensure that subdirectories get handled correctly.
1405 }
1406
1407 if (!key_exists || write_defaults) {
1408 created = write_key(path, write_defaults);
1409 } else {
1410 read_key(path);
1411 }
1412
1413 // correct wrong parent ODB from initializer_list
1414 for (int i = 0; i < m_num_values; i++)
1415 m_data[i].set_parent(this);
1416
1417 if (m_tid == TID_KEY) {
1418 for (int i = 0; i < m_num_values; i++)
1419 m_data[i].get_odb().connect(get_full_path(), m_data[i].get_odb().get_name(), write_defaults);
1420 } else if (created || write_defaults) {
1421 write();
1422 } else {
1423 read();
1424 }
1425 }
std::string get_full_path()
Definition odbxx.cxx:362
static HNDLE s_hDB
Definition odbxx.h:452
static void init_hdb()
Definition odbxx.cxx:50
bool write_key(std::string &path, bool write_defaults)
Definition odbxx.cxx:743
#define DB_SUCCESS
Definition midas.h:632
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4256
HNDLE hKey
INT HNDLE
Definition midas.h:132
#define write(n, a, f, d)
#define name(x)
Definition midas_macro.h:24
void recurse_del_keys_not_in_defaults(std::string path, HNDLE hDB, HNDLE hKey, midas::odb &default_odb)
Definition odbxx.cxx:1253
DWORD status
Definition odbhist.cxx:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ connect() [2/2]

void midas::odb::connect ( std::string  str,
bool  write_defaults = false,
bool  delete_keys_not_in_defaults = false 
)

Definition at line 1428 of file odbxx.cxx.

1428 {
1429
1430 if (str.empty())
1431 mthrow("odb::connect() cannot be called with an empty ODB path");
1432
1433 if (str[0] != '/')
1434 mthrow("odb::connect(\"" + str + "\"): path must start with leading \"/\"");
1435
1436 if (str == "/")
1437 mthrow("odb::connect(\"" + str + "\"): root ODB tree is not allowed");
1438
1440 mthrow("odb::connect(\"" + str + "\"): not allowed in STRING or FILE mode");
1441
1442 if (str.back() == '/')
1443 str = str.substr(0, str.size()-1);
1444
1445 // separate ODB path and key nam
1446 std::string name;
1447 std::string path;
1448 name = str.substr(str.find_last_of('/') + 1);
1449 path = str.substr(0, str.find_last_of('/') + 1);
1450
1451 connect(path, name, write_defaults, delete_keys_not_in_defaults);
1452 }
void connect(const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults=false)
Definition odbxx.cxx:1377
char str[256]
Definition odbhist.cxx:33
Here is the call graph for this function:

◆ connect_and_fix_structure()

void midas::odb::connect_and_fix_structure ( std::string  path)

Definition at line 1459 of file odbxx.cxx.

1459 {
1460 // Store the order the user specified.
1461 // Need to do this recursively before calling connect(), as the first
1462 // read() in that function merges user keys and existing keys.
1463 std::map<std::string, std::vector<std::string> > user_order;
1464 recurse_get_defaults_order(path, *this, user_order);
1465
1466 // Main connect() that adds/deletes/updates keys as needed.
1467 connect(path, false, true);
1468
1469 // Fix order in ODB (and memory)
1470 recurse_fix_order(*this, user_order);
1471 }
void recurse_fix_order(midas::odb &default_odb, std::map< std::string, std::vector< std::string > > &user_order)
Definition odbxx.cxx:1300
void recurse_get_defaults_order(std::string path, midas::odb &default_odb, std::map< std::string, std::vector< std::string > > &retval)
Definition odbxx.cxx:1290
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create()

int midas::odb::create ( const char *  name,
int  type = TID_KEY 
)
static

Definition at line 140 of file odbxx.cxx.

140 {
141 init_hdb();
142 int status = -1;
143 if (is_connected_odb())
146 mthrow("Cannot create key " + std::string(name) + ", db_create_key() status = " + std::to_string(status));
147 return status;
148 }
static bool is_connected_odb()
Definition odbxx.h:1428
#define DB_KEY_EXIST
Definition midas.h:642
INT db_create_key(HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type)
Definition odb.cxx:3392
INT type
Definition mana.cxx:269
Here is the call graph for this function:
Here is the caller graph for this function:

◆ deep_copy()

void midas::odb::deep_copy ( odb d,
const odb s 
)

Definition at line 334 of file odbxx.cxx.

334 {
335 d.m_tid = s.m_tid;
336 d.m_name = s.m_name;
337 d.m_num_values = s.m_num_values;
338 d.m_hKey = s.m_hKey;
339 d.m_watch_callback = s.m_watch_callback;
340 d.m_data = new midas::u_odb[d.m_num_values]{};
341 for (int i = 0; i < d.m_num_values; i++) {
342 d.m_data[i].set_tid(d.m_tid);
343 d.m_data[i].set_parent(&d);
344 if (d.m_tid == TID_STRING || d.m_tid == TID_LINK) {
345 // set_string() creates a copy of our string
346 d.m_data[i].set_string(s.m_data[i]);
347 } else if (d.m_tid == TID_KEY) {
348 // recursive call to create a copy of the odb object
349 midas::odb *po = s.m_data[i].get_podb();
350 midas::odb *pc = new midas::odb(*po);
351 pc->set_parent(&d);
352 d.m_data[i].set(pc);
353 } else {
354 // simply pass basic types
355 d.m_data[i] = s.m_data[i];
356 d.m_data[i].set_parent(this);
357 }
358 }
359 }
double d
Definition system.cxx:1313
Here is the call graph for this function:

◆ delete_key() [1/2]

void midas::odb::delete_key ( )

Definition at line 1473 of file odbxx.cxx.

1473 {
1474 init_hdb();
1475
1477
1478 if (this->is_write_protect())
1479 mthrow("Cannot modify write protected key \"" + m_name + "\"");
1480
1481
1482 // delete key in ODB
1484 if (status != DB_SUCCESS && status != DB_INVALID_HANDLE)
1485 mthrow("db_delete_key for ODB key \"" + m_name +
1486 "\" returnd error code " + std::to_string(status));
1487
1488 if (s_debug)
1489 std::cout << "Deleted ODB key \"" + m_name + "\"" << std::endl;
1490
1491 // invalidate this object
1492 delete[] m_data;
1493 m_data = nullptr;
1494 m_num_values = 0;
1495 m_tid = 0;
1496 m_hKey = 0;
1497
1498 // set flag that this object has been deleted
1499 set_deleted(true);
1500 }
static bool s_debug
Definition odbxx.h:454
void set_deleted(bool f)
Definition odbxx.h:531
bool is_write_protect() const
Definition odbxx.h:1388
#define DB_INVALID_HANDLE
Definition midas.h:636
INT db_delete_key(HNDLE hDB, HNDLE hKey, BOOL follow_links)
Definition odb.cxx:3933
Here is the call graph for this function:
Here is the caller graph for this function:

◆ delete_key() [2/2]

int midas::odb::delete_key ( const std::string &  name)
static

Definition at line 85 of file odbxx.cxx.

85 {
86 init_hdb();
88 return false;
89 HNDLE hkey;
90 auto status = db_find_key(s_hDB, 0, name.c_str(), &hkey);
91 if (status != DB_SUCCESS) {
92 if (s_debug)
93 std::cout << "Delete key " + name << " not found in ODB" << std::endl;
94 return status;
95 }
96 if (s_debug)
97 std::cout << "Delete ODB key " + name << std::endl;
98 return db_delete_key(s_hDB, hkey);
99 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ detect_type()

template<typename T >
int midas::odb::detect_type ( const T &  )
inline

Definition at line 745 of file odbxx.h.

745 {
746 if (std::is_same<T, uint8_t>::value)
747 return TID_UINT8;
748 else if (std::is_same<T, int8_t>::value)
749 return TID_INT8;
750 else if (std::is_same<T, uint16_t>::value)
751 return TID_UINT16;
752 else if (std::is_same<T, int16_t>::value)
753 return TID_INT16;
754 else if (std::is_same<T, uint32_t>::value)
755 return TID_UINT32;
756 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 4)
757 return TID_UINT32;
758 else if (std::is_same<T, int32_t>::value)
759 return TID_INT32;
760 else if (std::is_same<T, long>::value && sizeof(long) == 4)
761 return TID_INT32;
762 else if (std::is_same<T, uint64_t>::value)
763 return TID_UINT64;
764 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 8)
765 return TID_UINT64;
766 else if (std::is_same<T, int64_t>::value)
767 return TID_INT64;
768 else if (std::is_same<T, long>::value && sizeof(long) == 8)
769 return TID_INT64;
770 else if (std::is_same<T, bool>::value)
771 return TID_BOOL;
772 else if (std::is_same<T, float>::value)
773 return TID_FLOAT;
774 else if (std::is_same<T, double>::value)
775 return TID_DOUBLE;
776 else
777 return TID_STRING;
778 }
#define TID_DOUBLE
Definition midas.h:343
#define TID_BOOL
Definition midas.h:340
#define TID_UINT64
Definition midas.h:352
#define TID_INT64
Definition midas.h:351
#define TID_INT32
Definition midas.h:339
#define TID_UINT8
Definition midas.h:328
#define TID_INT8
Definition midas.h:330
#define TID_UINT32
Definition midas.h:337
#define TID_UINT16
Definition midas.h:333
#define TID_INT16
Definition midas.h:335
#define TID_FLOAT
Definition midas.h:341
Here is the caller graph for this function:

◆ dump() [1/2]

std::string midas::odb::dump ( )

Definition at line 427 of file odbxx.cxx.

427 {
428 std::string s;
429 s = "{\n";
430 dump(s, 1);
431 s += "\n}";
432 return s;
433 }
std::string dump()
Definition odbxx.cxx:427
Here is the call graph for this function:
Here is the caller graph for this function:

◆ dump() [2/2]

void midas::odb::dump ( std::string &  s,
int  indent = 0 
)

Definition at line 469 of file odbxx.cxx.

469 {
470 if (m_name != "root")
471 for (int i = 0; i < indent; i++)
472 s += " ";
473 if (m_tid == TID_KEY) {
474 if (m_name == "root")
475 indent--;
476 else {
477 s += "\"" + m_name + "\": {\n";
478 }
479 for (int i = 0; i < m_num_values; i++) {
480 std::string v;
481 m_data[i].get_odb().dump(v, indent + 1);
482 s += v;
483 if (i < m_num_values - 1)
484 s += ",\n";
485 else
486 s += "\n";
487 }
488 if (m_name != "root") {
489 for (int i = 0; i < indent; i++)
490 s += " ";
491 s += "}";
492 }
493 } else {
494 s += "\"" + m_name + "/key\": ";
495 s += "{ \"type\": " + std::to_string(m_tid) + ", ";
496
498 KEY key;
500 s += "\"access_mode\": " + std::to_string(key.access_mode) + ", ";
501 s += "\"last_written\": " + std::to_string(key.last_written) + "},\n";
502 }
503
504 for (int i = 0; i < indent; i++)
505 s += " ";
506 s += "\"" + m_name + "\": ";
507 if (m_num_values > 1)
508 s += "[";
509 std::string v;
510 get(v, m_tid == TID_STRING || m_tid == TID_LINK);
511 s += v;
512 if (m_num_values > 1)
513 s += "]";
514 }
515 }
T get()
Definition odbxx.h:494
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6043
KEY key
Definition mdump.cxx:34
static std::string indent(int x, const char *p=" ")
Definition midas.h:1027
WORD access_mode
Definition midas.h:1034
INT last_written
Definition midas.h:1038
Here is the call graph for this function:

◆ end()

iterator midas::odb::end ( ) const
inline

Definition at line 1019 of file odbxx.h.

1019{ return iterator(m_data + m_num_values); }

◆ exists()

bool midas::odb::exists ( const std::string &  name)
static

Definition at line 76 of file odbxx.cxx.

76 {
77 init_hdb();
79 return false;
80 HNDLE hkey;
81 return db_find_key(s_hDB, 0, name.c_str(), &hkey) == DB_SUCCESS;
82 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fix_order()

void midas::odb::fix_order ( std::vector< std::string >  target_subkey_order)

Definition at line 1314 of file odbxx.cxx.

1314 {
1315 // Fix the order of ODB keys to match that specified in target_order.
1316 // The in-ODB representation is simple, as we can just use db_reorder_key()
1317 // on anything that's in the wrong place.
1318 // The in-memory representation is a little trickier, but we just copy raw
1319 // memory into a temporary array, so we don't have to delete/recreate the
1320 // u_odb objects.
1321 std::vector<std::string> curr_order;
1322
1323 if (get_subkeys(curr_order) <= 0) {
1324 // Not a TID_KEY (or no keys)
1325 return;
1326 }
1327
1328 if (target_order.size() != curr_order.size() || (int)target_order.size() != m_num_values) {
1329 return;
1330 }
1331
1332 HNDLE hKey = get_hkey();
1333 bool force_order = false;
1334
1335 // Temporary location where we'll store in-memory u_odb objects in th
1336 // correct order.
1337 u_odb* new_m_data = new u_odb[m_num_values];
1338
1339 for (int i = 0; i < m_num_values; i++) {
1340 if (force_order || curr_order[i] != target_order[i]) {
1341 force_order = true;
1342 HNDLE hSubKey;
1343
1344 // Fix the order in the ODB
1345 db_find_key(s_hDB, hKey, target_order[i].c_str(), &hSubKey);
1346 db_reorder_key(s_hDB, hSubKey, i);
1347 }
1348
1349 // Fix the order in memory
1350 auto curr_it = std::find(curr_order.begin(), curr_order.end(), target_order[i]);
1351
1352 if (curr_it == curr_order.end()) {
1353 // Logic error - bail to avoid doing any damage to the in-memory version.
1354 delete[] new_m_data;
1355 return;
1356 }
1357
1358 int curr_idx = curr_it - curr_order.begin();
1359 new_m_data[i] = m_data[curr_idx];
1360 }
1361
1362 // Final update of the in-memory version so they are in the correct order
1363 for (int i = 0; i < m_num_values; i++) {
1364 m_data[i] = new_m_data[i];
1365
1366 // Nullify pointers that point to the same object in
1367 // m_data and new_m_data, so the underlying object doesn't
1368 // get destroyed when we delete new_m_data.
1369 new_m_data[i].set_string_ptr(nullptr);
1370 new_m_data[i].set_odb(nullptr);
1371 }
1372
1373 delete[] new_m_data;
1374 }
HNDLE get_hkey()
Definition odbxx.h:1451
int get_subkeys(std::vector< std::string > &name)
Definition odbxx.cxx:632
void set_string_ptr(std::string *s)
Definition odbxx.h:179
INT db_reorder_key(HNDLE hDB, HNDLE hKey, INT idx)
Definition odb.cxx:6385
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get() [1/3]

template<typename T >
T midas::odb::get ( )
inlineprivate

Definition at line 494 of file odbxx.h.

494 {
495 if (m_num_values > 1)
496 mthrow("ODB key \"" + get_full_path() +
497 "[0..." + std::to_string(m_num_values - 1) +
498 "]\" contains array. Please assign to std::vector.");
500 read();
501 return (T) m_data[0];
502 }
bool is_auto_refresh_read() const
Definition odbxx.h:1361
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get() [2/3]

void midas::odb::get ( std::string &  s,
bool  quotes = false,
bool  refresh = true 
)
private

Definition at line 285 of file odbxx.cxx.

285 {
286 if (refresh && is_auto_refresh_read())
287 read();
288
289 // put value into quotes
290 s = "";
291 std::string sd;
292 for (int i = 0; i < m_num_values; i++) {
293 m_data[i].get(sd);
294 if (quotes)
295 s += "\"";
296 s += sd;
297 if (quotes)
298 s += "\"";
299 if (i < m_num_values - 1)
300 s += ",";
301 }
302 }
Here is the call graph for this function:

◆ get() [3/3]

template<typename T >
void midas::odb::get ( T &  v)
inlineprivate

Definition at line 506 of file odbxx.h.

506 {
507 if (m_num_values > 1)
508 mthrow("ODB key \"" + get_full_path() + "\" contains array. Please assign to std::vector.");
510 read();
511 v = (T) m_data[0];
512 }
Here is the call graph for this function:

◆ get_debug()

static bool midas::odb::get_debug ( )
inlinestatic

Definition at line 1402 of file odbxx.h.

1402{ return s_debug; }
Here is the caller graph for this function:

◆ get_flags()

uint32_t midas::odb::get_flags ( )
inlineprivate

Definition at line 528 of file odbxx.h.

528{ return static_cast<uint32_t>(m_flags.to_ulong()); }
Here is the caller graph for this function:

◆ get_full_path()

std::string midas::odb::get_full_path ( )

Definition at line 362 of file odbxx.cxx.

362 {
363 if (m_name[0] == '/')
364 return m_name;
365 if (m_parent)
366 return m_parent->get_full_path() + "/" + m_name;
367
368 if (!is_connected_odb() || m_hKey == -1)
369 return m_name;
370
371 std::string str = db_get_path(s_hDB, m_hKey);
372 if (str == "/") // change "/" to ""
373 str = "";
374 return str;
375 }
INT db_get_path(HNDLE hDB, HNDLE hKey, char *path, INT buf_size)
Definition odb.cxx:4775
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_hkey()

HNDLE midas::odb::get_hkey ( )
inline

Definition at line 1451 of file odbxx.h.

1451{ return m_hKey; }
Here is the caller graph for this function:

◆ get_last_index()

int midas::odb::get_last_index ( )
inline

Definition at line 1014 of file odbxx.h.

1014{ return m_last_index; }

◆ get_last_written()

unsigned int midas::odb::get_last_written ( )

Definition at line 1533 of file odbxx.cxx.

1533 {
1534 init_hdb();
1535
1536 // set mode in ODB
1537 KEY key;
1538 int status = db_get_key(s_hDB, m_hKey, &key);
1539
1541 mthrow("db_get_key for ODB key \"" + get_full_path() +
1542 "\" returnd error code " + std::to_string(status));
1543
1544 return (unsigned int) (key.last_written);
1545 }
Here is the call graph for this function:

◆ get_mdata()

u_odb & midas::odb::get_mdata ( int  index = 0)
inlineprivate

Definition at line 518 of file odbxx.h.

518{ return m_data[index]; }
INT index
Definition mana.cxx:271

◆ get_mode()

int midas::odb::get_mode ( )

Definition at line 1519 of file odbxx.cxx.

1519 {
1520 init_hdb();
1521
1522 // set mode in ODB
1523 KEY key;
1524 int status = db_get_key(s_hDB, m_hKey, &key);
1525
1527 mthrow("db_get_key for ODB key \"" + get_full_path() +
1528 "\" returnd error code " + std::to_string(status));
1529
1530 return key.access_mode;
1531 }
Here is the call graph for this function:

◆ get_name()

std::string midas::odb::get_name ( )
inline

Definition at line 1456 of file odbxx.h.

1456{ return m_name; }
Here is the caller graph for this function:

◆ get_num_values()

int midas::odb::get_num_values ( )
inline

Definition at line 1455 of file odbxx.h.

1455{ return m_num_values; }

◆ get_odb_source()

static odb::odb_source midas::odb::get_odb_source ( )
inlinestatic

Definition at line 1415 of file odbxx.h.

1415{ return s_odb_source; }

◆ get_parent()

midas::odb * midas::odb::get_parent ( )
inlineprivate

Definition at line 539 of file odbxx.h.

539{ return m_parent; }

◆ get_parent_path()

std::string midas::odb::get_parent_path ( )

Definition at line 378 of file odbxx.cxx.

378 {
379 std::string s = get_full_path();
380 std::size_t i = s.find_last_of("/");
381 s = s.substr(0, i);
382 return s;
383 }
Here is the call graph for this function:

◆ get_subkey()

odb & midas::odb::get_subkey ( std::string  str)
private

Definition at line 568 of file odbxx.cxx.

568 {
569 if (m_tid == 0) {
570 if (is_auto_create()) {
571 m_tid = TID_KEY;
572 int status = db_create_key(s_hDB, 0, m_name.c_str(), m_tid);
574 mthrow("Cannot create ODB key \"" + m_name + "\", status" + std::to_string(status));
575 db_find_key(s_hDB, 0, m_name.c_str(), &m_hKey);
576 if (s_debug) {
577 if (m_name[0] == '/')
578 std::cout << "Created ODB key \"" + m_name + "\"" << std::endl;
579 else
580 std::cout << "Created ODB key \"" + get_full_path() + "\"" << std::endl;
581 }
582 // strip path from name
583 if (m_name.find_last_of('/') != std::string::npos)
584 m_name = m_name.substr(m_name.find_last_of('/') + 1);
585 } else
586 mthrow("Invalid key \"" + m_name + "\" does not have subkeys");
587
588 }
589 if (m_tid != TID_KEY)
590 mthrow("ODB key \"" + get_full_path() + "\" does not have subkeys");
591
592 std::string first = str;
593 std::string tail{};
594 if (str.find('/') != std::string::npos) {
595 first = str.substr(0, str.find('/'));
596 tail = str.substr(str.find('/') + 1);
597 }
598
599 int i;
600 for (i = 0; i < m_num_values; i++)
601 if (equal_ustring(first.c_str(), m_data[i].get_odb().get_name().c_str()))
602 break;
603 if (i == m_num_values) {
604 if (is_auto_create()) {
605 if (m_num_values == 0) {
606 m_num_values = 1;
607 m_data = new u_odb[1]{};
608 i = 0;
609 } else {
610 // resize array
612 i = m_num_values - 1;
613 }
614 midas::odb *o = new midas::odb();
616 m_data[i].set_parent(this);
617 o->set_name(get_full_path() + "/" + str);
618 o->set_tid(0); // tid is currently undefined
619 o->set_flags(get_flags());
620 o->set_parent(this);
621 m_data[i].set(o);
622 } else
623 mthrow("ODB key \"" + get_full_path() + "\" does not contain subkey \"" + first + "\"");
624 }
625 if (!tail.empty())
626 return m_data[i].get_odb().get_subkey(tail);
627
628 return *m_data[i].get_podb();
629 }
bool is_auto_create() const
Definition odbxx.h:1376
void set_tid(int tid)
Definition odbxx.h:533
void set_flags(uint32_t f)
Definition odbxx.h:527
void resize_mdata(int size)
Definition odbxx.cxx:261
odb & get_subkey(std::string str)
Definition odbxx.cxx:568
void set_name(std::string s)
Definition odbxx.h:536
uint32_t get_flags()
Definition odbxx.h:528
#define DB_CREATED
Definition midas.h:633
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3285
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_subkeys()

int midas::odb::get_subkeys ( std::vector< std::string > &  name)
private

Definition at line 632 of file odbxx.cxx.

632 {
633 if (m_tid != TID_KEY)
634 return 0;
635 if (m_hKey == 0 || m_hKey == -1)
636 mthrow("get_sub-keys called with invalid m_hKey for ODB key \"" + m_name + "\"");
637
638 // count number of subkeys in ODB
639 std::vector<HNDLE> hlist;
640 int n = 0;
641 for (int i = 0;; i++) {
642 HNDLE h;
643 int status = db_enum_key(s_hDB, m_hKey, i, &h);
644 if (status != DB_SUCCESS)
645 break;
646 KEY key;
647 db_get_key(s_hDB, h, &key);
648 hlist.push_back(h);
649 name.push_back(key.name);
650 n = i + 1;
651 }
652
653 return n;
654 }
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5357
DWORD n[4]
Definition mana.cxx:247
char name[NAME_LENGTH]
Definition midas.h:1030
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_tid()

int midas::odb::get_tid ( )
inline

Definition at line 1454 of file odbxx.h.

1454{ return m_tid; }
Here is the caller graph for this function:

◆ init_hdb()

void midas::odb::init_hdb ( )
staticprivate

Definition at line 50 of file odbxx.cxx.

50 {
52 mthrow("Operation only possible if connected to an online ODB");
53
54 if (s_hDB == 0)
56 if (s_hDB == 0)
57 mthrow("Please call cm_connect_experiment() before accessing the ODB");
58 s_connected_odb = true;
59 }
static bool s_connected_odb
Definition odbxx.h:456
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3027
Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_auto_create()

bool midas::odb::is_auto_create ( ) const
inline

Definition at line 1376 of file odbxx.h.

Here is the caller graph for this function:

◆ is_auto_enlarge_array()

bool midas::odb::is_auto_enlarge_array ( ) const
inline

Definition at line 1382 of file odbxx.h.

Here is the caller graph for this function:

◆ is_auto_refresh_read()

bool midas::odb::is_auto_refresh_read ( ) const
inline

Definition at line 1361 of file odbxx.h.

Here is the caller graph for this function:

◆ is_auto_refresh_write()

bool midas::odb::is_auto_refresh_write ( ) const
inline

Definition at line 1367 of file odbxx.h.

Here is the caller graph for this function:

◆ is_connected_odb()

static bool midas::odb::is_connected_odb ( )
inlinestatic

Definition at line 1428 of file odbxx.h.

1428{ return s_connected_odb; }
Here is the caller graph for this function:

◆ is_deleted()

bool midas::odb::is_deleted ( ) const
inlineprivate

Definition at line 530 of file odbxx.h.

530{ return m_flags[odb_flags::DELETED]; }
@ DELETED
Definition odbxx.h:400
Here is the caller graph for this function:

◆ is_dirty()

bool midas::odb::is_dirty ( ) const
inline

Definition at line 1373 of file odbxx.h.

1373{ return m_flags[odb_flags::DIRTY]; }
@ DIRTY
Definition odbxx.h:399

◆ is_preserve_string_size()

bool midas::odb::is_preserve_string_size ( ) const
inline

Definition at line 1355 of file odbxx.h.

@ PRESERVE_STRING_SIZE
Definition odbxx.h:396
Here is the caller graph for this function:

◆ is_subkey()

bool midas::odb::is_subkey ( std::string  str)

Definition at line 544 of file odbxx.cxx.

544 {
545 if (m_tid != TID_KEY)
546 return false;
547
548 std::string first = str;
549 std::string tail{};
550 if (str.find('/') != std::string::npos) {
551 first = str.substr(0, str.find('/'));
552 tail = str.substr(str.find('/') + 1);
553 }
554
555 int i;
556 for (i = 0; i < m_num_values; i++)
557 if (m_data[i].get_odb().get_name() == first)
558 break;
559 if (i == m_num_values)
560 return false;
561
562 if (!tail.empty())
563 return m_data[i].get_odb().is_subkey(tail);
564
565 return true;
566 }
bool is_subkey(std::string str)
Definition odbxx.cxx:544
Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_trigger_hotlink()

bool midas::odb::is_trigger_hotlink ( ) const
inline

Definition at line 1394 of file odbxx.h.

Here is the caller graph for this function:

◆ is_write_protect()

bool midas::odb::is_write_protect ( ) const
inline

Definition at line 1388 of file odbxx.h.

@ WRITE_PROTECT
Definition odbxx.h:401
Here is the caller graph for this function:

◆ items()

odb & midas::odb::items ( )
inline

Definition at line 1457 of file odbxx.h.

1457{ return *this; }

◆ load()

void midas::odb::load ( const std::string &  filename,
const std::string &  odb_path 
)
static

Definition at line 102 of file odbxx.cxx.

102 {
103 init_hdb();
105 mthrow("Cannot connect to ODB");
106
107 HNDLE hkey;
108 auto status = db_find_key(s_hDB, 0, odb_path.c_str(), &hkey);
109 if (status == DB_NO_KEY)
110 db_create_key(s_hDB, 0, odb_path.c_str(), TID_KEY);
111 status = db_find_key(s_hDB, 0, odb_path.c_str(), &hkey);
112 if (status != DB_SUCCESS)
113 mthrow("ODB path " + odb_path + " not found in ODB");
114
115 KEY key;
116 db_get_key(s_hDB, hkey, &key);
117 if (key.type != TID_KEY)
118 mthrow("ODB path " + odb_path + " does not point to a directory");
119
120 db_load(s_hDB, hkey, filename.c_str(), false);
121 }
#define DB_NO_KEY
Definition midas.h:643
INT db_load(HNDLE hDB, HNDLE hKeyRoot, const char *filename, BOOL bRemote)
Definition odb.cxx:8139
DWORD type
Definition midas.h:1028
Here is the call graph for this function:

◆ node_to_string()

static std::string midas::odb::node_to_string ( const MJsonNode *  node)
inlinestatic

Definition at line 1254 of file odbxx.h.

1254 {
1255 std::string value;
1256
1257 switch (node->GetType()) {
1258 case MJSON_STRING:
1259 value = node->GetString();
1260 break;
1261 case MJSON_INT:
1262 value = std::to_string(node->GetInt());
1263 break;
1264 case MJSON_NUMBER:
1265 value = std::to_string(node->GetDouble());
1266 break;
1267 case MJSON_BOOL:
1268 value = std::to_string(node->GetBool());
1269 break;
1270 default:
1271 mthrow("Invalid MJSON type \"" + std::to_string(node->GetType()) + "\"");
1272 }
1273
1274 return value;
1275 };
double value[100]
Definition odbhist.cxx:42
Here is the caller graph for this function:

◆ odb_from_json()

static midas::odb * midas::odb::odb_from_json ( const MJsonNode *  node,
std::string  name,
int  tid,
odb o 
)
inlinestatic

Definition at line 1278 of file odbxx.h.

1278 {
1279 int type = node->GetType();
1280
1281 if (type == MJSON_OBJECT) { // subdir
1282 const MJsonStringVector* names = node->GetObjectNames();
1283 const MJsonNodeVector* nodes = node->GetObjectNodes();
1284 if (names == nullptr || nodes==nullptr || names->size() != nodes->size())
1285 mthrow("Invalid JSON format");
1286
1287 if (o == nullptr)
1288 o = new midas::odb();
1289 o->set_tid(TID_KEY);
1290 o->set_name(name);
1291 o->set_hkey(0);
1292
1293 // count subkeys
1294 int n=0;
1295 for (int i=0 ; i<(int)names->size() ; i++) {
1296 const char *name = (*names)[i].c_str();
1297
1298 if (strchr(name, '/'))// skip special entries
1299 continue;
1300 n++;
1301 }
1302 o->set_num_values(n);
1303
1304 for (int i=n=0 ; i<(int)names->size() ; i++) {
1305 const char *name = (*names)[i].c_str();
1306
1307 if (strchr(name, '/'))// skip special entries
1308 continue;
1309
1310 int t = 0;
1311 auto key = node->FindObjectNode((std::string(name) + "/key").c_str());
1312 if (key)
1313 t = key->FindObjectNode("type")->GetInt();
1314 else
1315 t = TID_KEY;
1316
1317 midas::odb *os = odb_from_json((*nodes)[i], (*names)[i].c_str(), t, nullptr);
1318 os->set_parent(o);
1319 o->set_odb(os, n);
1320 n++;
1321 }
1322
1323 o->set_num_values(n);
1324
1325 } else { // key
1326
1327 if (o == nullptr)
1328 o = new midas::odb();
1329
1330 o->set_name(name);
1331 o->set_tid(tid);
1332 o->set_hkey(0);
1333
1334 if (node->GetType() == MJSON_ARRAY) {
1335 const MJsonNodeVector* a = node->GetArray();
1336 o->set_num_values(a->size());
1337 for (int i=0 ; i<(int)a->size() ; i++) {
1338 MJsonNode *n = (*a)[i];
1339 auto value = node_to_string(n);
1340 o->set(value, i);
1341 }
1342 } else {
1343 auto value = node_to_string(node);
1344 o->set(value);
1345 }
1346 }
1347
1348 return o;
1349 };
static std::string node_to_string(const MJsonNode *node)
Definition odbxx.h:1254
static midas::odb * odb_from_json(const MJsonNode *node, std::string name, int tid, odb *o)
Definition odbxx.h:1278
Here is the call graph for this function:
Here is the caller graph for this function:

◆ odb_from_json_string() [1/2]

void midas::odb::odb_from_json_string ( const std::string &  str)
static

Definition at line 240 of file odbxx.cxx.

240 {
241
242 MJsonNode* node = MJsonNode::Parse(str.c_str());
243 if (node->GetType() == MJSON_ERROR)
244 mthrow("Error parsing JSON: " + node->GetError());
245
246 // node->Dump();
247
248 odb_from_json(node, "root", TID_KEY, s_odb);
249
250 delete node;
251
252 s_odb->set_auto_create(false);
258 }
void set_auto_refresh_read(bool f)
Definition odbxx.h:1362
void set_auto_enlarge_array(bool f)
Definition odbxx.h:1383
void set_trigger_hotlink(bool f)
Definition odbxx.h:1395
void set_auto_refresh_write(bool f)
Definition odbxx.h:1368
void set_auto_create(bool f)
Definition odbxx.h:1377
void set_write_protect(bool f)
Definition odbxx.h:1389
Here is the call graph for this function:

◆ odb_from_json_string() [2/2]

void midas::odb::odb_from_json_string ( const std::string &  str,
const std::string &  subkey 
)
Here is the caller graph for this function:

◆ odb_from_xml()

static midas::odb * midas::odb::odb_from_xml ( PMXML_NODE  node,
odb o 
)
inlinestatic

Definition at line 1201 of file odbxx.h.

1201 {
1202 std::string type(mxml_get_name(node));
1203
1204 unsigned int tid = 0;
1205 if (type == "dir" || type == "odb")
1206 tid = TID_KEY;
1207 else {
1208 for (tid = 0; tid < TID_LAST; tid++) {
1209 if (equal_ustring(rpc_tid_name(tid), mxml_get_attribute(node, "type")))
1210 break;
1211 }
1212 }
1213 if (tid == TID_LAST)
1214 mthrow("Wrong key type in XML file");
1215
1216 if (o == nullptr)
1217 o = new midas::odb();
1218 o->set_tid(tid);
1219 if (type == "odb") {
1220 o->set_name("root");
1221 o->set_hkey(0);
1222 } else {
1223 o->set_name(mxml_get_attribute(node, "name"));
1224 if (mxml_get_attribute(node, "handle") == nullptr)
1225 mthrow("No \"handle\" attribute found in XML data");
1226 o->set_hkey(std::stoi(std::string(mxml_get_attribute(node, "handle"))));
1227 }
1228
1229 if (type == "key") {
1230 std::string value(mxml_get_value(node));
1231 o->set(value);
1232 } else if (type == "keyarray") {
1233 int n = std::atoi(mxml_get_attribute(node, "num_values"));
1234 o->set_num_values(n);
1235 for (int i=0 ; i<n ; i++) {
1236 std::string value(mxml_get_value(mxml_subnode(node, i)));
1237 o->set(value, i);
1238 }
1239 } else if (type == "dir" || type == "odb") {
1240 int n = mxml_get_number_of_children(node);
1241 o->set_num_values(n);
1242 for (int i = 0; i < n; i++) {
1243 midas::odb *os = odb_from_xml(mxml_subnode(node, i), nullptr);
1244 os->set_parent(o);
1245 o->set_odb(os, i);
1246 }
1247 } else
1248 mthrow("Unexpected XML element " + std::string(mxml_get_name(node)));
1249
1250 return o;
1251 };
static midas::odb * odb_from_xml(PMXML_NODE node, odb *o)
Definition odbxx.h:1201
#define TID_LAST
Definition midas.h:354
const char * rpc_tid_name(INT id)
Definition midas.cxx:11895
Here is the call graph for this function:
Here is the caller graph for this function:

◆ odb_from_xml_remote()

void midas::odb::odb_from_xml_remote ( const std::string &  str)

Definition at line 160 of file odbxx.cxx.

160 {
161 init_hdb();
162
163 HNDLE hKey;
164 int status = db_find_key(s_hDB, 0, str.c_str(), &hKey);
165 if (status != DB_SUCCESS)
166 mthrow("ODB key \"" + str + "\" not found in ODB");
167
168 int bsize = 1000000;
169 char *buffer = (char *)malloc(bsize);
170 do {
171 int size = bsize;
172 status = db_copy_xml(s_hDB, hKey, buffer, &size, false);
173 if (status == DB_TRUNCATED) {
174 bsize *= 2;
175 buffer = (char *)realloc(buffer, bsize);
176 }
177 } while (status == DB_TRUNCATED);
178
179 if (status != DB_SUCCESS)
180 mthrow("Cannot retrieve XML data, status = " + std::to_string(status));
181
182 if (s_debug)
183 std::cout << "Retrieved XML tree for \"" + str + "\"" << std::endl;
184
185 char error[256] = "";
186 PMXML_NODE tree = mxml_parse_buffer(buffer, error, sizeof(error), NULL);
187 if (error[0]) {
188 std::cout << "MXML error, buffer =\n" << buffer << std::endl;
189 mthrow("MXML error: " + std::string(error));
190 }
191 free(buffer);
192
193 odb_from_xml(&tree->child[2], this);
194 m_hKey = hKey;
195
196 mxml_free_tree(tree);
197 }
int size()
Definition odbxx.cxx:386
#define DB_TRUNCATED
Definition midas.h:645
INT db_copy_xml(HNDLE hDB, HNDLE hKey, char *buffer, int *buffer_size, bool header)
Definition odb.cxx:9055
Here is the call graph for this function:
Here is the caller graph for this function:

◆ odb_from_xml_string() [1/2]

void midas::odb::odb_from_xml_string ( const std::string &  str)
static

Definition at line 199 of file odbxx.cxx.

199 {
200 char error[256] = "";
201 PMXML_NODE tree = mxml_parse_buffer(str.c_str(), error, sizeof(error), NULL);
202 if (error[0]) {
203 std::cout << "MXML error, buffer =\n" << str << std::endl;
204 mthrow("MXML error: " + std::string(error));
205 }
206
207 PMXML_NODE root;
208 root = &tree->child[2];
209
210 odb_from_xml(root, s_odb);
211
212 mxml_free_tree(tree);
213
214 s_odb->set_auto_create(false);
220 }
Here is the call graph for this function:

◆ odb_from_xml_string() [2/2]

void midas::odb::odb_from_xml_string ( const std::string &  str,
const std::string &  subkey 
)
Here is the caller graph for this function:

◆ operator std::string()

midas::odb::operator std::string ( )
inline

Definition at line 887 of file odbxx.h.

887 {
888 std::string s;
889 if (m_tid == TID_KEY)
890 print(s, 0);
891 else
892 get(s); // forward to get(std::string)
893 return s;
894 }
std::string print()
Definition odbxx.cxx:419
Here is the call graph for this function:

◆ operator std::vector< std::string >()

midas::odb::operator std::vector< std::string > ( )
inline

Definition at line 907 of file odbxx.h.

907 {
909 read();
910 std::vector<std::string> v(m_num_values);
911 for (int i = 0; i < m_num_values; i++)
912 v[i] = m_data[i].get();
913 return v;
914 }
Here is the call graph for this function:

◆ operator std::vector< T >()

template<typename T >
midas::odb::operator std::vector< T > ( )
inline

Definition at line 898 of file odbxx.h.

898 {
900 read();
901 std::vector<T> v(m_num_values);
902 for (int i = 0; i < m_num_values; i++)
903 v[i] = m_data[i];
904 return v;
905 }
Here is the call graph for this function:

◆ operator T()

template<typename T , typename std::enable_if< std::is_same< T, uint8_t >::value||std::is_same< T, int8_t >::value||std::is_same< T, uint16_t >::value||std::is_same< T, int16_t >::value||std::is_same< T, uint32_t >::value||std::is_same< T, int32_t >::value||std::is_same< T, uint64_t >::value||std::is_same< T, int64_t >::value||std::is_same< T, bool >::value||std::is_same< T, float >::value||std::is_same< T, double >::value, T >::type * = nullptr>
midas::odb::operator T ( )
inline

Definition at line 929 of file odbxx.h.

929 {
930 if (m_tid == 0)
931 mthrow("Element \"" + m_name + "\" not found");
932 return get<T>(); // forward to get<T>()
933 }

◆ operator()()

template<typename T >
odb & midas::odb::operator() ( v)
inline

Definition at line 991 of file odbxx.h.

991 {
992 if (m_tid == 0) {
993 if (m_num_values == 0) {
994 // initialize this
995 m_num_values = 1;
996 m_tid = detect_type(v);
997 m_data = new u_odb[1]{};
998 m_data[0].set_tid(m_tid);
999 m_data[0].set_parent(this);
1000 m_data[0].set(v);
1001 if (this->is_auto_refresh_write())
1002 write();
1003 } else {
1004 for (int i = 0; i < m_num_values; i++)
1005 m_data[i].set(v);
1006 if (this->is_auto_refresh_write())
1007 write();
1008 }
1009 }
1010 return *this;
1011 }
bool is_auto_refresh_write() const
Definition odbxx.h:1367
int detect_type(const T &)
Definition odbxx.h:745
#define set(var, value)
Here is the call graph for this function:

◆ operator*()

template<typename T >
T midas::odb::operator* ( const T  i)
inline

Definition at line 1067 of file odbxx.h.

1067 {
1068 if (m_num_values > 1)
1069 mthrow("ODB key \"" + get_full_path() +
1070 "\" contains array which cannot be used in basic arithmetic operation.");
1072 read();
1073 T s = (T) m_data[0];
1074 return s * i;
1075 }
Here is the call graph for this function:

◆ operator*=()

odb & midas::odb::operator*= ( double  d)
inline

Definition at line 1152 of file odbxx.h.

1152 {
1154 read();
1155 for (int i = 0; i < m_num_values; i++)
1156 m_data[i].mult(d, false);
1157 if (this->is_auto_refresh_write())
1158 write();
1159 return *this;
1160 }
Here is the call graph for this function:

◆ operator+()

template<typename T >
T midas::odb::operator+ ( i)
inline

Definition at line 1023 of file odbxx.h.

1023 {
1024 if (m_num_values > 1)
1025 mthrow("ODB key \"" + get_full_path() +
1026 "\" contains array which cannot be used in basic arithmetic operation.");
1027 if (std::is_same<T, midas::odb>::value) {
1028 if (is_auto_refresh_read()) {
1029 read();
1030 i.read();
1031 }
1032 // adding two midas::odb objects is best done in double
1033 double s1 = static_cast<double>(m_data[0]);
1034 double s2 = static_cast<double>(i.m_data[0]);
1035 return s1 + s2;
1036 } else {
1038 read();
1039 T s = (T) m_data[0];
1040 return s + i;
1041 }
1042 }
Here is the call graph for this function:

◆ operator++() [1/2]

odb & midas::odb::operator++ ( )
inline

Definition at line 1088 of file odbxx.h.

1088 {
1090 read();
1091 for (int i = 0; i < m_num_values; i++)
1092 m_data[i].add(1, false);
1093 if (this->is_auto_refresh_write())
1094 write();
1095 return *this;
1096 }
INT add
Definition odbhist.cxx:40
Here is the call graph for this function:

◆ operator++() [2/2]

odb midas::odb::operator++ ( int  )
inline

Definition at line 1098 of file odbxx.h.

1098 {
1099 // create temporary object
1100 odb o(this);
1102 read();
1103 for (int i = 0; i < m_num_values; i++)
1104 m_data[i].add(1, false);
1105 if (this->is_auto_refresh_write())
1106 write();
1107 return o;
1108 }
Here is the call graph for this function:

◆ operator+=()

odb & midas::odb::operator+= ( double  d)
inline

Definition at line 1132 of file odbxx.h.

1132 {
1134 read();
1135 for (int i = 0; i < m_num_values; i++)
1136 m_data[i].add(d, false);
1137 if (this->is_auto_refresh_write())
1138 write();
1139 return *this;
1140 }
Here is the call graph for this function:

◆ operator-()

template<typename T >
T midas::odb::operator- ( i)
inline

Definition at line 1045 of file odbxx.h.

1045 {
1046 if (m_num_values > 1)
1047 mthrow("ODB key \"" + get_full_path() +
1048 "\" contains array which cannot be used in basic arithmetic operation.");
1049 if (std::is_same<T, midas::odb>::value) {
1050 if (is_auto_refresh_read()) {
1051 read();
1052 i.read();
1053 }
1054 // subtracting two midas::odb objects is best done in double
1055 double s1 = static_cast<double>(m_data[0]);
1056 double s2 = static_cast<double>(i.m_data[0]);
1057 return s1 - s2;
1058 } else {
1060 read();
1061 T s = (T) m_data[0];
1062 return s - i;
1063 }
1064 }
Here is the call graph for this function:

◆ operator--() [1/2]

odb & midas::odb::operator-- ( )
inline

Definition at line 1110 of file odbxx.h.

1110 {
1112 read();
1113 for (int i = 0; i < m_num_values; i++)
1114 m_data[i].add(-1, false);
1115 if (this->is_auto_refresh_write())
1116 write();
1117 return *this;
1118 }
Here is the call graph for this function:

◆ operator--() [2/2]

odb midas::odb::operator-- ( int  )
inline

Definition at line 1120 of file odbxx.h.

1120 {
1121 // create temporary object
1122 odb o(this);
1124 read();
1125 for (int i = 0; i < m_num_values; i++)
1126 m_data[i].add(-1, false);
1127 if (this->is_auto_refresh_write())
1128 write();
1129 return o;
1130 }
Here is the call graph for this function:

◆ operator-=()

odb & midas::odb::operator-= ( double  d)
inline

Definition at line 1142 of file odbxx.h.

1142 {
1144 read();
1145 for (int i = 0; i < m_num_values; i++)
1146 m_data[i].add(-d, false);
1147 if (this->is_auto_refresh_write())
1148 write();
1149 return *this;
1150 }
Here is the call graph for this function:

◆ operator/()

template<typename T >
T midas::odb::operator/ ( const T  i)
inline

Definition at line 1078 of file odbxx.h.

1078 {
1079 if (m_num_values > 1)
1080 mthrow("ODB key \"" + get_full_path() +
1081 "\" contains array which cannot be used in basic arithmetic operation.");
1083 read();
1084 T s = (T) m_data[0];
1085 return s / i;
1086 }
Here is the call graph for this function:

◆ operator/=()

odb & midas::odb::operator/= ( double  d)
inline

Definition at line 1162 of file odbxx.h.

1162 {
1164 read();
1165 if (d == 0)
1166 mthrow("Division by zero");
1167 for (int i = 0; i < m_num_values; i++)
1168 m_data[i].mult(1 / d, false);
1169 if (this->is_auto_refresh_write())
1170 write();
1171 return *this;
1172 }
Here is the call graph for this function:

◆ operator=() [1/4]

template<typename T , size_t SIZE>
const std::array< T, SIZE > & midas::odb::operator= ( const std::array< T, SIZE > &  arr)
inline

Definition at line 855 of file odbxx.h.

855 {
856
857 if (this->is_write_protect())
858 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
859
860 if (m_num_values == 0) {
861 // initialize this
863 m_tid = detect_type(arr[0]);
864 m_data = new u_odb[m_num_values]{};
865 for (int i = 0; i < m_num_values; i++) {
867 m_data[i].set_parent(this);
868 }
869
870 } else {
871
872 // resize internal array if different
873 if (SIZE != m_num_values) {
875 }
876 }
877
878 for (int i = 0; i < m_num_values; i++)
879 m_data[i].set(arr[i]);
880
881 if (this->is_auto_refresh_write())
882 write();
883 return arr;
884 }
Here is the call graph for this function:

◆ operator=() [2/4]

template<typename T >
const std::vector< T > & midas::odb::operator= ( const std::vector< T > &  v)
inline

Definition at line 809 of file odbxx.h.

809 {
810
811 if (this->is_write_protect())
812 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
813
814 if (m_num_values == 0) {
815 // initialize this
816 m_num_values = v.size();
817 if (std::is_same<T, bool>::value) {
818 // Special logic for vector<bool>, which may not be a true
819 // container: it's often optimized to be a bitfield, with
820 // references to elements being masked bits rather than bools.
821 // So T is a bool here, but typeof(v[0]) may not be bool!
822 // "Fake container optimization" only applies to vector<bool>,
823 // not array<bool> or any other vector<T>.
824 m_tid = TID_BOOL;
825 } else {
826 // Every other type can be detected using ref to first element.
827 m_tid = detect_type(v[0]);
828 }
829
830 m_data = new u_odb[m_num_values]{};
831 for (int i = 0; i < m_num_values; i++) {
833 m_data[i].set_parent(this);
834 }
835
836 } else {
837
838 // resize internal array if different
839 if ((int)v.size() != m_num_values) {
840 resize_mdata(v.size());
841 }
842 }
843
844 for (int i = 0; i < m_num_values; i++)
845 m_data[i].set(v[i]);
846
847 if (this->is_auto_refresh_write())
848 write();
849
850 return v;
851 }
Here is the call graph for this function:

◆ operator=() [3/4]

template<typename T >
const T & midas::odb::operator= ( const T &  v)
inline

Definition at line 782 of file odbxx.h.

782 {
783
784 if (this->is_write_protect())
785 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
786
787 if (m_num_values == 0) {
788 // initialize this
789 m_num_values = 1;
790 m_tid = detect_type(v);
791 m_data = new u_odb[1]{};
792 m_data[0].set_tid(m_tid);
793 m_data[0].set_parent(this);
794 m_data[0].set(v);
795 if (this->is_auto_refresh_write())
796 write();
797 } else {
798 for (int i = 0; i < m_num_values; i++)
799 m_data[i].set(v);
800
801 if (this->is_auto_refresh_write())
802 write();
803 }
804 return v;
805 }
Here is the call graph for this function:

◆ operator=() [4/4]

odb midas::odb::operator= ( odb &&  o)
delete

◆ operator[]() [1/3]

odb & midas::odb::operator[] ( const char *  str)
inline

Definition at line 985 of file odbxx.h.

985 {
986 return get_subkey(std::string(str));
987 }
Here is the call graph for this function:

◆ operator[]() [2/3]

u_odb & midas::odb::operator[] ( int  index)
inline

Definition at line 947 of file odbxx.h.

947 {
948 if (this->is_write_protect())
949 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
950
951 if (index < 0)
952 throw std::out_of_range("Index \"" + std::to_string(index) + "\" out of range for ODB key \"" + get_full_path() + "[0..." + std::to_string(m_num_values - 1) + "]\"");
953
954 if (index == 0 && m_num_values == 0) {
955 // initialize this
956 m_num_values = 1;
957 m_tid = 0;
958 m_data = new u_odb[1]{};
959 m_data[0].set_tid(m_tid);
960 m_data[0].set_parent(this);
961 m_last_index = 0;
962 return m_data[0];
963 } else if (index >= m_num_values) {
964 if (is_auto_enlarge_array()) {
966 if (this->is_auto_refresh_write())
967 write(index, 0);
968 } else {
969 throw std::out_of_range("Index \"" + std::to_string(index) + "\" out of range for ODB key \"" + get_full_path() + "[0..." + std::to_string(m_num_values - 1) + "]\", please consider set_auto_enlarge_array(true)");
970 }
971 }
972
974 read(index);
975
977 return m_data[index];
978 }
bool is_auto_enlarge_array() const
Definition odbxx.h:1382
Here is the call graph for this function:

◆ operator[]() [3/3]

odb & midas::odb::operator[] ( std::string  str)
inline

Definition at line 981 of file odbxx.h.

981 {
982 return get_subkey(str);
983 }
Here is the call graph for this function:

◆ print() [1/2]

std::string midas::odb::print ( )

Definition at line 419 of file odbxx.cxx.

419 {
420 std::string s;
421 s = "{\n";
422 print(s, 1);
423 s += "\n}";
424 return s;
425 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ print() [2/2]

void midas::odb::print ( std::string &  s,
int  indent = 0 
)

Definition at line 436 of file odbxx.cxx.

436 {
437 for (int i = 0; i < indent; i++)
438 s += " ";
439 if (m_tid == TID_KEY) {
440 s += "\"" + m_name + "\": {\n";
441 for (int i = 0; i < m_num_values; i++) {
442 std::string v;
443 // recursive call
444 m_data[i].get_odb().print(v, indent + 1);
445 s += v;
446 if (i < m_num_values - 1)
447 s += ",\n";
448 else
449 s += "\n";
450 }
451 for (int i = 0; i < indent; i++)
452 s += " ";
453 s += "}";
454 } else {
455 s += "\"" + m_name + "\": ";
456 if (m_num_values > 1)
457 s += "[";
458 std::string v;
459 get(v, m_tid == TID_STRING || m_tid == TID_LINK);
460 if (m_tid == TID_LINK)
461 s += " -> ";
462 s += v;
463 if (m_num_values > 1)
464 s += "]";
465 }
466 }
Here is the call graph for this function:

◆ read() [1/2]

void midas::odb::read ( )

Definition at line 802 of file odbxx.cxx.

802 {
803 if (!is_connected_odb())
804 return;
805
806 // check if deleted
807 if (is_deleted())
808 mthrow("ODB key \"" + m_name + "\" cannot be pulled because it has been deleted");
809
810 if (m_hKey == 0)
811 return; // needed to print un-connected objects
812
813 if (m_tid == 0)
814 mthrow("Read of invalid ODB key \"" + m_name + "\"");
815
816 if (m_hKey == -1) {
817 // connect un-connected object (crated via XML)
818 std::string path = get_full_path();
819
820 int status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
821 if (status != DB_SUCCESS)
822 mthrow("Cannot connect key \"" + path + "\" to ODB");
823 }
824
825 int status{};
826 if (m_tid == TID_STRING) {
827 KEY key;
829 char *str = (char *) malloc(key.total_size);
830 int size = key.total_size;
832 for (int i = 0; i < m_num_values; i++)
833 m_data[i].set(str + i * key.item_size);
834 free(str);
835 } else if (m_tid == TID_KEY) {
836 std::vector<std::string> name;
837 int n = get_subkeys(name);
838 if (n != m_num_values) {
839 // if subdirs have changed, rebuild it
840 delete[] m_data;
841 m_num_values = n;
843 for (int i = 0; i < m_num_values; i++) {
844 std::string k(get_full_path());
845 k += "/" + name[i];
846 midas::odb *o = new midas::odb(k.c_str());
847 o->set_parent(this);
849 m_data[i].set_parent(this);
850 m_data[i].set(o);
851 }
852 }
853 for (int i = 0; i < m_num_values; i++)
854 m_data[i].get_odb().read();
856 } else {
857 // resize local array if number of values has changed
858 KEY key;
860 if (key.num_values != m_num_values) {
861 delete[] m_data;
864 for (int i = 0; i < m_num_values; i++) {
866 m_data[i].set_parent(this);
867 }
868 }
869
871 void *buffer = malloc(size);
872 void *p = buffer;
874 for (int i = 0; i < m_num_values; i++) {
875 if (m_tid == TID_UINT8)
876 m_data[i].set(*static_cast<uint8_t *>(p));
877 else if (m_tid == TID_INT8)
878 m_data[i].set(*static_cast<int8_t *>(p));
879 else if (m_tid == TID_UINT16)
880 m_data[i].set(*static_cast<uint16_t *>(p));
881 else if (m_tid == TID_INT16)
882 m_data[i].set(*static_cast<int16_t *>(p));
883 else if (m_tid == TID_UINT32)
884 m_data[i].set(*static_cast<uint32_t *>(p));
885 else if (m_tid == TID_INT32)
886 m_data[i].set(*static_cast<int32_t *>(p));
887 else if (m_tid == TID_UINT64)
888 m_data[i].set(*static_cast<uint64_t *>(p));
889 else if (m_tid == TID_INT64)
890 m_data[i].set(*static_cast<int64_t *>(p));
891 else if (m_tid == TID_BOOL)
892 m_data[i].set(*static_cast<bool *>(p));
893 else if (m_tid == TID_FLOAT)
894 m_data[i].set(*static_cast<float *>(p));
895 else if (m_tid == TID_DOUBLE)
896 m_data[i].set(*static_cast<double *>(p));
897 else if (m_tid == TID_STRING)
898 m_data[i].set(std::string(static_cast<const char *>(p)));
899 else if (m_tid == TID_LINK)
900 m_data[i].set(std::string(static_cast<const char *>(p)));
901 else
902 mthrow("Invalid type ID " + std::to_string(m_tid));
903
904 p = static_cast<char *>(p) + rpc_tid_size(m_tid);
905 }
906 free(buffer);
907 }
908
909 if (status != DB_SUCCESS)
910 mthrow("db_get_data for ODB key \"" + get_full_path() +
911 "\" failed with status " + std::to_string(status));
912 if (s_debug) {
913 if (m_tid == TID_KEY) {
914 std::cout << "Get ODB key \"" + get_full_path() + "[0..." +
915 std::to_string(m_num_values - 1) + "]\"" << std::endl;
916 } else {
917 std::string s;
918 get(s, false, false);
919 if (m_num_values > 1) {
920 if (m_tid == TID_STRING || m_tid == TID_LINK)
921 std::cout << "Get ODB key \"" + get_full_path() + "[0..." +
922 std::to_string(m_num_values - 1) + "]\": [\"" + s + "\"]" << std::endl;
923 else
924 std::cout << "Get ODB key \"" + get_full_path() + "[0..." +
925 std::to_string(m_num_values - 1) + "]\": [" + s + "]" << std::endl;
926 } else {
927 if (m_tid == TID_STRING || m_tid == TID_LINK)
928 std::cout << "Get ODB key \"" + get_full_path() + "\": \"" + s + "\"" << std::endl;
929 else
930 std::cout << "Get ODB key \"" + get_full_path() + "\": " + s << std::endl;
931 }
932 }
933 }
934 }
bool is_deleted() const
Definition odbxx.h:530
INT db_get_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
Definition odb.cxx:6563
INT rpc_tid_size(INT id)
Definition midas.cxx:11888
INT k
Definition odbhist.cxx:40
INT num_values
Definition midas.h:1029
INT total_size
Definition midas.h:1032
INT item_size
Definition midas.h:1033
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read() [2/2]

void midas::odb::read ( int  index)

Definition at line 937 of file odbxx.cxx.

937 {
938 if (!is_connected_odb())
939 return;
940
941 if (m_hKey == 0 || m_hKey == -1)
942 return; // needed to print un-connected objects
943
944 if (m_tid == 0)
945 mthrow("Pull of invalid ODB key \"" + m_name + "\"");
946
947 int status{};
948 if (m_tid == TID_STRING || m_tid == TID_LINK) {
949 KEY key;
951 char *str = (char *) malloc(key.item_size);
952 int size = key.item_size;
955 free(str);
956 } else if (m_tid == TID_KEY) {
959 } else {
960 int size = rpc_tid_size(m_tid);
961 void *buffer = malloc(size);
962 void *p = buffer;
964 if (m_tid == TID_UINT8)
965 m_data[index].set(*static_cast<uint8_t *>(p));
966 else if (m_tid == TID_INT8)
967 m_data[index].set(*static_cast<int8_t *>(p));
968 else if (m_tid == TID_UINT16)
969 m_data[index].set(*static_cast<uint16_t *>(p));
970 else if (m_tid == TID_INT16)
971 m_data[index].set(*static_cast<int16_t *>(p));
972 else if (m_tid == TID_UINT32)
973 m_data[index].set(*static_cast<uint32_t *>(p));
974 else if (m_tid == TID_INT32)
975 m_data[index].set(*static_cast<int32_t *>(p));
976 else if (m_tid == TID_UINT64)
977 m_data[index].set(*static_cast<uint64_t *>(p));
978 else if (m_tid == TID_INT64)
979 m_data[index].set(*static_cast<int64_t *>(p));
980 else if (m_tid == TID_BOOL)
981 m_data[index].set(*static_cast<bool *>(p));
982 else if (m_tid == TID_FLOAT)
983 m_data[index].set(*static_cast<float *>(p));
984 else if (m_tid == TID_DOUBLE)
985 m_data[index].set(*static_cast<double *>(p));
986 else if (m_tid == TID_STRING)
987 m_data[index].set(std::string(static_cast<const char *>(p)));
988 else if (m_tid == TID_LINK)
989 m_data[index].set(std::string(static_cast<const char *>(p)));
990 else
991 mthrow("Invalid type ID " + std::to_string(m_tid));
992
993 free(buffer);
994 }
995
996 if (status != DB_SUCCESS)
997 mthrow("db_get_data for ODB key \"" + get_full_path() +
998 "\" failed with status " + std::to_string(status));
999 if (s_debug) {
1000 std::string s;
1001 m_data[index].get(s);
1002 if (m_tid == TID_STRING || m_tid == TID_LINK)
1003 std::cout << "Get ODB key \"" + get_full_path() + "[" +
1004 std::to_string(index) + "]\": [\"" + s + "\"]" << std::endl;
1005 else
1006 std::cout << "Get ODB key \"" + get_full_path() + "[" +
1007 std::to_string(index) + "]\": [" + s + "]" << std::endl;
1008 }
1009 }
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
Definition odb.cxx:6917
Here is the call graph for this function:

◆ read_key()

bool midas::odb::read_key ( const std::string &  path)
private

Definition at line 657 of file odbxx.cxx.

657 {
658 init_hdb();
659
660 int status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
661 if (status != DB_SUCCESS)
662 return false;
663
664 KEY key;
666 if (status != DB_SUCCESS)
667 mthrow("db_get_key for ODB key \"" + path +
668 "\" failed with status " + std::to_string(status));
669
670 // check for correct type if given as parameter
671 if (m_tid > 0 && m_tid != (int) key.type)
672 mthrow("ODB key \"" + get_full_path() +
673 "\" has different type than specified");
674
675 if (s_debug)
676 std::cout << "Get definition for ODB key \"" + get_full_path() + "\"" << std::endl;
677
678 m_tid = key.type;
679 m_name = key.name;
680 if (m_tid == TID_KEY) {
681
682 // merge ODB keys with local keys
683 for (int i = 0; i < m_num_values; i++) {
684 std::string p(path);
685 if (p.back() != '/')
686 p += "/";
687 p += m_data[i].get_odb().get_name();
688 HNDLE h;
689 status = db_find_key(s_hDB, 0, p.c_str(), &h);
690 if (status != DB_SUCCESS) {
691 // if key does not exist in ODB write it
692 m_data[i].get_odb().write_key(p, true);
693 m_data[i].get_odb().write();
694 } else {
695 // check key type
696 KEY key;
697 status = db_get_key(s_hDB, h, &key);
698 if (status != DB_SUCCESS)
699 mthrow("db_get_key for ODB key \"" + get_full_path() +
700 "\" failed with status " + std::to_string(status));
701 if (m_data[i].get_odb().get_tid() != (int)key.type) {
702 // write key if different
703 m_data[i].get_odb().write_key(p, true);
704 m_data[i].get_odb().write();
705 }
706 if (m_data[i].get_odb().get_tid() == TID_KEY) {
707 // update subkey structure
708 m_data[i].get_odb().read_key(p);
709 }
710 }
711 }
712
713 // read back everything from ODB
714 std::vector<std::string> name;
716 delete[] m_data;
718 for (int i = 0; i < m_num_values; i++) {
719 std::string p(path);
720 if (p.back() != '/')
721 p += "/";
722 p += name[i];
723 midas::odb *o = new midas::odb(p.c_str());
724 o->set_parent(this);
726 m_data[i].set_parent(this);
727 m_data[i].set(o);
728 }
729 } else {
731 delete[] m_data;
733 for (int i = 0; i < m_num_values; i++) {
735 m_data[i].set_parent(this);
736 }
737 }
738
739 return true;
740 }
void write(int str_size=0)
Definition odbxx.cxx:1113
int get_tid()
Definition odbxx.h:1454
Here is the call graph for this function:
Here is the caller graph for this function:

◆ resize() [1/2]

void midas::odb::resize ( int  size)

Definition at line 391 of file odbxx.cxx.

391 {
393 if (this->is_auto_refresh_write()) {
395 if (status != DB_SUCCESS)
396 mthrow("db_set_num_values for ODB key \"" + get_full_path() +
397 "\" failed with status " + std::to_string(status));
398 }
399 }
INT db_set_num_values(HNDLE hDB, HNDLE hKey, INT num_values)
Definition odb.cxx:7523
Here is the call graph for this function:
Here is the caller graph for this function:

◆ resize() [2/2]

void midas::odb::resize ( int  size,
bool  b 
)

Definition at line 402 of file odbxx.cxx.

402 {
403 int old_size = m_num_values;
405 if (this->is_auto_refresh_write()) {
407 if (status != DB_SUCCESS)
408 mthrow("db_set_num_values for ODB key \"" + get_full_path() +
409 "\" failed with status " + std::to_string(status));
410 }
411 if (size > old_size) {
412 for (int i=old_size ; i<size ; i++)
413 m_data[i] = b;
414 if (this->is_auto_refresh_write())
415 write();
416 }
417 }
Here is the call graph for this function:

◆ resize_mdata()

void midas::odb::resize_mdata ( int  size)
private

Definition at line 261 of file odbxx.cxx.

261 {
262 auto new_array = new u_odb[size]{};
263 int i;
264 for (i = 0; i < m_num_values && i < size; i++) {
265 new_array[i] = m_data[i];
266 if (m_tid == TID_KEY)
267 m_data[i].set_odb(nullptr); // move odb*
268 if (m_tid == TID_STRING || m_tid == TID_LINK)
269 m_data[i].set_string_ptr(nullptr); // move std::string*
270 }
271 for (; i < size; i++) {
272 if (m_tid == TID_STRING || m_tid == TID_LINK)
273 new_array[i].set_string(""); // allocates new string
274 }
275 delete[] m_data;
276 m_data = new_array;
278 for (i = 0; i < m_num_values; i++) {
280 m_data[i].set_parent(this);
281 }
282 }
void set_odb(odb *v)
Definition odbxx.h:189
Here is the call graph for this function:
Here is the caller graph for this function:

◆ s()

std::string midas::odb::s ( )
inline

Definition at line 1459 of file odbxx.h.

1459 {
1460 std::string s;
1461 get(s);
1462 return s;
1463 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ save()

void midas::odb::save ( const std::string &  filename)

Definition at line 518 of file odbxx.cxx.

518 {
519 std::string buffer;
520
521 std::string header = "{\n";
522 header += " \"/MIDAS version\" : \"2.1\",\n";
523 header += " \"/filename\" : \"" + filename + "\",\n";
524
525 std::string path = get_full_path();
526 if (path == "")
527 path = "/";
528 header += " \"/ODB path\" : \"" + path + "\",\n\n";
529
530 odb::dump(buffer, 1);
531
532 buffer += "\n}\n";
533
534 std::ofstream f(filename);
535 if (!f.is_open())
536 mthrow("Cannot open file \"" + filename);
537
538 f << header << buffer;
539 f.close();
540 }
Here is the call graph for this function:

◆ search_hkey()

midas::odb * midas::odb::search_hkey ( midas::odb po,
int  hKey 
)
staticprivate

Definition at line 62 of file odbxx.cxx.

62 {
63 if (po->m_hKey == hKey)
64 return po;
65 if (po->m_tid == TID_KEY) {
66 for (int i = 0; i < po->m_num_values; i++) {
68 if (pot != nullptr)
69 return pot;
70 }
71 }
72 return nullptr;
73 }
static midas::odb * search_hkey(midas::odb *po, int hKey)
Definition odbxx.cxx:62
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set() [1/2]

void midas::odb::set ( std::string  s,
int  i 
)

Definition at line 1599 of file odbxx.cxx.

1600 {
1601 if (this->is_write_protect())
1602 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
1603
1604 if (m_tid == TID_BOOL)
1605 s = (s == "y" || s == "1") ? "1" : "0";
1606
1607 if (m_data == nullptr)
1608 m_data = new u_odb[m_num_values];
1609 m_data[i].set_parent(this);
1611 m_data[i].set(s);
1612 }
Here is the call graph for this function:

◆ set() [2/2]

void midas::odb::set ( std::string  str)

Definition at line 1584 of file odbxx.cxx.

1585 {
1586 if (this->is_write_protect())
1587 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
1588
1589 if (m_tid == TID_BOOL)
1590 s = (s == "y" || s == "1") ? "1" : "0";
1591
1592 m_num_values = 1;
1593 m_data = new u_odb[1];
1594 m_data[0].set_parent(this);
1595 m_data[0].set_tid(m_tid);
1596 m_data[0].set(s);
1597 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_auto_create()

void midas::odb::set_auto_create ( bool  f)
inline

Definition at line 1377 of file odbxx.h.

1377 {
1380 }
void set_flags_recursively(uint32_t f)
Definition odbxx.cxx:152
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_auto_enlarge_array()

void midas::odb::set_auto_enlarge_array ( bool  f)
inline

Definition at line 1383 of file odbxx.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_auto_refresh_read()

void midas::odb::set_auto_refresh_read ( bool  f)
inline

Definition at line 1362 of file odbxx.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_auto_refresh_write()

void midas::odb::set_auto_refresh_write ( bool  f)
inline

Definition at line 1368 of file odbxx.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_debug()

static void midas::odb::set_debug ( bool  flag)
inlinestatic

Definition at line 1401 of file odbxx.h.

1401{ s_debug = flag; }
Here is the caller graph for this function:

◆ set_deleted()

void midas::odb::set_deleted ( bool  f)
inlineprivate

Definition at line 531 of file odbxx.h.

Here is the caller graph for this function:

◆ set_dirty()

void midas::odb::set_dirty ( bool  f)
inline

Definition at line 1374 of file odbxx.h.

1374{ m_flags[odb_flags::DIRTY] = f; }

◆ set_flags()

void midas::odb::set_flags ( uint32_t  f)
inlineprivate

Definition at line 527 of file odbxx.h.

527{ m_flags = f; }
Here is the caller graph for this function:

◆ set_flags_recursively()

void midas::odb::set_flags_recursively ( uint32_t  f)
private

Definition at line 152 of file odbxx.cxx.

152 {
153 m_flags = f;
154 if (m_tid == TID_KEY) {
155 for (int i = 0; i < m_num_values; i++)
156 m_data[i].get_odb().set_flags_recursively(f);
157 }
158 }
Here is the caller graph for this function:

◆ set_hkey()

void midas::odb::set_hkey ( HNDLE  hKey)
inlineprivate

Definition at line 525 of file odbxx.h.

525{ m_hKey = hKey; }
Here is the caller graph for this function:

◆ set_last_index()

void midas::odb::set_last_index ( int  i)
inline

Definition at line 1015 of file odbxx.h.

1015{ m_last_index = i; }
Here is the caller graph for this function:

◆ set_mode()

void midas::odb::set_mode ( int  mode)

Definition at line 1502 of file odbxx.cxx.

1502 {
1503 // set mode of ODB key
1504 // default is MODE_READ | MODE_WRITE | MODE_DELETE
1505
1506 init_hdb();
1507
1508 // set mode in ODB
1509 int status = db_set_mode(s_hDB, m_hKey, mode, TRUE);
1510
1512 mthrow("db_set_mode for ODB key \"" + get_full_path() +
1513 "\" returnd error code " + std::to_string(status));
1514
1515 if (s_debug)
1516 std::cout << "Set mode of ODB key \"" + get_full_path() + "\" to " << mode << std::endl;
1517 }
INT db_set_mode(HNDLE hDB, HNDLE hKey, WORD mode, BOOL recurse)
Definition odb.cxx:8040
#define TRUE
Definition midas.h:182
Here is the call graph for this function:

◆ set_name()

void midas::odb::set_name ( std::string  s)
inlineprivate

Definition at line 536 of file odbxx.h.

536{ m_name = s; }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_num_values()

void midas::odb::set_num_values ( int  n)
inlineprivate

Definition at line 534 of file odbxx.h.

534{ m_num_values = n; }
Here is the caller graph for this function:

◆ set_odb()

void midas::odb::set_odb ( odb o,
int  i 
)

Definition at line 1628 of file odbxx.cxx.

1629 {
1630 if (this->is_write_protect())
1631 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
1632
1633 if (m_data == nullptr)
1634 m_data = new u_odb[m_num_values];
1635 m_data[i].set_parent(this);
1637 m_data[i].set_odb(o);
1638 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_odb_source() [1/2]

static void midas::odb::set_odb_source ( odb::odb_source  s)
inlinestatic

Definition at line 1416 of file odbxx.h.

1416 {
1417 if (s == STRING)
1418 mthrow1("ODB source STRING requires a string");
1419 if (s == FILE)
1420 mthrow1("ODB source FILE requires a filename");
1421 s_odb_source = s;
1422 }
#define mthrow1(arg)
Definition mexcept.h:27
Here is the call graph for this function:

◆ set_odb_source() [2/2]

void midas::odb::set_odb_source ( odb::odb_source  s,
std::string  str 
)
static

Definition at line 1640 of file odbxx.cxx.

1640 {
1641
1642 s_odb_source = s;
1644
1645 if (s_odb != nullptr)
1646 delete s_odb;
1647 s_odb = nullptr;
1648
1649 if (s == odb::FILE) {
1650 // check file contents
1651 std::ifstream file(str);
1652 if (!file)
1653 mthrow("File \"" + str + "\" not found");
1654 std::ostringstream ss;
1655 ss << file.rdbuf();
1656 file.close();
1657
1658 // create new root ODB object
1659 s_odb = new midas::odb();
1660
1661 // populate object from file string
1662 if (s_odb_source_str.find(".xml") != std::string::npos ||
1663 s_odb_source_str.find(".XML") != std::string::npos)
1664 odb_from_xml_string(ss.str());
1665 else if (s_odb_source_str.find(".json") != std::string::npos ||
1666 s_odb_source_str.find(".JSON") != std::string::npos)
1667 odb_from_json_string(ss.str());
1668 else
1669 mthrow("File type of \"" +s_odb_source_str + "\" is not supported");
1670 }
1671
1672 if (s == odb::STRING) {
1673
1674 // create new root ODB object
1675 s_odb = new midas::odb();
1676
1677 // populate object from string
1678 if (s_odb_source_str.substr(0, 19) == "<?xml version=\"1.0\"")
1680 else if (s_odb_source_str.substr(0, 1) == "{")
1682 else
1683 mthrow("Unknown string format: \"" + s_odb_source_str + "\"");
1684 }
1685
1686 // std::cout << s_odb->dump() << std::endl;
1687 }
static thread_local std::string s_odb_source_str
Definition odbxx.h:448
void odb_from_xml_string(const std::string &str, const std::string &subkey)
void odb_from_json_string(const std::string &str, const std::string &subkey)
Here is the call graph for this function:

◆ set_parent()

void midas::odb::set_parent ( midas::odb p)
inlineprivate

Definition at line 538 of file odbxx.h.

538{ m_parent = p; }
Here is the caller graph for this function:

◆ set_preserve_string_size()

void midas::odb::set_preserve_string_size ( bool  f)
inline

Definition at line 1356 of file odbxx.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_string_size()

void midas::odb::set_string_size ( std::string  s,
int  size 
)

Definition at line 1614 of file odbxx.cxx.

1615 {
1616 if (this->is_write_protect())
1617 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
1618
1619 m_num_values = 1;
1620 m_tid = TID_STRING;
1621 m_data = new u_odb[1];
1622 m_data[0].set_parent(this);
1623 m_data[0].set_tid(m_tid);
1626 }
void set_preserve_string_size(bool f)
Definition odbxx.h:1356
void set_string_size(std::string s, int size)
Definition odbxx.cxx:1854
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_tid()

void midas::odb::set_tid ( int  tid)
inlineprivate

Definition at line 533 of file odbxx.h.

533{ m_tid = tid; }
Here is the caller graph for this function:

◆ set_trigger_hotlink()

void midas::odb::set_trigger_hotlink ( bool  f)
inline

Definition at line 1395 of file odbxx.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_write_protect()

void midas::odb::set_write_protect ( bool  f)
inline

Definition at line 1389 of file odbxx.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ size()

int midas::odb::size ( )

Definition at line 386 of file odbxx.cxx.

386 {
387 return m_num_values;
388 }
Here is the caller graph for this function:

◆ unwatch()

void midas::odb::unwatch ( )

Definition at line 1563 of file odbxx.cxx.

1564 {
1565 for (int i=0 ; i<(int) g_watchlist.size() ; i++) {
1566 if (g_watchlist[i]->get_hkey() == this->get_hkey()) {
1568 delete g_watchlist[i];
1569 g_watchlist.erase(g_watchlist.begin() + i);
1570 i--;
1571 }
1572 }
1573 }
INT db_unwatch(HNDLE hDB, HNDLE hKey)
Definition odb.cxx:13920
std::vector< midas::odb * > g_watchlist
Definition odbxx.cxx:45
Here is the call graph for this function:

◆ unwatch_all()

void midas::odb::unwatch_all ( )
staticprivate

Definition at line 1575 of file odbxx.cxx.

1576 {
1577 for (int i=0 ; i<(int) g_watchlist.size() ; i++) {
1579 delete g_watchlist[i];
1580 }
1581 g_watchlist.clear();
1582 }
Here is the call graph for this function:

◆ watch()

void midas::odb::watch ( std::function< void(midas::odb &)>  f)

Definition at line 1547 of file odbxx.cxx.

1547 {
1548 if (m_hKey == 0 || m_hKey == -1)
1549 mthrow("watch() called for ODB key \"" + m_name +
1550 "\" which is not connected to ODB");
1551
1552 // create a deep copy of current object in case it
1553 // goes out of scope
1554 midas::odb* ow = new midas::odb(*this);
1555
1556 ow->m_watch_callback = f;
1558
1559 // put object into watchlist
1560 g_watchlist.push_back(ow);
1561 }
static void watch_callback(int hDB, int hKey, int index, void *info)
Definition odbxx.cxx:124
INT db_watch(HNDLE hDB, HNDLE hKey, void(*dispatcher)(INT, INT, INT, void *), void *info)
Definition odb.cxx:13845
Here is the call graph for this function:
Here is the caller graph for this function:

◆ watch_callback()

void midas::odb::watch_callback ( int  hDB,
int  hKey,
int  index,
void *  info 
)
staticprivate

Definition at line 124 of file odbxx.cxx.

124 {
125 midas::odb *po = static_cast<midas::odb *>(info);
126 if (po->m_data == nullptr)
127 mthrow("Callback received for a midas::odb object which went out of scope");
128 midas::odb *poh = search_hkey(po, hKey);
129 if (poh == nullptr) {
130 auto s = db_get_path(hDB, hKey);
131 mthrow("New key \"" + s + "\" has been created in ODB after calling watch()");
132 }
133
134 poh->m_last_index = index;
135 po->m_watch_callback(*poh);
136 poh->m_last_index = -1;
137 }
void ** info
Definition fesimdaq.cxx:41
HNDLE hDB
main ODB handle
Definition mana.cxx:207
Here is the call graph for this function:
Here is the caller graph for this function:

◆ write() [1/2]

void midas::odb::write ( int  index,
int  str_size 
)

Definition at line 1012 of file odbxx.cxx.

1012 {
1013 if (!is_connected_odb())
1014 return;
1015
1016 if (m_hKey == -1) {
1017 // connect un-connected object (crated via XML)
1018 std::string path = get_full_path();
1019
1020 int status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
1021 if (status != DB_SUCCESS)
1022 mthrow("Cannot connect key \"" + path + "\" to ODB");
1023
1024 } else if (m_hKey == 0) {
1025 if (is_auto_create()) {
1026 std::string to_create = m_name[0] == '/' ? m_name : get_full_path();
1027 int status = db_create_key(s_hDB, 0, to_create.c_str(), m_tid);
1029 mthrow("Cannot create ODB key \"" + to_create + "\", status =" + std::to_string(status));
1030 db_find_key(s_hDB, 0, to_create.c_str(), &m_hKey);
1031 if (s_debug) {
1032 std::cout << "Created ODB key \"" + to_create + "\"" << std::endl;
1033 }
1034 // strip path from name
1035 if (m_name.find_last_of('/') != std::string::npos)
1036 m_name = m_name.substr(m_name.find_last_of('/') + 1);
1037 } else
1038 mthrow("Write of un-connected ODB key \"" + m_name + "\" not possible");
1039 }
1040
1041 // don't write keys
1042 if (m_tid == TID_KEY)
1043 return;
1044
1045 int status{};
1046 if (m_tid == TID_STRING || m_tid == TID_LINK) {
1047 KEY key;
1049 std::string s;
1050 m_data[index].get(s);
1051 if (m_num_values == 1) {
1052 int size = key.item_size;
1053 if (key.item_size == 0 || !is_preserve_string_size())
1054 size = s.size() + 1;
1055 if (str_size > 0)
1056 size = str_size;
1057 char *ss = (char *)malloc(size+1);
1058 mstrlcpy(ss, s.c_str(), size);
1059 if (is_trigger_hotlink())
1060 status = db_set_data(s_hDB, m_hKey, ss, size, 1, m_tid);
1061 else
1063 free(ss);
1064 } else {
1065 if (key.item_size == 0)
1066 key.item_size = s.size() + 1;
1067 if (str_size > 0) {
1068 if (key.item_size > 0 && key.item_size != str_size) {
1069 std::cout << "ODB string size mismatch for \"" << get_full_path() <<
1070 "\" (" << key.item_size << " vs " << str_size << "). ODB key recreated."
1071 << std::endl;
1072 if (is_trigger_hotlink())
1073 status = db_set_data(s_hDB, m_hKey, s.c_str(), str_size, 1, m_tid);
1074 else
1075 status = db_set_data1(s_hDB, m_hKey, s.c_str(), str_size, 1, m_tid);
1076 }
1077 key.item_size = str_size;
1078 }
1080 }
1081 if (s_debug) {
1082 if (m_num_values > 1)
1083 std::cout << "Set ODB key \"" + get_full_path() + "[" + std::to_string(index) + "]\" = \"" + s
1084 + "\"" << std::endl;
1085 else
1086 std::cout << "Set ODB key \"" + get_full_path() + "\" = \"" + s + "\""<< std::endl;
1087 }
1088 } else {
1089 u_odb u = m_data[index];
1090 if (m_tid == TID_BOOL) {
1091 u.set_parent(nullptr);
1092 BOOL b = static_cast<bool>(u); // "bool" is only 1 Byte, BOOL is 4 Bytes
1094 } else {
1096 }
1097 if (s_debug) {
1098 std::string s;
1099 u.get(s);
1100 if (m_num_values > 1)
1101 std::cout << "Set ODB key \"" + get_full_path() + "[" + std::to_string(index) + "]\" = " + s
1102 << std::endl;
1103 else
1104 std::cout << "Set ODB key \"" + get_full_path() + "\" = " + s << std::endl;
1105 }
1106 }
1107 if (status != DB_SUCCESS)
1108 mthrow("db_set_data_index for ODB key \"" + get_full_path() +
1109 "\" failed with status " + std::to_string(status));
1110 }
bool is_preserve_string_size() const
Definition odbxx.h:1355
bool is_trigger_hotlink() const
Definition odbxx.h:1394
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7239
INT db_set_data1(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7337
INT db_set_data_index1(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type, BOOL bNotify)
Definition odb.cxx:7844
DWORD BOOL
Definition midas.h:105
Here is the call graph for this function:

◆ write() [2/2]

void midas::odb::write ( int  str_size = 0)

Definition at line 1113 of file odbxx.cxx.

1113 {
1114
1115 // check if deleted
1116 if (is_deleted())
1117 mthrow("ODB key \"" + m_name + "\" cannot be written because it has been deleted");
1118
1119 // write subkeys
1120 if (m_tid == TID_KEY) {
1121 for (int i = 0; i < m_num_values; i++)
1122 m_data[i].get_odb().write();
1123 return;
1124 }
1125
1126 if (m_tid == 0 && m_data[0].get_tid() != 0)
1127 m_tid = m_data[0].get_tid();
1128
1129 if (m_tid < 1 || m_tid >= TID_LAST)
1130 mthrow("Invalid TID for ODB key \"" + get_full_path() + "\"");
1131
1132 if ((m_hKey == 0 || m_hKey == -1) && !is_auto_create())
1133 mthrow("Writing ODB key \"" + m_name +
1134 "\" is not possible because of invalid key handle");
1135
1136 // if index operator [] returned previously a certain index, write only this one
1137 if (m_last_index != -1) {
1138 write(m_last_index, str_size);
1139 m_last_index = -1;
1140 return;
1141 }
1142
1143 if (m_num_values == 1) {
1144 write(0, str_size);
1145 return;
1146 }
1147
1148 if (m_hKey == -1) {
1149 // connect un-connected object (crated via XML)
1150 std::string path = get_full_path();
1151
1152 int status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
1153 if (status != DB_SUCCESS)
1154 mthrow("Cannot connect key \"" + path + "\" to ODB");
1155
1156 } else if (m_hKey == 0) {
1157 if (is_auto_create()) {
1158 std::string to_create = m_name[0] == '/' ? m_name : get_full_path();
1159 int status = db_create_key(s_hDB, 0, to_create.c_str(), m_tid);
1161 mthrow("Cannot create ODB key \"" + to_create + "\", status" + std::to_string(status));
1162 db_find_key(s_hDB, 0, to_create.c_str(), &m_hKey);
1163 if (s_debug) {
1164 std::cout << "Created ODB key \"" + to_create + "\"" << std::endl;
1165 }
1166 // strip path from name
1167 if (m_name.find_last_of('/') != std::string::npos)
1168 m_name = m_name.substr(m_name.find_last_of('/') + 1);
1169 } else
1170 mthrow("Write of un-connected ODB key \"" + m_name + "\" not possible");
1171 }
1172
1173 int status{};
1174 if (m_tid == TID_STRING || m_tid == TID_LINK) {
1176 KEY key;
1178 if (key.item_size == 0 || key.total_size == 0) {
1179 int size = 1;
1180 for (int i = 0; i < m_num_values; i++) {
1181 std::string d;
1182 m_data[i].get(d);
1183 if ((int) d.size() + 1 > size)
1184 size = d.size() + 1;
1185 }
1186 // round up to multiples of 32
1187 size = (((size - 1) / 32) + 1) * 32;
1188 key.item_size = size;
1190 }
1191 char *str = (char *) calloc(m_num_values, key.item_size);
1192 for (int i = 0; i < m_num_values; i++) {
1193 std::string d;
1194 m_data[i].get(d);
1195 strncpy(str + i * key.item_size, d.c_str(), key.item_size);
1196 }
1197 if (is_trigger_hotlink())
1199 else
1201 free(str);
1202 if (s_debug) {
1203 std::string s;
1204 get(s, true, false);
1205 std::cout << "Set ODB key \"" + get_full_path() +
1206 "[0..." + std::to_string(m_num_values - 1) + "]\" = [" + s + "]" << std::endl;
1207 }
1208 } else {
1209 std::string s;
1210 m_data[0].get(s);
1211 if (is_trigger_hotlink())
1212 status = db_set_data(s_hDB, m_hKey, s.c_str(), s.length() + 1, 1, m_tid);
1213 else
1214 status = db_set_data1(s_hDB, m_hKey, s.c_str(), s.length() + 1, 1, m_tid);
1215 if (s_debug)
1216 std::cout << "Set ODB key \"" + get_full_path() + "\" = " + s << std::endl;
1217 }
1218 } else {
1220 uint8_t *buffer = (uint8_t *) malloc(size);
1221 uint8_t *p = buffer;
1222 for (int i = 0; i < m_num_values; i++) {
1223 if (m_tid == TID_BOOL) {
1224 // bool has 1 Byte, BOOL has 4 Bytes
1225 BOOL b = static_cast<bool>(m_data[i]);
1226 memcpy(p, &b, rpc_tid_size(m_tid));
1227 } else {
1228 memcpy(p, (void*)&m_data[i], rpc_tid_size(m_tid));
1229 }
1230 p += rpc_tid_size(m_tid);
1231 }
1232 if (is_trigger_hotlink())
1234 else
1236 free(buffer);
1237 if (s_debug) {
1238 std::string s;
1239 get(s, false, false);
1240 if (m_num_values > 1)
1241 std::cout << "Set ODB key \"" + get_full_path() + "[0..." + std::to_string(m_num_values - 1) +
1242 "]\" = [" + s + "]" << std::endl;
1243 else
1244 std::cout << "Set ODB key \"" + get_full_path() + "\" = " + s << std::endl;
1245 }
1246 }
1247
1248 if (status != DB_SUCCESS)
1249 mthrow("db_set_data for ODB key \"" + get_full_path() +
1250 "\" failed with status " + std::to_string(status));
1251 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ write_key()

bool midas::odb::write_key ( std::string &  path,
bool  write_defaults 
)
private

Definition at line 743 of file odbxx.cxx.

743 {
744 int status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
745 if (status != DB_SUCCESS) {
746 if (m_tid == 0) // auto-create subdir
747 m_tid = TID_KEY;
748 if (m_tid > 0 && m_tid < TID_LAST) {
749 status = db_create_key(s_hDB, 0, path.c_str(), m_tid);
750 if (status != DB_SUCCESS)
751 mthrow("ODB key \"" + path + "\" cannot be created");
752 status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
753 if (status != DB_SUCCESS)
754 mthrow("ODB key \"" + path + "\" not found after creation");
755 if (s_debug) {
756 if (path[0] == '/')
757 std::cout << "Created ODB key \"" + path + "\"" << std::endl;
758 else
759 std::cout << "Created ODB key \"" + get_full_path() + "\"" << std::endl;
760 }
761 } else
762 mthrow("ODB key \"" + path + "\" cannot be found");
763 return true;
764 } else {
765 KEY key;
767 if (status != DB_SUCCESS)
768 mthrow("db_get_key for ODB key \"" + path +
769 "\" failed with status " + std::to_string(status));
770 if (m_tid == 0)
771 m_tid = key.type;
772
773 // check for correct type
774 if (m_tid > 0 && m_tid != (int) key.type) {
775 if (force_write) {
776 // delete and recreate key
778 if (status != DB_SUCCESS)
779 mthrow("db_delete_key for ODB key \"" + path +
780 "\" failed with status " + std::to_string(status));
781 status = db_create_key(s_hDB, 0, path.c_str(), m_tid);
782 if (status != DB_SUCCESS)
783 mthrow("ODB key \"" + path + "\" cannot be created");
784 status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
785 if (status != DB_SUCCESS)
786 mthrow("ODB key \"" + path + "\" not found after creation");
787 if (s_debug)
788 std::cout << "Re-created ODB key \"" + get_full_path() << "\" with different type" << std::endl;
789 } else
790 // abort
791 mthrow("ODB key \"" + get_full_path() +
792 "\" has differnt type than specified");
793 } else if (s_debug)
794 std::cout << "Validated ODB key \"" + get_full_path() + "\"" << std::endl;
795
796 return false;
797 }
798 }
Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Symbol Documentation

◆ operator!= [1/2]

template<typename T >
bool operator!= ( const midas::odb o,
const T &  d 
)
friend

Definition at line 1495 of file odbxx.h.

1495 {
1496 T v;
1497 midas::odb oc(o);
1498 oc.get(v);
1499 return v != d;
1500 }

◆ operator!= [2/2]

template<typename T >
bool operator!= ( const T &  d,
const midas::odb o 
)
friend

Definition at line 1503 of file odbxx.h.

1503 {
1504 T v;
1505 midas::odb oc(o);
1506 oc.get(v);
1507 return d != v;
1508 }

◆ operator< [1/2]

template<typename T >
bool operator< ( const midas::odb o,
const T &  d 
)
friend

Definition at line 1511 of file odbxx.h.

1511 {
1512 T v;
1513 midas::odb oc(o);
1514 oc.get(v);
1515 return v < d;
1516 }

◆ operator< [2/2]

template<typename T >
bool operator< ( const T &  d,
const midas::odb o 
)
friend

Definition at line 1519 of file odbxx.h.

1519 {
1520 T v;
1521 midas::odb oc(o);
1522 oc.get(v);
1523 return d < v;
1524 }

◆ operator<<

std::ostream & operator<< ( std::ostream &  output,
odb o 
)
friend

Definition at line 936 of file odbxx.h.

936 {
937 std::string s;
938 if (o.m_tid == TID_KEY)
939 o.print(s, 0);
940 else
941 o.get(s);
942 output << s;
943 return output;
944 };
static void output(code_int code)
Definition mgd.cxx:1647

◆ operator<= [1/2]

template<typename T >
bool operator<= ( const midas::odb o,
const T &  d 
)
friend

Definition at line 1527 of file odbxx.h.

1527 {
1528 T v;
1529 midas::odb oc(o);
1530 oc.get(v);
1531 return v <= d;
1532 }

◆ operator<= [2/2]

template<typename T >
bool operator<= ( const T &  d,
const midas::odb o 
)
friend

Definition at line 1535 of file odbxx.h.

1535 {
1536 T v;
1537 midas::odb oc(o);
1538 oc.get(v);
1539 return d <= v;
1540 }

◆ operator== [1/2]

template<typename T >
bool operator== ( const midas::odb o,
const T &  d 
)
friend

Definition at line 1477 of file odbxx.h.

1477 {
1478 // the operator needs a "const midas::odb" reference,
1479 // so we have to make a non-const copy
1480 T v;
1481 midas::odb oc(o);
1482 oc.get(v);
1483 return v == d;
1484 }

◆ operator== [2/2]

template<typename T >
bool operator== ( const T &  d,
const midas::odb o 
)
friend

Definition at line 1487 of file odbxx.h.

1487 {
1488 T v;
1489 midas::odb oc(o);
1490 oc.get(v);
1491 return d == v;
1492 }

◆ operator> [1/2]

template<typename T >
bool operator> ( const midas::odb o,
const T &  d 
)
friend

Definition at line 1543 of file odbxx.h.

1543 {
1544 T v;
1545 midas::odb oc(o);
1546 oc.get(v);
1547 return v > d;
1548 }

◆ operator> [2/2]

template<typename T >
bool operator> ( const T &  d,
const midas::odb o 
)
friend

Definition at line 1551 of file odbxx.h.

1551 {
1552 T v;
1553 midas::odb oc(o);
1554 oc.get(v);
1555 return d > v;
1556 }

◆ operator>= [1/2]

template<typename T >
bool operator>= ( const midas::odb o,
const T &  d 
)
friend

Definition at line 1559 of file odbxx.h.

1559 {
1560 T v;
1561 midas::odb oc(o);
1562 oc.get(v);
1563 return v >= d;
1564 }

◆ operator>= [2/2]

template<typename T >
bool operator>= ( const T &  d,
const midas::odb o 
)
friend

Definition at line 1567 of file odbxx.h.

1567 {
1568 T v;
1569 midas::odb oc(o);
1570 oc.get(v);
1571 return d >= v;
1572 }

Member Data Documentation

◆ m_data

u_odb* midas::odb::m_data
private

Definition at line 465 of file odbxx.h.

◆ m_flags

std::bitset<9> midas::odb::m_flags
private

Definition at line 461 of file odbxx.h.

◆ m_hKey

HNDLE midas::odb::m_hKey
private

Definition at line 473 of file odbxx.h.

◆ m_last_index

int midas::odb::m_last_index
private

Definition at line 471 of file odbxx.h.

◆ m_name

std::string midas::odb::m_name
private

Definition at line 467 of file odbxx.h.

◆ m_num_values

int midas::odb::m_num_values
private

Definition at line 469 of file odbxx.h.

◆ m_parent

midas::odb* midas::odb::m_parent
private

Definition at line 477 of file odbxx.h.

◆ m_tid

int midas::odb::m_tid
private

Definition at line 463 of file odbxx.h.

◆ m_watch

std::vector<midas::odb> midas::odb::m_watch
staticprivate

Definition at line 458 of file odbxx.h.

◆ m_watch_callback

std::function<void(midas::odb &)> midas::odb::m_watch_callback
private

Definition at line 475 of file odbxx.h.

◆ s_connected_odb

bool midas::odb::s_connected_odb = false
staticprivate

Definition at line 456 of file odbxx.h.

◆ s_debug

bool midas::odb::s_debug = false
staticprivate

Definition at line 454 of file odbxx.h.

◆ s_hDB

HNDLE midas::odb::s_hDB = 0
staticprivate

Definition at line 452 of file odbxx.h.

◆ s_odb

thread_local odb * midas::odb::s_odb = nullptr
staticprivate

Definition at line 450 of file odbxx.h.

◆ s_odb_source

thread_local odb::odb_source midas::odb::s_odb_source = odb::ONLINE
staticprivate

Definition at line 447 of file odbxx.h.

◆ s_odb_source_str

thread_local std::string midas::odb::s_odb_source_str = std::string("")
staticprivate

Definition at line 448 of file odbxx.h.


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