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)
 
midas::odbodb_from_xml (PMXML_NODE node, odb *o)
 
midas::odbodb_from_json (const MJsonNode *node, std::string name, odb *o)
 
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 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 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 odb_source s_odb_source = odb::ONLINE
 
static std::string s_odb_source_str = std::string("")
 
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 542 of file odbxx.h.

542 :
548 m_tid{0},
549 m_data{nullptr},
550 m_name{},
551 m_num_values{0},
552 m_last_index{-1},
553 m_hKey{},
554 m_parent{} {}
int m_num_values
Definition odbxx.h:467
int m_tid
Definition odbxx.h:461
u_odb * m_data
Definition odbxx.h:463
int m_last_index
Definition odbxx.h:469
std::bitset< 9 > m_flags
Definition odbxx.h:459
HNDLE m_hKey
Definition odbxx.h:471
std::string m_name
Definition odbxx.h:465
midas::odb * m_parent
Definition odbxx.h:475
@ 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 557 of file odbxx.h.

557 {
558 delete[] m_data;
559 }

◆ odb() [2/10]

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

Definition at line 303 of file odbxx.cxx.

303 : odb() {
304 m_tid = o.m_tid;
305 m_name = o.m_name;
306 m_num_values = o.m_num_values;
307 m_hKey = o.m_hKey;
308 m_watch_callback = o.m_watch_callback;
310 for (int i = 0; i < m_num_values; i++) {
312 m_data[i].set_parent(this);
313 if (m_tid == TID_STRING || m_tid == TID_LINK) {
314 // set_string() creates a copy of our string
315 m_data[i].set_string(o.m_data[i]);
316 } else if (m_tid == TID_KEY) {
317 // recursive call to create a copy of the odb object
319 midas::odb *pc = new midas::odb(*po);
320 pc->set_parent(this);
321 m_data[i].set(pc);
322 } else {
323 // simply pass basic types
324 m_data[i] = o.m_data[i];
325 m_data[i].set_parent(this);
326 }
327 }
328 }
std::function< void(midas::odb &)> m_watch_callback
Definition odbxx.h:473
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
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Here is the call graph for this function:

◆ odb() [3/10]

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

Definition at line 569 of file odbxx.h.

569 :odb() {
570 m_num_values = 1;
571 m_data = new u_odb[1]{v};
572 m_tid = m_data[0].get_tid();
573 m_data[0].set_parent(this);
574 }
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 577 of file odbxx.h.

577 : odb() {
578 m_tid = TID_KEY;
579 m_num_values = list.size();
580 m_data = new u_odb[m_num_values];
581 int i = 0;
582 for (auto &element: list) {
583 // check if name exists already
584 for (int j=0 ; j<i ; j++) {
585 if (strcasecmp(element.first, m_data[j].get_odb().get_name().c_str()) == 0) {
586 if (element.first == m_data[j].get_odb().get_name().c_str()) {
587 mthrow("ODB key with name \"" + m_data[j].get_odb().get_name() + "\" exists already");
588 } else {
589 mthrow("ODB key \"" + std::string(element.first) + "\" exists already as \"" +
590 m_data[j].get_odb().get_name() + "\" (only case differs)");
591 }
592 }
593 }
594 auto o = new midas::odb(element.second);
595 o->set_name(element.first);
596 o->set_parent(this);
598 m_data[i].set_parent(this);
599 m_data[i].set(o);
600 i++;
601 }
602 }
std::string get_name()
Definition odbxx.h:1422
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 606 of file odbxx.h.

606 : odb() {
607 m_num_values = list.size();
608 m_data = new u_odb[m_num_values]{};
609 int i = 0;
610 for (auto &element : list) {
611 u_odb u(element);
612 m_data[i].set_tid(u.get_tid());
613 m_data[i].set_parent(this);
615 i++;
616 }
617 m_tid = m_data[0].get_tid();
618 }
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 622 of file odbxx.h.

622 : odb() {
624 m_data = new u_odb[m_num_values]{};
625 for (int i = 0; i < (int)SIZE; i++) {
626 u_odb u(arr[i]);
627 m_data[i].set_tid(u.get_tid());
628 m_data[i].set_parent(this);
629 m_data[i].set(arr[i]);
630 }
631 m_tid = m_data[0].get_tid();
632 }
#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 636 of file odbxx.h.

636 : odb() {
638 m_data = new u_odb[m_num_values]{};
639 for (int i = 0; i < (int)SIZE; i++) {
640 std::string * mystring = new std::string(arr[i]);
641 u_odb u(mystring);
642 m_data[i].set_tid(u.get_tid());
643 m_data[i].set_parent(this);
644 m_data[i].set(arr[i]);
645 }
646 m_tid = m_data[0].get_tid();
647 }
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 650 of file odbxx.h.

650 : odb() {
651 if (path[0] == '/') {
652 // ODB path
653 if (s_odb_source == ONLINE) {
654 if (init_via_xml) {
655 if (!exists(path))
656 odb::create(path.c_str(), TID_KEY);
658 } else {
659 if (!read_key(path))
660 // create subdir if key does not exist
661 odb::create(path.c_str(), TID_KEY);
662
663 if (!read_key(path))
664 mthrow("ODB key \"" + path + "\" not found in ODB");
665
666 if (m_tid != TID_KEY)
667 read();
668 }
669 } else if (s_odb_source == STRING) {
670
671 if (s_odb_source_str.substr(0, 19) == "<?xml version=\"1.0\"")
673 else if (s_odb_source_str.substr(5, 14) == "/MIDAS version")
675 else
676 mthrow("Unknown string format: \"" + s_odb_source_str + "\"");
677
678 } else if (s_odb_source == FILE) {
679
680 // create odb from file
681 std::ifstream file(s_odb_source_str);
682 if (!file)
683 mthrow("File \"" + s_odb_source_str + "\" not found");
684 std::ostringstream ss;
685 ss << file.rdbuf();
686
687 if (s_odb_source_str.find(".xml") != std::string::npos ||
688 s_odb_source_str.find(".XML") != std::string::npos)
689 odb_from_xml_string(ss.str(), path);
690 else if (s_odb_source_str.find(".json") != std::string::npos ||
691 s_odb_source_str.find(".JSON") != std::string::npos)
692 odb_from_json_string(ss.str(), path);
693 else
694 mthrow("File type of \"" +s_odb_source_str + "\" is not supported");
695
696 } else
697 mthrow("Unknown ODB source: " + std::to_string(s_odb_source));
698
699 } else {
700 // simple string
701
702 // Construct object from initializer_list
703 m_num_values = 1;
704 m_data = new u_odb[1]{new std::string{path}};
705 m_tid = m_data[0].get_tid();
706 m_data[0].set_parent(this);
707 }
708 }
static bool exists(const std::string &name)
Definition odbxx.cxx:75
bool read_key(const std::string &path)
Definition odbxx.cxx:638
static std::string s_odb_source_str
Definition odbxx.h:448
void odb_from_xml_remote(const std::string &str)
Definition odbxx.cxx:159
void odb_from_xml_string(const std::string &str, const std::string &subkey)
Definition odbxx.cxx:198
void read()
Definition odbxx.cxx:783
void odb_from_json_string(const std::string &str, const std::string &subkey)
Definition odbxx.cxx:241
static int create(const char *name, int type=TID_KEY)
Definition odbxx.cxx:139
static odb_source s_odb_source
Definition odbxx.h:447
Here is the call graph for this function:

◆ odb() [9/10]

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

Definition at line 711 of file odbxx.h.

711 : odb(std::string(s)) {
712 }
std::string s()
Definition odbxx.h:1425

◆ odb() [10/10]

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

Definition at line 715 of file odbxx.h.

715 : odb() {
716 m_num_values = list.size();
717 m_data = new u_odb[m_num_values]{};
718 int i = 0;
719 for (auto &element : list) {
721 m_data[i].set_parent(this);
723 i++;
724 }
725 m_tid = m_data[0].get_tid();
726 }
Here is the call graph for this function:

Member Function Documentation

◆ begin()

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

Definition at line 1002 of file odbxx.h.

1002{ 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 1358 of file odbxx.cxx.

1358 {
1359 init_hdb();
1360
1361 if (!name.empty())
1362 m_name = name;
1363 std::string path(p);
1364
1365 if (path.empty())
1366 mthrow("odb::connect() cannot be called with an empty ODB path");
1367
1368 if (path[0] != '/')
1369 mthrow("odb::connect(\"" + path + "\"): path must start with leading \"/\"");
1370
1371 if (path.back() != '/')
1372 path += "/";
1373
1374 path += m_name;
1375
1376 HNDLE hKey;
1377 int status = db_find_key(s_hDB, 0, path.c_str(), &hKey);
1378 bool key_exists = (status == DB_SUCCESS);
1379 bool created = false;
1380
1382 // Recurse down to delete keys as needed.
1383 // We need to do this recursively BEFORE calling read/read_key for the first time
1384 // to ensure that subdirectories get handled correctly.
1386 }
1387
1388 if (!key_exists || write_defaults) {
1390 } else {
1391 read_key(path);
1392 }
1393
1394 // correct wrong parent ODB from initializer_list
1395 for (int i = 0; i < m_num_values; i++)
1396 m_data[i].set_parent(this);
1397
1398 if (m_tid == TID_KEY) {
1399 for (int i = 0; i < m_num_values; i++)
1400 m_data[i].get_odb().connect(get_full_path(), m_data[i].get_odb().get_name(), write_defaults);
1401 } else if (created || write_defaults) {
1402 write();
1403 } else {
1404 read();
1405 }
1406 }
std::string get_full_path()
Definition odbxx.cxx:358
static HNDLE s_hDB
Definition odbxx.h:450
static void init_hdb()
Definition odbxx.cxx:49
bool write_key(std::string &path, bool write_defaults)
Definition odbxx.cxx:724
void set_parent(midas::odb *p)
Definition odbxx.h:536
#define DB_SUCCESS
Definition midas.h:631
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4079
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:1234
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 1409 of file odbxx.cxx.

