17#include <initializer_list>
47 mthrow(
"Please call cm_connect_experiment() before accessing the ODB");
56 for (
int i = 0;
i <
po->m_num_values;
i++) {
83 std::cout <<
"Delete key " +
name <<
" not found in ODB" << std::endl;
87 std::cout <<
"Delete ODB key " +
name << std::endl;
92 void odb::load(
const std::string &filename,
const std::string &odb_path) {
95 mthrow(
"Cannot connect to ODB");
103 mthrow(
"ODB path " + odb_path +
" not found in ODB");
108 mthrow(
"ODB path " + odb_path +
" does not point to a directory");
116 if (
po->m_data ==
nullptr)
117 mthrow(
"Callback received for a midas::odb object which went out of scope");
119 if (
poh ==
nullptr) {
121 mthrow(
"New key \"" +
s +
"\" has been created in ODB after calling watch()");
125 po->m_watch_callback(*
poh);
126 poh->m_last_index = -1;
136 mthrow(
"Cannot create key " + std::string(
name) +
", db_create_key() status = " + std::to_string(
status));
146 m_data[
i].get_odb().set_flags_recursively(f);
156 mthrow(
"ODB key \"" +
str +
"\" not found in ODB");
170 mthrow(
"Cannot retrieve XML data, status = " + std::to_string(
status));
173 std::cout <<
"Retrieved XML tree for \"" +
str +
"\"" << std::endl;
175 char error[256] =
"";
178 std::cout <<
"MXML error, buffer =\n" << buffer << std::endl;
179 mthrow(
"MXML error: " + std::string(error));
253 pc->set_parent(
this);
266 d.m_num_values =
s.m_num_values;
268 d.m_watch_callback =
s.m_watch_callback;
270 for (
int i = 0;
i <
d.m_num_values;
i++) {
272 d.m_data[
i].set_parent(&
d);
275 d.m_data[
i].set_string(
s.m_data[
i]);
284 d.m_data[
i] =
s.m_data[
i];
285 d.m_data[
i].set_parent(
this);
309 std::size_t
i =
s.find_last_of(
"/");
326 "\" failed with status " + std::to_string(
status));
338 "\" failed with status " + std::to_string(
status));
369 s +=
"\"" +
m_name +
"\": {\n";
402 s +=
"\"" +
m_name +
"\": {\n";
418 s +=
"\"" +
m_name +
"/key\": ";
419 s +=
"{ \"type\": " + std::to_string(
m_tid) +
", ";
439 std::string header =
"{\n";
440 header +=
" \"/MIDAS version\" : \"2.1\",\n";
441 header +=
" \"/filename\" : \"" + filename +
"\",\n";
442 header +=
" \"/ODB path\" : \"" +
get_full_path() +
"\",\n\n";
448 std::ofstream f(filename);
450 mthrow(
"Cannot open file \"" + filename);
452 f << header << buffer;
464 if (
str.find(
'/') != std::string::npos) {
492 std::cout <<
"Created ODB key \"" +
m_name +
"\"" << std::endl;
494 std::cout <<
"Created ODB key \"" +
get_full_path() +
"\"" << std::endl;
497 if (
m_name.find_last_of(
'/') != std::string::npos)
500 mthrow(
"Invalid key \"" +
m_name +
"\" does not have subkeys");
508 if (
str.find(
'/') != std::string::npos) {
550 mthrow(
"get_sub-keys called with invalid m_hKey for ODB key \"" +
m_name +
"\"");
553 std::vector<HNDLE>
hlist;
555 for (
int i = 0;;
i++) {
581 mthrow(
"db_get_key for ODB key \"" + path +
582 "\" failed with status " + std::to_string(
status));
587 "\" has different type than specified");
590 std::cout <<
"Get definition for ODB key \"" +
get_full_path() +
"\"" << std::endl;
614 "\" failed with status " + std::to_string(
status));
628 std::vector<std::string>
name;
665 mthrow(
"ODB key \"" + path +
"\" cannot be created");
668 mthrow(
"ODB key \"" + path +
"\" not found after creation");
671 std::cout <<
"Created ODB key \"" + path +
"\"" << std::endl;
673 std::cout <<
"Created ODB key \"" +
get_full_path() +
"\"" << std::endl;
676 mthrow(
"ODB key \"" + path +
"\" cannot be found");
682 mthrow(
"db_get_key for ODB key \"" + path +
683 "\" failed with status " + std::to_string(
status));
693 mthrow(
"db_delete_key for ODB key \"" + path +
694 "\" failed with status " + std::to_string(
status));
697 mthrow(
"ODB key \"" + path +
"\" cannot be created");
700 mthrow(
"ODB key \"" + path +
"\" not found after creation");
702 std::cout <<
"Re-created ODB key \"" +
get_full_path() <<
"\" with different type" << std::endl;
706 "\" has differnt type than specified");
708 std::cout <<
"Validated ODB key \"" +
get_full_path() +
"\"" << std::endl;
722 mthrow(
"ODB key \"" +
m_name +
"\" cannot be pulled because it has been deleted");
736 mthrow(
"Cannot connect key \"" + path +
"\" to ODB");
750 std::vector<std::string>
name;
812 m_data[
i].
set(std::string(
static_cast<const char *
>(p)));
814 m_data[
i].
set(std::string(
static_cast<const char *
>(p)));
816 mthrow(
"Invalid type ID " + std::to_string(
m_tid));
825 "\" failed with status " + std::to_string(
status));
832 get(
s,
false,
false);
836 std::to_string(
m_num_values - 1) +
"]\": [\"" +
s +
"\"]" << std::endl;
839 std::to_string(
m_num_values - 1) +
"]\": [" +
s +
"]" << std::endl;
842 std::cout <<
"Get ODB key \"" +
get_full_path() +
"\": \"" +
s +
"\"" << std::endl;
844 std::cout <<
"Get ODB key \"" +
get_full_path() +
"\": " +
s << std::endl;
905 mthrow(
"Invalid type ID " + std::to_string(
m_tid));
912 "\" failed with status " + std::to_string(
status));
918 std::to_string(
index) +
"]\": [\"" +
s +
"\"]" << std::endl;
921 std::to_string(
index) +
"]\": [" +
s +
"]" << std::endl;
936 mthrow(
"Cannot connect key \"" + path +
"\" to ODB");
946 std::cout <<
"Created ODB key \"" +
to_create +
"\"" << std::endl;
949 if (
m_name.find_last_of(
'/') != std::string::npos)
952 mthrow(
"Write of un-connected ODB key \"" +
m_name +
"\" not possible");
983 std::cout <<
"ODB string size mismatch for \"" <<
get_full_path() <<
997 std::cout <<
"Set ODB key \"" +
get_full_path() +
"[" + std::to_string(
index) +
"]\" = \"" +
s
1000 std::cout <<
"Set ODB key \"" +
get_full_path() +
"\" = \"" +
s +
"\""<< std::endl;
1006 BOOL b =
static_cast<bool>(
u);
1015 std::cout <<
"Set ODB key \"" +
get_full_path() +
"[" + std::to_string(
index) +
"]\" = " +
s
1018 std::cout <<
"Set ODB key \"" +
get_full_path() +
"\" = " +
s << std::endl;
1023 "\" failed with status " + std::to_string(
status));
1031 mthrow(
"ODB key \"" +
m_name +
"\" cannot be written because it has been deleted");
1048 "\" is not possible because of invalid key handle");
1068 mthrow(
"Cannot connect key \"" + path +
"\" to ODB");
1070 }
else if (
m_hKey == 0) {
1078 std::cout <<
"Created ODB key \"" +
to_create +
"\"" << std::endl;
1081 if (
m_name.find_last_of(
'/') != std::string::npos)
1084 mthrow(
"Write of un-connected ODB key \"" +
m_name +
"\" not possible");
1097 if ((
int)
d.size() + 1 >
size)
1098 size =
d.size() + 1;
1101 size = (((
size - 1) / 32) + 1) * 32;
1118 get(
s,
true,
false);
1120 "[0..." + std::to_string(
m_num_values - 1) +
"]\" = [" +
s +
"]" << std::endl;
1130 std::cout <<
"Set ODB key \"" +
get_full_path() +
"\" = " +
s << std::endl;
1153 get(
s,
false,
false);
1156 "]\" = [" +
s +
"]" << std::endl;
1158 std::cout <<
"Set ODB key \"" +
get_full_path() +
"\" = " +
s << std::endl;
1164 "\" failed with status " + std::to_string(
status));
1175 for (
int i = 0;;
i++) {
1189 std::cout <<
"Deleting " <<
full_path <<
" as not in list of defaults" << std::endl;
1296 std::string path(p);
1299 mthrow(
"odb::connect() cannot be called with an empty ODB path");
1302 mthrow(
"odb::connect(\"" + path +
"\"): path must start with leading \"/\"");
1304 if (path.back() !=
'/')
1345 mthrow(
"odb::connect() cannot be called with an empty ODB path");
1348 mthrow(
"odb::connect(\"" +
str +
"\"): path must start with leading \"/\"");
1351 mthrow(
"odb::connect(\"" +
str +
"\"): root ODB tree is not allowed");
1353 if (
str.back() ==
'/')
1359 name =
str.substr(
str.find_last_of(
'/') + 1);
1360 path =
str.substr(0,
str.find_last_of(
'/') + 1);
1374 std::map<std::string, std::vector<std::string> >
user_order;
1390 mthrow(
"Cannot modify write protected key \"" +
m_name +
"\"");
1397 "\" returnd error code " + std::to_string(
status));
1400 std::cout <<
"Deleted ODB key \"" +
m_name +
"\"" << std::endl;
1424 "\" returnd error code " + std::to_string(
status));
1427 std::cout <<
"Set mode of ODB key \"" +
get_full_path() +
"\" to " <<
mode << std::endl;
1439 "\" returnd error code " + std::to_string(
status));
1453 "\" returnd error code " + std::to_string(
status));
1461 "\" which is not connected to ODB");
1467 ow->m_watch_callback = f;
1501 s = (
s ==
"y" ||
s ==
"1") ?
"1" :
"0";
1516 s = (
s ==
"y" ||
s ==
"1") ?
"1" :
"0";
1581 s = std::string(
m_bool ?
"true" :
"false");
1592 else if (
m_tid == 0)
1595 mthrow(
"Invalid type ID " + std::to_string(
m_tid));
1726 m_parent_odb->set_last_index(-1);
1731 m_parent_odb->set_last_index(-1);
1736 m_parent_odb->set_last_index(-1);
1741 m_parent_odb->set_last_index(-1);
1746 m_parent_odb->set_last_index(-1);
1751 m_parent_odb->set_last_index(-1);
1756 m_parent_odb->set_last_index(-1);
1761 m_parent_odb->set_last_index(-1);
1766 m_parent_odb->set_last_index(-1);
1771 m_parent_odb->set_last_index(-1);
1776 m_parent_odb->set_last_index(-1);
1779 u_odb::operator std::string() {
1781 m_parent_odb->set_last_index(-1);
1786 u_odb::operator
const char *() {
1788 m_parent_odb->set_last_index(-1);
1790 mthrow(
"Only ODB string keys can be converted to \"const char *\"");
1791 return m_string->c_str();
1797 mthrow(
"Only ODB directories can be converted to \"midas::odb &\"");
1820 mthrow(
"Invalid arithmetic operation for ODB key \"" +
1845 mthrow(
"Invalid operation for ODB key \"" +
void set_string_size(std::string s, int size)
std::string get_parent_path()
std::string get_full_path()
void set(std::string str)
static bool exists(const std::string &name)
void write(int str_size=0)
void set_odb(odb *o, int i)
void deep_copy(odb &d, const odb &s)
bool is_auto_refresh_read() const
static void unwatch_all()
std::function< void(midas::odb &)> m_watch_callback
bool is_auto_create() const
bool is_preserve_string_size() const
static void watch_callback(int hDB, int hKey, int index, void *info)
bool is_auto_refresh_write() const
bool read_key(const std::string &path)
void set_preserve_string_size(bool f)
void resize_mdata(int size)
odb & get_subkey(std::string str)
void set_flags_recursively(uint32_t f)
unsigned int get_last_written()
int get_subkeys(std::vector< std::string > &name)
void watch(std::function< void(midas::odb &)> f)
void save(const std::string &filename)
void set_last_index(int i)
static int create(const char *name, int type=TID_KEY)
bool is_subkey(std::string str)
void fix_order(std::vector< std::string > target_subkey_order)
void connect_and_fix_structure(std::string path)
static bool s_connected_odb
bool is_trigger_hotlink() const
bool write_key(std::string &path, bool write_defaults)
static midas::odb * search_hkey(midas::odb *po, int hKey)
static bool is_connected_odb()
static void load(const std::string &filename, const std::string &odb_path)
midas::odb * odb_from_xml(PMXML_NODE node, odb *o)
void set_parent(midas::odb *p)
bool is_write_protect() const
void connect(const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults=false)
uint8_t operator=(uint8_t v)
void mult(double f, bool push=true)
void set_string(std::string s)
void add(double inc, bool push=true)
void set_string_size(std::string s, int size)
void set_string_ptr(std::string *s)
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
#define DB_INVALID_HANDLE
BOOL equal_ustring(const char *str1, const char *str2)
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
INT db_delete_key(HNDLE hDB, HNDLE hKey, BOOL follow_links)
INT db_reorder_key(HNDLE hDB, HNDLE hKey, INT idx)
INT db_get_path(HNDLE hDB, HNDLE hKey, char *path, INT buf_size)
INT db_get_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
INT db_create_key(HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type)
INT db_copy_xml(HNDLE hDB, HNDLE hKey, char *buffer, int *buffer_size, bool header)
INT db_unwatch(HNDLE hDB, HNDLE hKey)
INT db_set_mode(HNDLE hDB, HNDLE hKey, WORD mode, BOOL recurse)
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
INT db_load(HNDLE hDB, HNDLE hKeyRoot, const char *filename, BOOL bRemote)
INT db_watch(HNDLE hDB, HNDLE hKey, void(*dispatcher)(INT, INT, INT, void *), void *info)
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
INT db_set_data1(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
INT db_set_data_index1(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type, BOOL bNotify)
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
INT db_set_num_values(HNDLE hDB, HNDLE hKey, INT num_values)
#define write(n, a, f, d)
static std::string indent(int x, const char *p=" ")
void recurse_fix_order(midas::odb &default_odb, std::map< std::string, std::vector< std::string > > &user_order)
void recurse_get_defaults_order(std::string path, midas::odb &default_odb, std::map< std::string, std::vector< std::string > > &retval)
std::vector< midas::odb * > g_watchlist
void recurse_del_keys_not_in_defaults(std::string path, HNDLE hDB, HNDLE hKey, midas::odb &default_odb)
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
static double sub(double a, double b)