1409 {
1410
1411 if (str.empty())
1412 mthrow("odb::connect() cannot be called with an empty ODB path");
1413
1414 if (str[0] != '/')
1415 mthrow("odb::connect(\"" + str + "\"): path must start with leading \"/\"");
1416
1417 if (str == "/")
1418 mthrow("odb::connect(\"" + str + "\"): root ODB tree is not allowed");
1419
1420 if (str.back() == '/')
1421 str = str.substr(0, str.size()-1);
1422
1423 // separate ODB path and key nam
1424 std::string name;
1425 std::string path;
1426 name = str.substr(str.find_last_of('/') + 1);
1427 path = str.substr(0, str.find_last_of('/') + 1);
1428
1430 }
void connect(const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults=false)
Definition odbxx.cxx:1358
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 1437 of file odbxx.cxx.

1437 {
1438 // Store the order the user specified.
1439 // Need to do this recursively before calling connect(), as the first
1440 // read() in that function merges user keys and existing keys.
1441 std::map<std::string, std::vector<std::string> > user_order;
1443
1444 // Main connect() that adds/deletes/updates keys as needed.
1445 connect(path, false, true);
1446
1447 // Fix order in ODB (and memory)
1449 }
void recurse_fix_order(midas::odb &default_odb, std::map< std::string, std::vector< std::string > > &user_order)
Definition odbxx.cxx:1281
void recurse_get_defaults_order(std::string path, midas::odb &default_odb, std::map< std::string, std::vector< std::string > > &retval)
Definition odbxx.cxx:1271
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 139 of file odbxx.cxx.

139 {
140 init_hdb();
141 int status = -1;
142 if (is_connected_odb())
145 mthrow("Cannot create key " + std::string(name) + ", db_create_key() status = " + std::to_string(status));
146 return status;
147 }
static bool is_connected_odb()
Definition odbxx.h:1394
#define DB_KEY_EXIST
Definition midas.h:641
INT db_create_key(HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type)
Definition odb.cxx:3308
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 330 of file odbxx.cxx.

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

◆ delete_key() [1/2]

void midas::odb::delete_key ( )

Definition at line 1451 of file odbxx.cxx.

1451 {
1452 init_hdb();
1453
1455
1456 if (this->is_write_protect())
1457 mthrow("Cannot modify write protected key \"" + m_name + "\"");
1458
1459
1460 // delete key in ODB
1462 if (status != DB_SUCCESS && status != DB_INVALID_HANDLE)
1463 mthrow("db_delete_key for ODB key \"" + m_name +
1464 "\" returnd error code " + std::to_string(status));
1465
1466 if (s_debug)
1467 std::cout << "Deleted ODB key \"" + m_name + "\"" << std::endl;
1468
1469 // invalidate this object
1470 delete[] m_data;
1471 m_data = nullptr;
1472 m_num_values = 0;
1473 m_tid = 0;
1474 m_hKey = 0;
1475
1476 // set flag that this object has been deleted
1477 set_deleted(true);
1478 }
#define FALSE
Definition cfortran.h:309
static bool s_debug
Definition odbxx.h:452
void set_deleted(bool f)
Definition odbxx.h:529
bool is_write_protect() const
Definition odbxx.h:1354
#define DB_INVALID_HANDLE
Definition midas.h:635
INT db_delete_key(HNDLE hDB, HNDLE hKey, BOOL follow_links)
Definition odb.cxx:3856
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 84 of file odbxx.cxx.

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

◆ detect_type()

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

Definition at line 729 of file odbxx.h.

729 {
730 if (std::is_same<T, uint8_t>::value)
731 return TID_UINT8;
732 else if (std::is_same<T, int8_t>::value)
733 return TID_INT8;
734 else if (std::is_same<T, uint16_t>::value)
735 return TID_UINT16;
736 else if (std::is_same<T, int16_t>::value)
737 return TID_INT16;
738 else if (std::is_same<T, uint32_t>::value)
739 return TID_UINT32;
740 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 4)
741 return TID_UINT32;
742 else if (std::is_same<T, int32_t>::value)
743 return TID_INT32;
744 else if (std::is_same<T, long>::value && sizeof(long) == 4)
745 return TID_INT32;
746 else if (std::is_same<T, uint64_t>::value)
747 return TID_UINT64;
748 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 8)
749 return TID_UINT64;
750 else if (std::is_same<T, int64_t>::value)
751 return TID_INT64;
752 else if (std::is_same<T, long>::value && sizeof(long) == 8)
753 return TID_INT64;
754 else if (std::is_same<T, bool>::value)
755 return TID_BOOL;
756 else if (std::is_same<T, float>::value)
757 return TID_FLOAT;
758 else if (std::is_same<T, double>::value)
759 return TID_DOUBLE;
760 else
761 return TID_STRING;
762 }
#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 423 of file odbxx.cxx.

423 {
424 std::string s;
425 s = "{\n";
426 dump(s, 1);
427 s += "\n}";
428 return s;
429 }
std::string dump()
Definition odbxx.cxx:423
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 465 of file odbxx.cxx.

465 {
466 for (int i = 0; i < indent; i++)
467 s += " ";
468 if (m_tid == TID_KEY) {
469 s += "\"" + m_name + "\": {\n";
470 for (int i = 0; i < m_num_values; i++) {
471 std::string v;
472 m_data[i].get_odb().dump(v, indent + 1);
473 s += v;
474 if (i < m_num_values - 1)
475 s += ",\n";
476 else
477 s += "\n";
478 }
479 for (int i = 0; i < indent; i++)
480 s += " ";
481 s += "}";
482 } else {
483 KEY key;
485 s += "\"" + m_name + "/key\": ";
486 s += "{ \"type\": " + std::to_string(m_tid) + ", ";
487 s += "\"access_mode\": " + std::to_string(key.access_mode) + ", ";
488 s += "\"last_written\": " + std::to_string(key.last_written) + "},\n";
489 for (int i = 0; i < indent; i++)
490 s += " ";
491 s += "\"" + m_name + "\": ";
492 if (m_num_values > 1)
493 s += "[";
494 std::string v;
495 get(v, m_tid == TID_STRING || m_tid == TID_LINK);
496 s += v;
497 if (m_num_values > 1)
498 s += "]";
499 }
500 }
T get()
Definition odbxx.h:492
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6019
KEY key
Definition mdump.cxx:34
static std::string indent(int x, const char *p=" ")
Definition midas.h:1026
WORD access_mode
Definition midas.h:1033
INT last_written
Definition midas.h:1037
Here is the call graph for this function:

◆ end()

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

Definition at line 1003 of file odbxx.h.

1003{ return iterator(m_data + m_num_values); }

◆ exists()

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

Definition at line 75 of file odbxx.cxx.

75 {
76 init_hdb();
78 return false;
79 HNDLE hkey;
80 return db_find_key(s_hDB, 0, name.c_str(), &hkey) == DB_SUCCESS;
81 }
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 1295 of file odbxx.cxx.

1295 {
1296 // Fix the order of ODB keys to match that specified in target_order.
1297 // The in-ODB representation is simple, as we can just use db_reorder_key()
1298 // on anything that's in the wrong place.
1299 // The in-memory representation is a little trickier, but we just copy raw
1300 // memory into a temporary array, so we don't have to delete/recreate the
1301 // u_odb objects.
1302 std::vector<std::string> curr_order;
1303
1304 if (get_subkeys(curr_order) <= 0) {
1305 // Not a TID_KEY (or no keys)
1306 return;
1307 }
1308
1309 if (target_order.size() != curr_order.size() || (int)target_order.size() != m_num_values) {
1310 return;
1311 }
1312
1313 HNDLE hKey = get_hkey();
1314 bool force_order = false;
1315
1316 // Temporary location where we'll store in-memory u_odb objects in th
1317 // correct order.
1318 u_odb* new_m_data = new u_odb[m_num_values];
1319
1320 for (int i = 0; i < m_num_values; i++) {
1321 if (force_order || curr_order[i] != target_order[i]) {
1322 force_order = true;
1323 HNDLE hSubKey;
1324
1325 // Fix the order in the ODB
1328 }
1329
1330 // Fix the order in memory
1331 auto curr_it = std::find(curr_order.begin(), curr_order.end(), target_order[i]);
1332
1333 if (curr_it == curr_order.end()) {
1334 // Logic error - bail to avoid doing any damage to the in-memory version.
1335 delete[] new_m_data;
1336 return;
1337 }
1338
1339 int curr_idx = curr_it - curr_order.begin();
1341 }
1342
1343 // Final update of the in-memory version so they are in the correct order
1344 for (int i = 0; i < m_num_values; i++) {
1345 m_data[i] = new_m_data[i];
1346
1347 // Nullify pointers that point to the same object in
1348 // m_data and new_m_data, so the underlying object doesn't
1349 // get destroyed when we delete new_m_data.
1350 new_m_data[i].set_string_ptr(nullptr);
1351 new_m_data[i].set_odb(nullptr);
1352 }
1353
1354 delete[] new_m_data;
1355 }
HNDLE get_hkey()
Definition odbxx.h:1417
int get_subkeys(std::vector< std::string > &name)
Definition odbxx.cxx:613
void set_string_ptr(std::string *s)
Definition odbxx.h:179
INT db_reorder_key(HNDLE hDB, HNDLE hKey, INT idx)
Definition odb.cxx:6361
Here is the call graph for this function:

◆ get() [1/3]

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

Definition at line 492 of file odbxx.h.

492 {
493 if (m_num_values > 1)
494 mthrow("ODB key \"" + get_full_path() +
495 "[0..." + std::to_string(m_num_values - 1) +
496 "]\" contains array. Please assign to std::vector.");
498 read();
499 return (T) m_data[0];
500 }
bool is_auto_refresh_read() const
Definition odbxx.h:1327
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 281 of file odbxx.cxx.

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

◆ get() [3/3]

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

Definition at line 504 of file odbxx.h.

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

◆ get_debug()

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

Definition at line 1368 of file odbxx.h.

1368{ return s_debug; }

◆ get_flags()

uint32_t midas::odb::get_flags ( )
inlineprivate

Definition at line 526 of file odbxx.h.

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

◆ get_full_path()

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

Definition at line 358 of file odbxx.cxx.

358 {
359 if (m_name[0] == '/')
360 return m_name;
361 if (m_parent)
362 return m_parent->get_full_path() + "/" + m_name;
363
364 if (!is_connected_odb() || m_hKey == -1)
365 return m_name;
366
367 std::string str = db_get_path(s_hDB, m_hKey);
368 if (str == "/") // change "/" to ""
369 str = "";
370 return str;
371 }
INT db_get_path(HNDLE hDB, HNDLE hKey, char *path, INT buf_size)
Definition odb.cxx:4990
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 1417 of file odbxx.h.

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

◆ get_last_index()

int midas::odb::get_last_index ( )
inline

Definition at line 998 of file odbxx.h.

998{ return m_last_index; }

◆ get_last_written()

unsigned int midas::odb::get_last_written ( )

Definition at line 1511 of file odbxx.cxx.

1511 {
1512 init_hdb();
1513
1514 // set mode in ODB
1515 KEY key;
1516 int status = db_get_key(s_hDB, m_hKey, &key);
1517
1519 mthrow("db_get_key for ODB key \"" + get_full_path() +
1520 "\" returnd error code " + std::to_string(status));
1521
1522 return (unsigned int) (key.last_written);
1523 }
Here is the call graph for this function:

◆ get_mdata()

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

Definition at line 516 of file odbxx.h.

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

◆ get_mode()

int midas::odb::get_mode ( )

Definition at line 1497 of file odbxx.cxx.

1497 {
1498 init_hdb();
1499
1500 // set mode in ODB
1501 KEY key;
1502 int status = db_get_key(s_hDB, m_hKey, &key);
1503
1505 mthrow("db_get_key for ODB key \"" + get_full_path() +
1506 "\" returnd error code " + std::to_string(status));
1507
1508 return key.access_mode;
1509 }
Here is the call graph for this function:

◆ get_name()

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

Definition at line 1422 of file odbxx.h.

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

◆ get_num_values()

int midas::odb::get_num_values ( )
inline

Definition at line 1421 of file odbxx.h.

1421{ return m_num_values; }

◆ get_odb_source()

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

Definition at line 1381 of file odbxx.h.

1381{ return s_odb_source; }

◆ get_parent()

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

Definition at line 537 of file odbxx.h.

537{ return m_parent; }

◆ get_parent_path()

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

Definition at line 374 of file odbxx.cxx.

374 {
375 std::string s = get_full_path();
376 std::size_t i = s.find_last_of("/");
377 s = s.substr(0, i);
378 return s;
379 }
Here is the call graph for this function:

◆ get_subkey()

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

Definition at line 549 of file odbxx.cxx.

549 {
550 if (m_tid == 0) {
551 if (is_auto_create()) {
552 m_tid = TID_KEY;
553 int status = db_create_key(s_hDB, 0, m_name.c_str(), m_tid);
555 mthrow("Cannot create ODB key \"" + m_name + "\", status" + std::to_string(status));
556 db_find_key(s_hDB, 0, m_name.c_str(), &m_hKey);
557 if (s_debug) {
558 if (m_name[0] == '/')
559 std::cout << "Created ODB key \"" + m_name + "\"" << std::endl;
560 else
561 std::cout << "Created ODB key \"" + get_full_path() + "\"" << std::endl;
562 }
563 // strip path from name
564 if (m_name.find_last_of('/') != std::string::npos)
565 m_name = m_name.substr(m_name.find_last_of('/') + 1);
566 } else
567 mthrow("Invalid key \"" + m_name + "\" does not have subkeys");
568
569 }
570 if (m_tid != TID_KEY)
571 mthrow("ODB key \"" + get_full_path() + "\" does not have subkeys");
572
573 std::string first = str;
574 std::string tail{};
575 if (str.find('/') != std::string::npos) {
576 first = str.substr(0, str.find('/'));
577 tail = str.substr(str.find('/') + 1);
578 }
579
580 int i;
581 for (i = 0; i < m_num_values; i++)
582 if (equal_ustring(first.c_str(), m_data[i].get_odb().get_name().c_str()))
583 break;
584 if (i == m_num_values) {
585 if (is_auto_create()) {
586 if (m_num_values == 0) {
587 m_num_values = 1;
588 m_data = new u_odb[1]{};
589 i = 0;
590 } else {
591 // resize array
593 i = m_num_values - 1;
594 }
595 midas::odb *o = new midas::odb();
597 m_data[i].set_parent(this);
598 o->set_name(get_full_path() + "/" + str);
599 o->set_tid(0); // tid is currently undefined
600 o->set_flags(get_flags());
601 o->set_parent(this);
602 m_data[i].set(o);
603 } else
604 mthrow("ODB key \"" + get_full_path() + "\" does not contain subkey \"" + first + "\"");
605 }
606 if (!tail.empty())
607 return m_data[i].get_odb().get_subkey(tail);
608
609 return *m_data[i].get_podb();
610 }
bool is_auto_create() const
Definition odbxx.h:1342
void resize_mdata(int size)
Definition odbxx.cxx:257
odb & get_subkey(std::string str)
Definition odbxx.cxx:549
uint32_t get_flags()
Definition odbxx.h:526
#define DB_CREATED
Definition midas.h:632
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3201
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 613 of file odbxx.cxx.

613 {
614 if (m_tid != TID_KEY)
615 return 0;
616 if (m_hKey == 0 || m_hKey == -1)
617 mthrow("get_sub-keys called with invalid m_hKey for ODB key \"" + m_name + "\"");
618
619 // count number of subkeys in ODB
620 std::vector<HNDLE> hlist;
621 int n = 0;
622 for (int i = 0;; i++) {
623 HNDLE h;
624 int status = db_enum_key(s_hDB, m_hKey, i, &h);
625 if (status != DB_SUCCESS)
626 break;
627 KEY key;
628 db_get_key(s_hDB, h, &key);
629 hlist.push_back(h);
630 name.push_back(key.name);
631 n = i + 1;
632 }
633
634 return n;
635 }
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5586
DWORD n[4]
Definition mana.cxx:247
char name[NAME_LENGTH]
Definition midas.h:1029
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 1420 of file odbxx.h.

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

◆ init_hdb()

void midas::odb::init_hdb ( )
staticprivate

Definition at line 49 of file odbxx.cxx.

49 {
51 mthrow("Operation only possible if connected to an online ODB");
52
53 if (s_hDB == 0)
55 if (s_hDB == 0)
56 mthrow("Please call cm_connect_experiment() before accessing the ODB");
57 s_connected_odb = true;
58 }
static bool s_connected_odb
Definition odbxx.h:454
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3011
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 1342 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 1348 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 1327 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 1333 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 1394 of file odbxx.h.

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

◆ is_deleted()

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

Definition at line 528 of file odbxx.h.

528{ 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 1339 of file odbxx.h.

1339{ 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 1321 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 525 of file odbxx.cxx.

525 {
526 if (m_tid != TID_KEY)
527 return false;
528
529 std::string first = str;
530 std::string tail{};
531 if (str.find('/') != std::string::npos) {
532 first = str.substr(0, str.find('/'));
533 tail = str.substr(str.find('/') + 1);
534 }
535
536 int i;
537 for (i = 0; i < m_num_values; i++)
538 if (m_data[i].get_odb().get_name() == first)
539 break;
540 if (i == m_num_values)
541 return false;
542
543 if (!tail.empty())
544 return m_data[i].get_odb().is_subkey(tail);
545
546 return true;
547 }
bool is_subkey(std::string str)
Definition odbxx.cxx:525
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 1360 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 1354 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 1423 of file odbxx.h.

1423{ return *this; }

◆ load()

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

Definition at line 101 of file odbxx.cxx.

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

◆ odb_from_json()

midas::odb * midas::odb::odb_from_json ( const MJsonNode *  node,
std::string  name,
odb o 
)
inline

Definition at line 1238 of file odbxx.h.

1238 {
1239 int type = node->GetType();
1240
1241 if (type == MJSON_OBJECT) { // subdir
1242 const MJsonStringVector* names = node->GetObjectNames();
1243 const MJsonNodeVector* nodes = node->GetObjectNodes();
1244 if (names == nullptr || nodes==nullptr || names->size() != nodes->size())
1245 mthrow("Invalid JSON format");
1246
1247 if (o == nullptr)
1248 o = new midas::odb();
1249 o->set_tid(TID_KEY);
1250 o->set_name(name);
1251 o->set_hkey(0);
1252
1253 int n=0;
1254 for (int i=0 ; i<(int)names->size() ; i++) {
1255 const char *name = (*names)[i].c_str();
1256 const MJsonNode *node = (*nodes)[i];
1257
1258 if (strchr(name, '/'))// skip special entries
1259 continue;
1260
1261 midas::odb *os = odb_from_json(node, (*names)[i].c_str(), nullptr);
1262 os->set_parent(o);
1263 o->set_odb(os, n);
1264 n++;
1265 }
1266
1267 o->set_num_values(n);
1268
1269 } else { // key
1270
1271 auto key = node->FindObjectNode((std::string(name) + "/key").c_str());
1272 int tid = key->FindObjectNode("type")->GetInt();
1273 const std::string value = node->GetString();
1274
1275 if (o == nullptr)
1276 o = new midas::odb();
1277 o->set_name(name);
1278 o->set_tid(tid);
1279 o->set_hkey(0);
1280 o->set(value);
1281 }
1282
1283// if (type == "odb") {
1284// o->set_name("root");
1285// o->set_hkey(0);
1286// } else {
1287// o->set_name(mxml_get_attribute(node, "name"));
1288// if (mxml_get_attribute(node, "handle") == nullptr)
1289// mthrow("No \"handle\" attribute found in XML data");
1290// o->set_hkey(std::stoi(std::string(mxml_get_attribute(node, "handle"))));
1291// }
1292//
1293// if (type == "key") {
1294// std::string value(mxml_get_value(node));
1295// o->set(value);
1296// } else if (type == "keyarray") {
1297// int n = std::atoi(mxml_get_attribute(node, "num_values"));
1298// o->set_num_values(n);
1299// for (int i=0 ; i<n ; i++) {
1300// std::string value(mxml_get_value(mxml_subnode(node, i)));
1301// o->set(value, i);
1302// }
1303// } else if (type == "dir" || type == "odb") {
1304// int n = mxml_get_number_of_children(node);
1305// o->set_num_values(n);
1306// for (int i = 0; i < n; i++) {
1307// midas::odb *os = odb_from_xml(mxml_subnode(node, i), nullptr);
1308// os->set_parent(o);
1309// o->set_odb(os, i);
1310// }
1311// } else
1312// mthrow("Unexpected XML element " + std::string(mxml_get_name(node)));
1313
1314 return o;
1315 };
midas::odb * odb_from_json(const MJsonNode *node, std::string name, odb *o)
Definition odbxx.h:1238
double value[100]
Definition odbhist.cxx:42
Here is the call graph for this function:
Here is the caller graph for this function:

◆ odb_from_json_string()

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

Definition at line 241 of file odbxx.cxx.

241 {
242
243 MJsonNode* node = MJsonNode::Parse(str.c_str());
244 node->Dump();
245
246 odb_from_json(node, "root", this);
247
248 this->set_auto_create(false);
249 this->set_auto_refresh_read(false);
250 this->set_auto_refresh_write(false);
251 this->set_auto_enlarge_array(false);
252 this->set_write_protect(true);
253 this->set_trigger_hotlink(false);
254 }
void set_auto_refresh_read(bool f)
Definition odbxx.h:1328
void set_auto_enlarge_array(bool f)
Definition odbxx.h:1349
void set_trigger_hotlink(bool f)
Definition odbxx.h:1361
void set_auto_refresh_write(bool f)
Definition odbxx.h:1334
void set_auto_create(bool f)
Definition odbxx.h:1343
void set_write_protect(bool f)
Definition odbxx.h:1355
Here is the call graph for this function:
Here is the caller graph for this function:

◆ odb_from_xml()

midas::odb * midas::odb::odb_from_xml ( PMXML_NODE  node,
odb o 
)
inline

Definition at line 1185 of file odbxx.h.

1185 {
1186 std::string type(mxml_get_name(node));
1187
1188 unsigned int tid = 0;
1189 if (type == "dir" || type == "odb")
1190 tid = TID_KEY;
1191 else {
1192 for (tid = 0; tid < TID_LAST; tid++) {
1194 break;
1195 }
1196 }
1197 if (tid == TID_LAST)
1198 mthrow("Wrong key type in XML file");
1199
1200 if (o == nullptr)
1201 o = new midas::odb();
1202 o->set_tid(tid);
1203 if (type == "odb") {
1204 o->set_name("root");
1205 o->set_hkey(0);
1206 } else {
1207 o->set_name(mxml_get_attribute(node, "name"));
1208 if (mxml_get_attribute(node, "handle") == nullptr)
1209 mthrow("No \"handle\" attribute found in XML data");
1210 o->set_hkey(std::stoi(std::string(mxml_get_attribute(node, "handle"))));
1211 }
1212
1213 if (type == "key") {
1214 std::string value(mxml_get_value(node));
1215 o->set(value);
1216 } else if (type == "keyarray") {
1217 int n = std::atoi(mxml_get_attribute(node, "num_values"));
1218 o->set_num_values(n);
1219 for (int i=0 ; i<n ; i++) {
1220 std::string value(mxml_get_value(mxml_subnode(node, i)));
1221 o->set(value, i);
1222 }
1223 } else if (type == "dir" || type == "odb") {
1225 o->set_num_values(n);
1226 for (int i = 0; i < n; i++) {
1228 os->set_parent(o);
1229 o->set_odb(os, i);
1230 }
1231 } else
1232 mthrow("Unexpected XML element " + std::string(mxml_get_name(node)));
1233
1234 return o;
1235 };
midas::odb * odb_from_xml(PMXML_NODE node, odb *o)
Definition odbxx.h:1185
#define TID_LAST
Definition midas.h:354
const char * rpc_tid_name(INT id)
Definition midas.cxx:11764
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 159 of file odbxx.cxx.

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

◆ odb_from_xml_string()

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

Definition at line 198 of file odbxx.cxx.

198 {
199 char error[256] = "";
200 PMXML_NODE tree = mxml_parse_buffer(str.c_str(), error, sizeof(error), NULL);
201 if (error[0]) {
202 std::cout << "MXML error, buffer =\n" << str << std::endl;
203 mthrow("MXML error: " + std::string(error));
204 }
205
207 if (subkey == "/")
208 root = &tree->child[2];
209 else {
210 // convert ODB path to XPATH
211 std::stringstream ss(subkey);
212 std::string dir, xpath;
213 while (std::getline(ss, dir, '/'))
214 if (!dir.empty())
215 xpath += "/dir[@name=\"" + dir + "\"]";
216
217 // std::string query("/dir[@name=\"Buffer sizes\"]");
218 root = mxml_find_node(&tree->child[2], xpath.c_str());
219 if (root == nullptr) {
220 // try with last element being a key
221 size_t pos = xpath.rfind("dir");
222 if (pos != std::string::npos)
223 xpath.replace(pos, 3, "key");
224 root = mxml_find_node(&tree->child[2], xpath.c_str());
225 if (root == nullptr)
226 mthrow("ODB key \"" + subkey + "\" not found in ODB");
227 }
228 }
229
230 odb_from_xml(root, this);
232
233 this->set_auto_create(false);
234 this->set_auto_refresh_read(false);
235 this->set_auto_refresh_write(false);
236 this->set_auto_enlarge_array(false);
237 this->set_write_protect(true);
238 this->set_trigger_hotlink(false);
239 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator std::string()

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

Definition at line 871 of file odbxx.h.

871 {
872 std::string s;
873 if (m_tid == TID_KEY)
874 print(s, 0);
875 else
876 get(s); // forward to get(std::string)
877 return s;
878 }
std::string print()
Definition odbxx.cxx:415
Here is the call graph for this function:

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

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

Definition at line 891 of file odbxx.h.

891 {
893 read();
894 std::vector<std::string> v(m_num_values);
895 for (int i = 0; i < m_num_values; i++)
896 v[i] = m_data[i].get();
897 return v;
898 }
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 882 of file odbxx.h.

882 {
884 read();
885 std::vector<T> v(m_num_values);
886 for (int i = 0; i < m_num_values; i++)
887 v[i] = m_data[i];
888 return v;
889 }
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 913 of file odbxx.h.

913 {
914 if (m_tid == 0)
915 mthrow("Element \"" + m_name + "\" not found");
916 return get<T>(); // forward to get<T>()
917 }
Here is the call graph for this function:

◆ operator()()

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

Definition at line 975 of file odbxx.h.

975 {
976 if (m_tid == 0) {
977 if (m_num_values == 0) {
978 // initialize this
979 m_num_values = 1;
980 m_tid = detect_type(v);
981 m_data = new u_odb[1]{};
982 m_data[0].set_tid(m_tid);
983 m_data[0].set_parent(this);
984 m_data[0].set(v);
985 if (this->is_auto_refresh_write())
986 write();
987 } else {
988 for (int i = 0; i < m_num_values; i++)
989 m_data[i].set(v);
990 if (this->is_auto_refresh_write())
991 write();
992 }
993 }
994 return *this;
995 }
bool is_auto_refresh_write() const
Definition odbxx.h:1333
int detect_type(const T &)
Definition odbxx.h:729
#define set(var, value)
Here is the call graph for this function:

◆ operator*()

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

Definition at line 1051 of file odbxx.h.

1051 {
1052 if (m_num_values > 1)
1053 mthrow("ODB key \"" + get_full_path() +
1054 "\" contains array which cannot be used in basic arithmetic operation.");
1056 read();
1057 T s = (T) m_data[0];
1058 return s * i;
1059 }
Here is the call graph for this function:

◆ operator*=()

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

Definition at line 1136 of file odbxx.h.

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

◆ operator+()

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

Definition at line 1007 of file odbxx.h.

1007 {
1008 if (m_num_values > 1)
1009 mthrow("ODB key \"" + get_full_path() +
1010 "\" contains array which cannot be used in basic arithmetic operation.");
1011 if (std::is_same<T, midas::odb>::value) {
1012 if (is_auto_refresh_read()) {
1013 read();
1014 i.read();
1015 }
1016 // adding two midas::odb objects is best done in double
1017 double s1 = static_cast<double>(m_data[0]);
1018 double s2 = static_cast<double>(i.m_data[0]);
1019 return s1 + s2;
1020 } else {
1022 read();
1023 T s = (T) m_data[0];
1024 return s + i;
1025 }
1026 }
Here is the call graph for this function:

◆ operator++() [1/2]

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

Definition at line 1072 of file odbxx.h.

1072 {
1074 read();
1075 for (int i = 0; i < m_num_values; i++)
1076 m_data[i].add(1, false);
1077 if (this->is_auto_refresh_write())
1078 write();
1079 return *this;
1080 }
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 1082 of file odbxx.h.

1082 {
1083 // create temporary object
1084 odb o(this);
1086 read();
1087 for (int i = 0; i < m_num_values; i++)
1088 m_data[i].add(1, false);
1089 if (this->is_auto_refresh_write())
1090 write();
1091 return o;
1092 }
Here is the call graph for this function:

◆ operator+=()

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

Definition at line 1116 of file odbxx.h.

1116 {
1118 read();
1119 for (int i = 0; i < m_num_values; i++)
1120 m_data[i].add(d, false);
1121 if (this->is_auto_refresh_write())
1122 write();
1123 return *this;
1124 }
Here is the call graph for this function:

◆ operator-()

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

Definition at line 1029 of file odbxx.h.

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

◆ operator--() [1/2]

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

Definition at line 1094 of file odbxx.h.

1094 {
1096 read();
1097 for (int i = 0; i < m_num_values; i++)
1098 m_data[i].add(-1, false);
1099 if (this->is_auto_refresh_write())
1100 write();
1101 return *this;
1102 }
Here is the call graph for this function:

◆ operator--() [2/2]

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

Definition at line 1104 of file odbxx.h.

1104 {
1105 // create temporary object
1106 odb o(this);
1108 read();
1109 for (int i = 0; i < m_num_values; i++)
1110 m_data[i].add(-1, false);
1111 if (this->is_auto_refresh_write())
1112 write();
1113 return o;
1114 }
Here is the call graph for this function:

◆ operator-=()

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

Definition at line 1126 of file odbxx.h.

1126 {
1128 read();
1129 for (int i = 0; i < m_num_values; i++)
1130 m_data[i].add(-d, false);
1131 if (this->is_auto_refresh_write())
1132 write();
1133 return *this;
1134 }
Here is the call graph for this function:

◆ operator/()

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

Definition at line 1062 of file odbxx.h.

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

◆ operator/=()

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

Definition at line 1146 of file odbxx.h.

1146 {
1148 read();
1149 if (d == 0)
1150 mthrow("Division by zero");
1151 for (int i = 0; i < m_num_values; i++)
1152 m_data[i].mult(1 / d, false);
1153 if (this->is_auto_refresh_write())
1154 write();
1155 return *this;
1156 }
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 839 of file odbxx.h.

839 {
840
841 if (this->is_write_protect())
842 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
843
844 if (m_num_values == 0) {
845 // initialize this
847 m_tid = detect_type(arr[0]);
848 m_data = new u_odb[m_num_values]{};
849 for (int i = 0; i < m_num_values; i++) {
851 m_data[i].set_parent(this);
852 }
853
854 } else {
855
856 // resize internal array if different
857 if (SIZE != m_num_values) {
859 }
860 }
861
862 for (int i = 0; i < m_num_values; i++)
863 m_data[i].set(arr[i]);
864
865 if (this->is_auto_refresh_write())
866 write();
867 return arr;
868 }
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 793 of file odbxx.h.

793 {
794
795 if (this->is_write_protect())
796 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
797
798 if (m_num_values == 0) {
799 // initialize this
800 m_num_values = v.size();
801 if (std::is_same<T, bool>::value) {
802 // Special logic for vector<bool>, which may not be a true
803 // container: it's often optimized to be a bitfield, with
804 // references to elements being masked bits rather than bools.
805 // So T is a bool here, but typeof(v[0]) may not be bool!
806 // "Fake container optimization" only applies to vector<bool>,
807 // not array<bool> or any other vector<T>.
808 m_tid = TID_BOOL;
809 } else {
810 // Every other type can be detected using ref to first element.
811 m_tid = detect_type(v[0]);
812 }
813
814 m_data = new u_odb[m_num_values]{};
815 for (int i = 0; i < m_num_values; i++) {
817 m_data[i].set_parent(this);
818 }
819
820 } else {
821
822 // resize internal array if different
823 if ((int)v.size() != m_num_values) {
824 resize_mdata(v.size());
825 }
826 }
827
828 for (int i = 0; i < m_num_values; i++)
829 m_data[i].set(v[i]);
830
831 if (this->is_auto_refresh_write())
832 write();
833
834 return v;
835 }
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 766 of file odbxx.h.

766 {
767
768 if (this->is_write_protect())
769 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
770
771 if (m_num_values == 0) {
772 // initialize this
773 m_num_values = 1;
774 m_tid = detect_type(v);
775 m_data = new u_odb[1]{};
776 m_data[0].set_tid(m_tid);
777 m_data[0].set_parent(this);
778 m_data[0].set(v);
779 if (this->is_auto_refresh_write())
780 write();
781 } else {
782 for (int i = 0; i < m_num_values; i++)
783 m_data[i].set(v);
784
785 if (this->is_auto_refresh_write())
786 write();
787 }
788 return v;
789 }
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 969 of file odbxx.h.

969 {
970 return get_subkey(std::string(str));
971 }
Here is the call graph for this function:

◆ operator[]() [2/3]

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

Definition at line 931 of file odbxx.h.

931 {
932 if (this->is_write_protect())
933 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
934
935 if (index < 0)
936 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) + "]\"");
937
938 if (index == 0 && m_num_values == 0) {
939 // initialize this
940 m_num_values = 1;
941 m_tid = 0;
942 m_data = new u_odb[1]{};
943 m_data[0].set_tid(m_tid);
944 m_data[0].set_parent(this);
945 m_last_index = 0;
946 return m_data[0];
947 } else if (index >= m_num_values) {
948 if (is_auto_enlarge_array()) {
950 if (this->is_auto_refresh_write())
951 write(index, 0);
952 } else {
953 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)");
954 }
955 }
956
958 read(index);
959
961 return m_data[index];
962 }
bool is_auto_enlarge_array() const
Definition odbxx.h:1348
Here is the call graph for this function:

◆ operator[]() [3/3]

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

Definition at line 965 of file odbxx.h.

965 {
966 return get_subkey(str);
967 }
Here is the call graph for this function:

◆ print() [1/2]

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

Definition at line 415 of file odbxx.cxx.

415 {
416 std::string s;
417 s = "{\n";
418 print(s, 1);
419 s += "\n}";
420 return s;
421 }
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 432 of file odbxx.cxx.

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

◆ read() [1/2]

void midas::odb::read ( )

Definition at line 783 of file odbxx.cxx.

783 {
784 if (!is_connected_odb())
785 return;
786
787 // check if deleted
788 if (is_deleted())
789 mthrow("ODB key \"" + m_name + "\" cannot be pulled because it has been deleted");
790
791 if (m_hKey == 0)
792 return; // needed to print un-connected objects
793
794 if (m_tid == 0)
795 mthrow("Read of invalid ODB key \"" + m_name + "\"");
796
797 if (m_hKey == -1) {
798 // connect un-connected object (crated via XML)
799 std::string path = get_full_path();
800
801 int status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
802 if (status != DB_SUCCESS)
803 mthrow("Cannot connect key \"" + path + "\" to ODB");
804 }
805
806 int status{};
807 if (m_tid == TID_STRING) {
808 KEY key;
810 char *str = (char *) malloc(key.total_size);
811 int size = key.total_size;
813 for (int i = 0; i < m_num_values; i++)
814 m_data[i].set(str + i * key.item_size);
815 free(str);
816 } else if (m_tid == TID_KEY) {
817 std::vector<std::string> name;
818 int n = get_subkeys(name);
819 if (n != m_num_values) {
820 // if subdirs have changed, rebuild it
821 delete[] m_data;
822 m_num_values = n;
824 for (int i = 0; i < m_num_values; i++) {
825 std::string k(get_full_path());
826 k += "/" + name[i];
827 midas::odb *o = new midas::odb(k.c_str());
828 o->set_parent(this);
830 m_data[i].set_parent(this);
831 m_data[i].set(o);
832 }
833 }
834 for (int i = 0; i < m_num_values; i++)
835 m_data[i].get_odb().read();
837 } else {
838 // resize local array if number of values has changed
839 KEY key;
841 if (key.num_values != m_num_values) {
842 delete[] m_data;
845 for (int i = 0; i < m_num_values; i++) {
847 m_data[i].set_parent(this);
848 }
849 }
850
852 void *buffer = malloc(size);
853 void *p = buffer;
855 for (int i = 0; i < m_num_values; i++) {
856 if (m_tid == TID_UINT8)
857 m_data[i].set(*static_cast<uint8_t *>(p));
858 else if (m_tid == TID_INT8)
859 m_data[i].set(*static_cast<int8_t *>(p));
860 else if (m_tid == TID_UINT16)
861 m_data[i].set(*static_cast<uint16_t *>(p));
862 else if (m_tid == TID_INT16)
863 m_data[i].set(*static_cast<int16_t *>(p));
864 else if (m_tid == TID_UINT32)
865 m_data[i].set(*static_cast<uint32_t *>(p));
866 else if (m_tid == TID_INT32)
867 m_data[i].set(*static_cast<int32_t *>(p));
868 else if (m_tid == TID_UINT64)
869 m_data[i].set(*static_cast<uint64_t *>(p));
870 else if (m_tid == TID_INT64)
871 m_data[i].set(*static_cast<int64_t *>(p));
872 else if (m_tid == TID_BOOL)
873 m_data[i].set(*static_cast<bool *>(p));
874 else if (m_tid == TID_FLOAT)
875 m_data[i].set(*static_cast<float *>(p));
876 else if (m_tid == TID_DOUBLE)
877 m_data[i].set(*static_cast<double *>(p));
878 else if (m_tid == TID_STRING)
879 m_data[i].set(std::string(static_cast<const char *>(p)));
880 else if (m_tid == TID_LINK)
881 m_data[i].set(std::string(static_cast<const char *>(p)));
882 else
883 mthrow("Invalid type ID " + std::to_string(m_tid));
884
885 p = static_cast<char *>(p) + rpc_tid_size(m_tid);
886 }
887 free(buffer);
888 }
889
890 if (status != DB_SUCCESS)
891 mthrow("db_get_data for ODB key \"" + get_full_path() +
892 "\" failed with status " + std::to_string(status));
893 if (s_debug) {
894 if (m_tid == TID_KEY) {
895 std::cout << "Get ODB key \"" + get_full_path() + "[0..." +
896 std::to_string(m_num_values - 1) + "]\"" << std::endl;
897 } else {
898 std::string s;
899 get(s, false, false);
900 if (m_num_values > 1) {
901 if (m_tid == TID_STRING || m_tid == TID_LINK)
902 std::cout << "Get ODB key \"" + get_full_path() + "[0..." +
903 std::to_string(m_num_values - 1) + "]\": [\"" + s + "\"]" << std::endl;
904 else
905 std::cout << "Get ODB key \"" + get_full_path() + "[0..." +
906 std::to_string(m_num_values - 1) + "]\": [" + s + "]" << std::endl;
907 } else {
908 if (m_tid == TID_STRING || m_tid == TID_LINK)
909 std::cout << "Get ODB key \"" + get_full_path() + "\": \"" + s + "\"" << std::endl;
910 else
911 std::cout << "Get ODB key \"" + get_full_path() + "\": " + s << std::endl;
912 }
913 }
914 }
915 }
bool is_deleted() const
Definition odbxx.h:528
INT db_get_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
Definition odb.cxx:6539
INT rpc_tid_size(INT id)
Definition midas.cxx:11757
INT k
Definition odbhist.cxx:40
INT num_values
Definition midas.h:1028
INT total_size
Definition midas.h:1031
INT item_size
Definition midas.h:1032
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 918 of file odbxx.cxx.

918 {
919 if (!is_connected_odb())
920 return;
921
922 if (m_hKey == 0 || m_hKey == -1)
923 return; // needed to print un-connected objects
924
925 if (m_tid == 0)
926 mthrow("Pull of invalid ODB key \"" + m_name + "\"");
927
928 int status{};
929 if (m_tid == TID_STRING || m_tid == TID_LINK) {
930 KEY key;
932 char *str = (char *) malloc(key.item_size);
933 int size = key.item_size;
936 free(str);
937 } else if (m_tid == TID_KEY) {
940 } else {
941 int size = rpc_tid_size(m_tid);
942 void *buffer = malloc(size);
943 void *p = buffer;
945 if (m_tid == TID_UINT8)
946 m_data[index].set(*static_cast<uint8_t *>(p));
947 else if (m_tid == TID_INT8)
948 m_data[index].set(*static_cast<int8_t *>(p));
949 else if (m_tid == TID_UINT16)
950 m_data[index].set(*static_cast<uint16_t *>(p));
951 else if (m_tid == TID_INT16)
952 m_data[index].set(*static_cast<int16_t *>(p));
953 else if (m_tid == TID_UINT32)
954 m_data[index].set(*static_cast<uint32_t *>(p));
955 else if (m_tid == TID_INT32)
956 m_data[index].set(*static_cast<int32_t *>(p));
957 else if (m_tid == TID_UINT64)
958 m_data[index].set(*static_cast<uint64_t *>(p));
959 else if (m_tid == TID_INT64)
960 m_data[index].set(*static_cast<int64_t *>(p));
961 else if (m_tid == TID_BOOL)
962 m_data[index].set(*static_cast<bool *>(p));
963 else if (m_tid == TID_FLOAT)
964 m_data[index].set(*static_cast<float *>(p));
965 else if (m_tid == TID_DOUBLE)
966 m_data[index].set(*static_cast<double *>(p));
967 else if (m_tid == TID_STRING)
968 m_data[index].set(std::string(static_cast<const char *>(p)));
969 else if (m_tid == TID_LINK)
970 m_data[index].set(std::string(static_cast<const char *>(p)));
971 else
972 mthrow("Invalid type ID " + std::to_string(m_tid));
973
974 free(buffer);
975 }
976
977 if (status != DB_SUCCESS)
978 mthrow("db_get_data for ODB key \"" + get_full_path() +
979 "\" failed with status " + std::to_string(status));
980 if (s_debug) {
981 std::string s;
982 m_data[index].get(s);
983 if (m_tid == TID_STRING || m_tid == TID_LINK)
984 std::cout << "Get ODB key \"" + get_full_path() + "[" +
985 std::to_string(index) + "]\": [\"" + s + "\"]" << std::endl;
986 else
987 std::cout << "Get ODB key \"" + get_full_path() + "[" +
988 std::to_string(index) + "]\": [" + s + "]" << std::endl;
989 }
990 }
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
Definition odb.cxx:6893
Here is the call graph for this function:

◆ read_key()

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

Definition at line 638 of file odbxx.cxx.

638 {
639 init_hdb();
640
641 int status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
642 if (status != DB_SUCCESS)
643 return false;
644
645 KEY key;
647 if (status != DB_SUCCESS)
648 mthrow("db_get_key for ODB key \"" + path +
649 "\" failed with status " + std::to_string(status));
650
651 // check for correct type if given as parameter
652 if (m_tid > 0 && m_tid != (int) key.type)
653 mthrow("ODB key \"" + get_full_path() +
654 "\" has different type than specified");
655
656 if (s_debug)
657 std::cout << "Get definition for ODB key \"" + get_full_path() + "\"" << std::endl;
658
659 m_tid = key.type;
660 m_name = key.name;
661 if (m_tid == TID_KEY) {
662
663 // merge ODB keys with local keys
664 for (int i = 0; i < m_num_values; i++) {
665 std::string p(path);
666 if (p.back() != '/')
667 p += "/";
668 p += m_data[i].get_odb().get_name();
669 HNDLE h;
670 status = db_find_key(s_hDB, 0, p.c_str(), &h);
671 if (status != DB_SUCCESS) {
672 // if key does not exist in ODB write it
673 m_data[i].get_odb().write_key(p, true);
674 m_data[i].get_odb().write();
675 } else {
676 // check key type
677 KEY key;
678 status = db_get_key(s_hDB, h, &key);
679 if (status != DB_SUCCESS)
680 mthrow("db_get_key for ODB key \"" + get_full_path() +
681 "\" failed with status " + std::to_string(status));
682 if (m_data[i].get_odb().get_tid() != (int)key.type) {
683 // write key if different
684 m_data[i].get_odb().write_key(p, true);
685 m_data[i].get_odb().write();
686 }
687 if (m_data[i].get_odb().get_tid() == TID_KEY) {
688 // update subkey structure
689 m_data[i].get_odb().read_key(p);
690 }
691 }
692 }
693
694 // read back everything from ODB
695 std::vector<std::string> name;
697 delete[] m_data;
699 for (int i = 0; i < m_num_values; i++) {
700 std::string p(path);
701 if (p.back() != '/')
702 p += "/";
703 p += name[i];
704 midas::odb *o = new midas::odb(p.c_str());
705 o->set_parent(this);
707 m_data[i].set_parent(this);
708 m_data[i].set(o);
709 }
710 } else {
712 delete[] m_data;
714 for (int i = 0; i < m_num_values; i++) {
716 m_data[i].set_parent(this);
717 }
718 }
719
720 return true;
721 }
void write(int str_size=0)
Definition odbxx.cxx:1094
int get_tid()
Definition odbxx.h:1420
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 387 of file odbxx.cxx.

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

◆ resize() [2/2]

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

Definition at line 398 of file odbxx.cxx.

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

◆ resize_mdata()

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

Definition at line 257 of file odbxx.cxx.

257 {
258 auto new_array = new u_odb[size]{};
259 int i;
260 for (i = 0; i < m_num_values && i < size; i++) {
261 new_array[i] = m_data[i];
262 if (m_tid == TID_KEY)
263 m_data[i].set_odb(nullptr); // move odb*
264 if (m_tid == TID_STRING || m_tid == TID_LINK)
265 m_data[i].set_string_ptr(nullptr); // move std::string*
266 }
267 for (; i < size; i++) {
268 if (m_tid == TID_STRING || m_tid == TID_LINK)
269 new_array[i].set_string(""); // allocates new string
270 }
271 delete[] m_data;
274 for (i = 0; i < m_num_values; i++) {
276 m_data[i].set_parent(this);
277 }
278 }
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 1425 of file odbxx.h.

1425 {
1426 std::string s;
1427 get(s);
1428 return s;
1429 }
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 503 of file odbxx.cxx.

503 {
504 std::string buffer;
505
506 std::string header = "{\n";
507 header += " \"/MIDAS version\" : \"2.1\",\n";
508 header += " \"/filename\" : \"" + filename + "\",\n";
509 header += " \"/ODB path\" : \"" + get_full_path() + "\",\n\n";
510
511 odb::dump(buffer, 1);
512
513 buffer += "\n}\n";
514
515 std::ofstream f(filename);
516 if (!f.is_open())
517 mthrow("Cannot open file \"" + filename);
518
519 f << header << buffer;
520 f.close();
521 }
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 61 of file odbxx.cxx.

61 {
62 if (po->m_hKey == hKey)
63 return po;
64 if (po->m_tid == TID_KEY) {
65 for (int i = 0; i < po->m_num_values; i++) {
66 midas::odb *pot = search_hkey(po->m_data[i].get_podb(), hKey);
67 if (pot != nullptr)
68 return pot;
69 }
70 }
71 return nullptr;
72 }
static midas::odb * search_hkey(midas::odb *po, int hKey)
Definition odbxx.cxx:61
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 1577 of file odbxx.cxx.

1578 {
1579 if (this->is_write_protect())
1580 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
1581
1582 if (m_tid == TID_BOOL)
1583 s = (s == "y" || s == "1") ? "1" : "0";
1584
1585 if (m_data == nullptr)
1586 m_data = new u_odb[m_num_values];
1587 m_data[i].set_parent(this);
1589 m_data[i].set(s);
1590 }
Here is the call graph for this function:

◆ set() [2/2]

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

Definition at line 1562 of file odbxx.cxx.

1563 {
1564 if (this->is_write_protect())
1565 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
1566
1567 if (m_tid == TID_BOOL)
1568 s = (s == "y" || s == "1") ? "1" : "0";
1569
1570 m_num_values = 1;
1571 m_data = new u_odb[1];
1572 m_data[0].set_parent(this);
1573 m_data[0].set_tid(m_tid);
1574 m_data[0].set(s);
1575 }
Here is the call graph for this function:

◆ set_auto_create()

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

Definition at line 1343 of file odbxx.h.

1343 {
1346 }
void set_flags_recursively(uint32_t f)
Definition odbxx.cxx:151
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 1349 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 1328 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 1334 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 1367 of file odbxx.h.

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

◆ set_deleted()

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

Definition at line 529 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 1340 of file odbxx.h.

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

◆ set_flags()

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

Definition at line 525 of file odbxx.h.

525{ m_flags = f; }

◆ set_flags_recursively()

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

Definition at line 151 of file odbxx.cxx.

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

◆ set_hkey()

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

Definition at line 523 of file odbxx.h.

523{ m_hKey = hKey; }

◆ set_last_index()

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

Definition at line 999 of file odbxx.h.

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

◆ set_mode()

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

Definition at line 1480 of file odbxx.cxx.

1480 {
1481 // set mode of ODB key
1482 // default is MODE_READ | MODE_WRITE | MODE_DELETE
1483
1484 init_hdb();
1485
1486 // set mode in ODB
1488
1490 mthrow("db_set_mode for ODB key \"" + get_full_path() +
1491 "\" returnd error code " + std::to_string(status));
1492
1493 if (s_debug)
1494 std::cout << "Set mode of ODB key \"" + get_full_path() + "\" to " << mode << std::endl;
1495 }
INT db_set_mode(HNDLE hDB, HNDLE hKey, WORD mode, BOOL recurse)
Definition odb.cxx:8027
#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 534 of file odbxx.h.

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

◆ set_num_values()

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

Definition at line 532 of file odbxx.h.

532{ m_num_values = n; }

◆ set_odb()

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

Definition at line 1606 of file odbxx.cxx.

1607 {
1608 if (this->is_write_protect())
1609 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
1610
1611 if (m_data == nullptr)
1612 m_data = new u_odb[m_num_values];
1613 m_data[i].set_parent(this);
1615 m_data[i].set_odb(o);
1616 }
Here is the call graph for this function:

◆ set_odb_source() [1/2]

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

Definition at line 1382 of file odbxx.h.

1382 {
1383 if (s == STRING)
1384 mthrow1("ODB source STRING requires a string");
1385 if (s == FILE)
1386 mthrow1("ODB source FILE requires a filename");
1387 s_odb_source = s;
1388 }
#define mthrow1(arg)
Definition mexcept.h:27
Here is the call graph for this function:

◆ set_odb_source() [2/2]

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

Definition at line 1389 of file odbxx.h.

1389 {
1390 s_odb_source = s;
1392 }
Here is the call graph for this function:

◆ set_parent()

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

Definition at line 536 of file odbxx.h.

536{ 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 1322 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 1592 of file odbxx.cxx.

1593 {
1594 if (this->is_write_protect())
1595 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
1596
1597 m_num_values = 1;
1598 m_tid = TID_STRING;
1599 m_data = new u_odb[1];
1600 m_data[0].set_parent(this);
1601 m_data[0].set_tid(m_tid);
1604 }
void set_preserve_string_size(bool f)
Definition odbxx.h:1322
void set_string_size(std::string s, int size)
Definition odbxx.cxx:1783
Here is the call graph for this function:

◆ set_tid()

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

Definition at line 531 of file odbxx.h.

531{ m_tid = tid; }

◆ set_trigger_hotlink()

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

Definition at line 1361 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 1355 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 382 of file odbxx.cxx.

382 {
383 return m_num_values;
384 }
Here is the caller graph for this function:

◆ unwatch()

void midas::odb::unwatch ( )

Definition at line 1541 of file odbxx.cxx.

1542 {
1543 for (int i=0 ; i<(int) g_watchlist.size() ; i++) {
1544 if (g_watchlist[i]->get_hkey() == this->get_hkey()) {
1546 delete g_watchlist[i];
1547 g_watchlist.erase(g_watchlist.begin() + i);
1548 i--;
1549 }
1550 }
1551 }
INT db_unwatch(HNDLE hDB, HNDLE hKey)
Definition odb.cxx:13887
std::vector< midas::odb * > g_watchlist
Definition odbxx.cxx:40
Here is the call graph for this function:

◆ unwatch_all()

void midas::odb::unwatch_all ( )
staticprivate

Definition at line 1553 of file odbxx.cxx.

1554 {
1555 for (int i=0 ; i<(int) g_watchlist.size() ; i++) {
1557 delete g_watchlist[i];
1558 }
1559 g_watchlist.clear();
1560 }
Here is the call graph for this function:

◆ watch()

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

Definition at line 1525 of file odbxx.cxx.

1525 {
1526 if (m_hKey == 0 || m_hKey == -1)
1527 mthrow("watch() called for ODB key \"" + m_name +
1528 "\" which is not connected to ODB");
1529
1530 // create a deep copy of current object in case it
1531 // goes out of scope
1532 midas::odb* ow = new midas::odb(*this);
1533
1534 ow->m_watch_callback = f;
1536
1537 // put object into watchlist
1538 g_watchlist.push_back(ow);
1539 }
static void watch_callback(int hDB, int hKey, int index, void *info)
Definition odbxx.cxx:123
INT db_watch(HNDLE hDB, HNDLE hKey, void(*dispatcher)(INT, INT, INT, void *), void *info)
Definition odb.cxx:13813
Here is the call graph for this function:

◆ watch_callback()

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

Definition at line 123 of file odbxx.cxx.

123 {
124 midas::odb *po = static_cast<midas::odb *>(info);
125 if (po->m_data == nullptr)
126 mthrow("Callback received for a midas::odb object which went out of scope");
128 if (poh == nullptr) {
129 auto s = db_get_path(hDB, hKey);
130 mthrow("New key \"" + s + "\" has been created in ODB after calling watch()");
131 }
132
133 poh->m_last_index = index;
134 po->m_watch_callback(*poh);
135 poh->m_last_index = -1;
136 }
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 993 of file odbxx.cxx.

993 {
994 if (!is_connected_odb())
995 return;
996
997 if (m_hKey == -1) {
998 // connect un-connected object (crated via XML)
999 std::string path = get_full_path();
1000
1001 int status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
1002 if (status != DB_SUCCESS)
1003 mthrow("Cannot connect key \"" + path + "\" to ODB");
1004
1005 } else if (m_hKey == 0) {
1006 if (is_auto_create()) {
1007 std::string to_create = m_name[0] == '/' ? m_name : get_full_path();
1008 int status = db_create_key(s_hDB, 0, to_create.c_str(), m_tid);
1010 mthrow("Cannot create ODB key \"" + to_create + "\", status =" + std::to_string(status));
1011 db_find_key(s_hDB, 0, to_create.c_str(), &m_hKey);
1012 if (s_debug) {
1013 std::cout << "Created ODB key \"" + to_create + "\"" << std::endl;
1014 }
1015 // strip path from name
1016 if (m_name.find_last_of('/') != std::string::npos)
1017 m_name = m_name.substr(m_name.find_last_of('/') + 1);
1018 } else
1019 mthrow("Write of un-connected ODB key \"" + m_name + "\" not possible");
1020 }
1021
1022 // don't write keys
1023 if (m_tid == TID_KEY)
1024 return;
1025
1026 int status{};
1027 if (m_tid == TID_STRING || m_tid == TID_LINK) {
1028 KEY key;
1030 std::string s;
1031 m_data[index].get(s);
1032 if (m_num_values == 1) {
1033 int size = key.item_size;
1034 if (key.item_size == 0 || !is_preserve_string_size())
1035 size = s.size() + 1;
1036 if (str_size > 0)
1037 size = str_size;
1038 char *ss = (char *)malloc(size+1);
1039 mstrlcpy(ss, s.c_str(), size);
1040 if (is_trigger_hotlink())
1042 else
1044 free(ss);
1045 } else {
1046 if (key.item_size == 0)
1047 key.item_size = s.size() + 1;
1048 if (str_size > 0) {
1049 if (key.item_size > 0 && key.item_size != str_size) {
1050 std::cout << "ODB string size mismatch for \"" << get_full_path() <<
1051 "\" (" << key.item_size << " vs " << str_size << "). ODB key recreated."
1052 << std::endl;
1053 if (is_trigger_hotlink())
1054 status = db_set_data(s_hDB, m_hKey, s.c_str(), str_size, 1, m_tid);
1055 else
1056 status = db_set_data1(s_hDB, m_hKey, s.c_str(), str_size, 1, m_tid);
1057 }
1059 }
1061 }
1062 if (s_debug) {
1063 if (m_num_values > 1)
1064 std::cout << "Set ODB key \"" + get_full_path() + "[" + std::to_string(index) + "]\" = \"" + s
1065 + "\"" << std::endl;
1066 else
1067 std::cout << "Set ODB key \"" + get_full_path() + "\" = \"" + s + "\""<< std::endl;
1068 }
1069 } else {
1070 u_odb u = m_data[index];
1071 if (m_tid == TID_BOOL) {
1072 u.set_parent(nullptr);
1073 BOOL b = static_cast<bool>(u); // "bool" is only 1 Byte, BOOL is 4 Bytes
1075 } else {
1077 }
1078 if (s_debug) {
1079 std::string s;
1080 u.get(s);
1081 if (m_num_values > 1)
1082 std::cout << "Set ODB key \"" + get_full_path() + "[" + std::to_string(index) + "]\" = " + s
1083 << std::endl;
1084 else
1085 std::cout << "Set ODB key \"" + get_full_path() + "\" = " + s << std::endl;
1086 }
1087 }
1088 if (status != DB_SUCCESS)
1089 mthrow("db_set_data_index for ODB key \"" + get_full_path() +
1090 "\" failed with status " + std::to_string(status));
1091 }
bool is_preserve_string_size() const
Definition odbxx.h:1321
bool is_trigger_hotlink() const
Definition odbxx.h:1360
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7215
INT db_set_data1(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7313
INT db_set_data_index1(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type, BOOL bNotify)
Definition odb.cxx:7828
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 1094 of file odbxx.cxx.

1094 {
1095
1096 // check if deleted
1097 if (is_deleted())
1098 mthrow("ODB key \"" + m_name + "\" cannot be written because it has been deleted");
1099
1100 // write subkeys
1101 if (m_tid == TID_KEY) {
1102 for (int i = 0; i < m_num_values; i++)
1103 m_data[i].get_odb().write();
1104 return;
1105 }
1106
1107 if (m_tid == 0 && m_data[0].get_tid() != 0)
1108 m_tid = m_data[0].get_tid();
1109
1111 mthrow("Invalid TID for ODB key \"" + get_full_path() + "\"");
1112
1113 if ((m_hKey == 0 || m_hKey == -1) && !is_auto_create())
1114 mthrow("Writing ODB key \"" + m_name +
1115 "\" is not possible because of invalid key handle");
1116
1117 // if index operator [] returned previously a certain index, write only this one
1118 if (m_last_index != -1) {
1120 m_last_index = -1;
1121 return;
1122 }
1123
1124 if (m_num_values == 1) {
1125 write(0, str_size);
1126 return;
1127 }
1128
1129 if (m_hKey == -1) {
1130 // connect un-connected object (crated via XML)
1131 std::string path = get_full_path();
1132
1133 int status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
1134 if (status != DB_SUCCESS)
1135 mthrow("Cannot connect key \"" + path + "\" to ODB");
1136
1137 } else if (m_hKey == 0) {
1138 if (is_auto_create()) {
1139 std::string to_create = m_name[0] == '/' ? m_name : get_full_path();
1140 int status = db_create_key(s_hDB, 0, to_create.c_str(), m_tid);
1142 mthrow("Cannot create ODB key \"" + to_create + "\", status" + std::to_string(status));
1143 db_find_key(s_hDB, 0, to_create.c_str(), &m_hKey);
1144 if (s_debug) {
1145 std::cout << "Created ODB key \"" + to_create + "\"" << std::endl;
1146 }
1147 // strip path from name
1148 if (m_name.find_last_of('/') != std::string::npos)
1149 m_name = m_name.substr(m_name.find_last_of('/') + 1);
1150 } else
1151 mthrow("Write of un-connected ODB key \"" + m_name + "\" not possible");
1152 }
1153
1154 int status{};
1155 if (m_tid == TID_STRING || m_tid == TID_LINK) {
1157 KEY key;
1159 if (key.item_size == 0 || key.total_size == 0) {
1160 int size = 1;
1161 for (int i = 0; i < m_num_values; i++) {
1162 std::string d;
1163 m_data[i].get(d);
1164 if ((int) d.size() + 1 > size)
1165 size = d.size() + 1;
1166 }
1167 // round up to multiples of 32
1168 size = (((size - 1) / 32) + 1) * 32;
1169 key.item_size = size;
1171 }
1172 char *str = (char *) calloc(m_num_values, key.item_size);
1173 for (int i = 0; i < m_num_values; i++) {
1174 std::string d;
1175 m_data[i].get(d);
1176 strncpy(str + i * key.item_size, d.c_str(), key.item_size);
1177 }
1178 if (is_trigger_hotlink())
1180 else
1182 free(str);
1183 if (s_debug) {
1184 std::string s;
1185 get(s, true, false);
1186 std::cout << "Set ODB key \"" + get_full_path() +
1187 "[0..." + std::to_string(m_num_values - 1) + "]\" = [" + s + "]" << std::endl;
1188 }
1189 } else {
1190 std::string s;
1191 m_data[0].get(s);
1192 if (is_trigger_hotlink())
1193 status = db_set_data(s_hDB, m_hKey, s.c_str(), s.length() + 1, 1, m_tid);
1194 else
1195 status = db_set_data1(s_hDB, m_hKey, s.c_str(), s.length() + 1, 1, m_tid);
1196 if (s_debug)
1197 std::cout << "Set ODB key \"" + get_full_path() + "\" = " + s << std::endl;
1198 }
1199 } else {
1201 uint8_t *buffer = (uint8_t *) malloc(size);
1202 uint8_t *p = buffer;
1203 for (int i = 0; i < m_num_values; i++) {
1204 if (m_tid == TID_BOOL) {
1205 // bool has 1 Byte, BOOL has 4 Bytes
1206 BOOL b = static_cast<bool>(m_data[i]);
1207 memcpy(p, &b, rpc_tid_size(m_tid));
1208 } else {
1209 memcpy(p, (void*)&m_data[i], rpc_tid_size(m_tid));
1210 }
1211 p += rpc_tid_size(m_tid);
1212 }
1213 if (is_trigger_hotlink())
1215 else
1217 free(buffer);
1218 if (s_debug) {
1219 std::string s;
1220 get(s, false, false);
1221 if (m_num_values > 1)
1222 std::cout << "Set ODB key \"" + get_full_path() + "[0..." + std::to_string(m_num_values - 1) +
1223 "]\" = [" + s + "]" << std::endl;
1224 else
1225 std::cout << "Set ODB key \"" + get_full_path() + "\" = " + s << std::endl;
1226 }
1227 }
1228
1229 if (status != DB_SUCCESS)
1230 mthrow("db_set_data for ODB key \"" + get_full_path() +
1231 "\" failed with status " + std::to_string(status));
1232 }
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 724 of file odbxx.cxx.

724 {
725 int status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
726 if (status != DB_SUCCESS) {
727 if (m_tid == 0) // auto-create subdir
728 m_tid = TID_KEY;
729 if (m_tid > 0 && m_tid < TID_LAST) {
730 status = db_create_key(s_hDB, 0, path.c_str(), m_tid);
731 if (status != DB_SUCCESS)
732 mthrow("ODB key \"" + path + "\" cannot be created");
733 status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
734 if (status != DB_SUCCESS)
735 mthrow("ODB key \"" + path + "\" not found after creation");
736 if (s_debug) {
737 if (path[0] == '/')
738 std::cout << "Created ODB key \"" + path + "\"" << std::endl;
739 else
740 std::cout << "Created ODB key \"" + get_full_path() + "\"" << std::endl;
741 }
742 } else
743 mthrow("ODB key \"" + path + "\" cannot be found");
744 return true;
745 } else {
746 KEY key;
748 if (status != DB_SUCCESS)
749 mthrow("db_get_key for ODB key \"" + path +
750 "\" failed with status " + std::to_string(status));
751 if (m_tid == 0)
752 m_tid = key.type;
753
754 // check for correct type
755 if (m_tid > 0 && m_tid != (int) key.type) {
756 if (force_write) {
757 // delete and recreate key
758 status = db_delete_key(s_hDB, m_hKey, false);
759 if (status != DB_SUCCESS)
760 mthrow("db_delete_key for ODB key \"" + path +
761 "\" failed with status " + std::to_string(status));
762 status = db_create_key(s_hDB, 0, path.c_str(), m_tid);
763 if (status != DB_SUCCESS)
764 mthrow("ODB key \"" + path + "\" cannot be created");
765 status = db_find_key(s_hDB, 0, path.c_str(), &m_hKey);
766 if (status != DB_SUCCESS)
767 mthrow("ODB key \"" + path + "\" not found after creation");
768 if (s_debug)
769 std::cout << "Re-created ODB key \"" + get_full_path() << "\" with different type" << std::endl;
770 } else
771 // abort
772 mthrow("ODB key \"" + get_full_path() +
773 "\" has differnt type than specified");
774 } else if (s_debug)
775 std::cout << "Validated ODB key \"" + get_full_path() + "\"" << std::endl;
776
777 return false;
778 }
779 }
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 1461 of file odbxx.h.

1461 {
1462 T v;
1463 midas::odb oc(o);
1464 oc.get(v);
1465 return v != d;
1466 }

◆ operator!= [2/2]

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

Definition at line 1469 of file odbxx.h.

1469 {
1470 T v;
1471 midas::odb oc(o);
1472 oc.get(v);
1473 return d != v;
1474 }

◆ 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 T v;
1479 midas::odb oc(o);
1480 oc.get(v);
1481 return v < d;
1482 }

◆ operator< [2/2]

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

Definition at line 1485 of file odbxx.h.

1485 {
1486 T v;
1487 midas::odb oc(o);
1488 oc.get(v);
1489 return d < v;
1490 }

◆ operator<<

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

Definition at line 920 of file odbxx.h.

920 {
921 std::string s;
922 if (o.m_tid == TID_KEY)
923 o.print(s, 0);
924 else
925 o.get(s);
926 output << s;
927 return output;
928 };
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 1493 of file odbxx.h.

1493 {
1494 T v;
1495 midas::odb oc(o);
1496 oc.get(v);
1497 return v <= d;
1498 }

◆ operator<= [2/2]

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

Definition at line 1501 of file odbxx.h.

1501 {
1502 T v;
1503 midas::odb oc(o);
1504 oc.get(v);
1505 return d <= v;
1506 }

◆ operator== [1/2]

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

Definition at line 1443 of file odbxx.h.

1443 {
1444 // the operator needs a "const midas::odb" reference,
1445 // so we have to make a non-const copy
1446 T v;
1447 midas::odb oc(o);
1448 oc.get(v);
1449 return v == d;
1450 }

◆ operator== [2/2]

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

Definition at line 1453 of file odbxx.h.

1453 {
1454 T v;
1455 midas::odb oc(o);
1456 oc.get(v);
1457 return d == v;
1458 }

◆ operator> [1/2]

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

Definition at line 1509 of file odbxx.h.

1509 {
1510 T v;
1511 midas::odb oc(o);
1512 oc.get(v);
1513 return v > d;
1514 }

◆ operator> [2/2]

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

Definition at line 1517 of file odbxx.h.

1517 {
1518 T v;
1519 midas::odb oc(o);
1520 oc.get(v);
1521 return d > v;
1522 }

◆ operator>= [1/2]

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

Definition at line 1525 of file odbxx.h.

1525 {
1526 T v;
1527 midas::odb oc(o);
1528 oc.get(v);
1529 return v >= d;
1530 }

◆ operator>= [2/2]

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

Definition at line 1533 of file odbxx.h.

1533 {
1534 T v;
1535 midas::odb oc(o);
1536 oc.get(v);
1537 return d >= v;
1538 }

Member Data Documentation

◆ m_data

u_odb* midas::odb::m_data
private

Definition at line 463 of file odbxx.h.

◆ m_flags

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

Definition at line 459 of file odbxx.h.

◆ m_hKey

HNDLE midas::odb::m_hKey
private

Definition at line 471 of file odbxx.h.

◆ m_last_index

int midas::odb::m_last_index
private

Definition at line 469 of file odbxx.h.

◆ m_name

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

Definition at line 465 of file odbxx.h.

◆ m_num_values

int midas::odb::m_num_values
private

Definition at line 467 of file odbxx.h.

◆ m_parent

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

Definition at line 475 of file odbxx.h.

◆ m_tid

int midas::odb::m_tid
private

Definition at line 461 of file odbxx.h.

◆ m_watch

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

Definition at line 456 of file odbxx.h.

◆ m_watch_callback

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

Definition at line 473 of file odbxx.h.

◆ s_connected_odb

bool midas::odb::s_connected_odb = false
staticprivate

Definition at line 454 of file odbxx.h.

◆ s_debug

bool midas::odb::s_debug = false
staticprivate

Definition at line 452 of file odbxx.h.

◆ s_hDB

HNDLE midas::odb::s_hDB = 0
staticprivate

Definition at line 450 of file odbxx.h.

◆ s_odb_source

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

Definition at line 447 of file odbxx.h.

◆ s_odb_source_str

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: