LCOV - code coverage report
Current view: top level - examples/odbxx - odbxx_test.cxx (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 123 0
Test Date: 2025-11-11 10:26:08 Functions: 0.0 % 2 0

            Line data    Source code
       1              : /********************************************************************\
       2              : 
       3              :   Name:         odbxx_test.cxx
       4              :   Created by:   Stefan Ritt
       5              : 
       6              :   Contents:     Test and Demo of Object oriented interface to ODB
       7              : 
       8              : \********************************************************************/
       9              : 
      10              : #include <string>
      11              : #include <iostream>
      12              : #include <array>
      13              : 
      14              : #include "midas.h"
      15              : #include "odbxx.h"
      16              : 
      17              : /*------------------------------------------------------------------*/
      18              : 
      19            0 : int main() {
      20              : 
      21            0 :    cm_connect_experiment(nullptr, nullptr, "test", nullptr);
      22            0 :    midas::odb::set_debug(true);
      23              : 
      24              :    // delete /Test/Settings to start from scratch
      25            0 :    midas::odb::delete_key("/Test/Settings");
      26              : 
      27              :    // create ODB structure...
      28              :    midas::odb o = {
      29            0 :       {"Int32 Key", 42},
      30              :       {"Bool Key", true},
      31            0 :       {"Subdir", {
      32            0 :          {"Int32 key", 123 },
      33            0 :          {"Double Key", 1.2},
      34            0 :          {"Subsub", {
      35            0 :             {"Float key", 1.2f},     // floats must be explicitly specified
      36              :             {"String Key", "Hello"},
      37              :          }}
      38              :       }},
      39            0 :       {"Int Array", {1, 2, 3}},
      40            0 :       {"Double Array", {1.2, 2.3, 3.4}},
      41            0 :       {"String Array", {"Hello1", "Hello2", "Hello3"}},
      42            0 :       {"Large Array", std::array<int, 10>{} },            // array with explicit size
      43            0 :       {"Large String", std::string(63, '\0') },           // string with explicit size
      44            0 :       {"String Array 10", std::array<std::string, 10>{}}, // string array with explicit size
      45              :       // string array with 10 strings of each 63 chars
      46            0 :       {"Large String Array 10", std::array<std::string, 10>{std::string(63, '\0')}}
      47            0 :    };
      48              : 
      49              :    // ...and push it to ODB. If keys are present in the
      50              :    // ODB, their value is kept. If not, the default values
      51              :    // from above are copied to the ODB
      52            0 :    o.connect("/Test/Settings");
      53              : 
      54              :    // alternatively, a structure can be created from an existing ODB subtree
      55            0 :    midas::odb o2("/Test/Settings");
      56            0 :    std::cout << o2 << std::endl;
      57              : 
      58              :    // set, retrieve, and change ODB value
      59            0 :    o["Int32 Key"] = 42;
      60            0 :    int i = o["Int32 Key"];
      61            0 :    o["Int32 Key"] = i+1;
      62            0 :    o["Int32 Key"]++;
      63            0 :    o["Int32 Key"] *= 1.3;
      64            0 :    std::cout << "Should be 57: " << o["Int32 Key"] << std::endl;
      65              : 
      66              :    // test with 64-bit variables
      67            0 :    o["Int64 Key"] = -1LL;
      68            0 :    int64_t i64 = o["Int64 Key"];
      69            0 :    std::cout << std::hex << "0x" << i64 << std::dec << std::endl;
      70              : 
      71            0 :    o["UInt64 Key"] = 0x1234567812345678u;
      72            0 :    uint64_t ui64 = o["UInt64 Key"];
      73            0 :    std::cout << std::hex << "0x" << ui64 << std::dec << std::endl;
      74              : 
      75              :    // test with bool
      76            0 :    o["Bool Key"] = false;
      77            0 :    o["Bool Key"] = !o["Bool Key"];
      78              : 
      79              :    // test with std::string
      80            0 :    o["Subdir"]["Subsub"]["String Key"] = "Hello";
      81            0 :    std::string s = o["Subdir"]["Subsub"]["String Key"];
      82            0 :    s += " world!";
      83            0 :    o["Subdir"]["Subsub"]["String Key"] = s;
      84            0 :    s = s + o["Subdir"]["Subsub"]["String Key"].s(); // need .s() for concatenations
      85            0 :    std::cout << s << std::endl;
      86              : 
      87              :    // use std::string as index
      88            0 :    std::string substr("Int32 Key");
      89            0 :    o[substr] = 43;
      90              : 
      91              :    // test with a vector
      92            0 :    std::vector<int> v = o["Int Array"]; // read vector
      93            0 :    std::fill(v.begin(), v.end(), 10);
      94            0 :    o["Int Array"] = v;        // assign vector to ODB array
      95            0 :    o["Int Array"][1] = 2;     // modify array element
      96            0 :    i = o["Int Array"][1];     // read from array element
      97            0 :    std::cout << i <<std::endl;
      98            0 :    o["Int Array"].resize(5);  // resize array
      99            0 :    o["Int Array"]++;          // increment all values of array
     100            0 :    std::cout << "Arrays size is " << o["Int Array"].size() << std::endl;
     101              : 
     102              :    // auto-enlarge arrays
     103            0 :    o["Int Array"][10] = 10;
     104              : 
     105              :    // test with a string vector
     106            0 :    std::vector<std::string> sv;
     107            0 :    sv = o["String Array"];
     108            0 :    sv[1] = "New String";
     109            0 :    o["String Array"] = sv;
     110            0 :    o["String Array"][2] = "Another String";
     111            0 :    o["String Array"][3] = std::string("One more");
     112            0 :    s = o["String Array"][1].s(); // need .s() to explicitly convert to std::string
     113            0 :    std::cout << s << std::endl;
     114              : 
     115              :    // test with strings with given size
     116            0 :    o["String Array 2"][0].set_string_size("Hello", 64);
     117            0 :    o["String Array 2"][1] = "Second string";
     118            0 :    o["String Array 2"][2] = "Third string";
     119              : 
     120              :    // test with bool arrays/vectors
     121            0 :    o["Bool Array"] = std::array<bool, 3>{true, false, true};
     122            0 :    o["Bool Array from Vector"] = std::vector<bool>{true, false, true};
     123              : 
     124              :    // iterate over array
     125            0 :    int sum = 0;
     126            0 :    for (int e : o["Int Array"])
     127            0 :       sum += e;
     128            0 :    std::cout << "Sum should be 37: " << sum << std::endl;
     129              : 
     130              :    // create key from other key
     131            0 :    midas::odb oi(o["Int32 Key"]);
     132            0 :    oi = 123;
     133              : 
     134              :    // test auto refresh read
     135            0 :    std::cout << oi << std::endl;     // each read access reads value from ODB
     136            0 :    oi.set_auto_refresh_read(false);  // turn off auto refresh
     137            0 :    std::cout << oi << std::endl;     // this does not read value from ODB
     138            0 :    oi.read();                        // this forces a manual read
     139            0 :    std::cout << oi << std::endl;
     140              : 
     141              :    // test auto refresh write
     142            0 :    oi.set_auto_refresh_write(false); // turn off auto refresh write
     143            0 :    oi = 321;                         // this does not write a value to the ODB
     144            0 :    oi.write();                       // this forces a manual write
     145              : 
     146              :    // create ODB entries on-the-fly
     147            0 :    midas::odb ot;
     148            0 :    ot.connect("/Test/Settings/OTF");// this forces /Test/OTF to be created if not already there
     149            0 :    ot["Int32 Key"] = 1;             // create all these keys with different types
     150            0 :    ot["Double Key"] = 1.23;
     151            0 :    ot["String Key"] = "Hello";
     152            0 :    ot["Int Array"] = std::array<int, 10>{};
     153            0 :    ot["Subdir"]["Int32 Key"] = 42;
     154            0 :    ot["String Array"] = std::vector<std::string>{"S1", "S2", "S3"};
     155            0 :    ot["Other String Array"][0] = "OSA0";
     156            0 :    ot["Other String Array"][1] = "OSA1";
     157              : 
     158              :    // create key with default value
     159            0 :    i = ot["Int32 Key"](123);        // key exists already (created above) -> use key value i=1
     160            0 :    std::cout << i << std::endl;
     161            0 :    i = ot["New Int32 Key"](123);    // key does not exist -> set it to default value 123 i=123
     162            0 :    std::cout << i << std::endl;
     163              : 
     164              :    //  std::string s1 = ot["New String Key"]("Hi"); // same for strings
     165            0 :    std::cout << ot << std::endl;
     166              : 
     167            0 :    o.read();                        // re-read the underlying ODB tree which got changed by above OTF code
     168            0 :    std::cout << o.print() << std::endl;
     169              : 
     170              :    // iterate over sub-keys
     171            0 :    midas::odb::set_debug(false);
     172            0 :    for (midas::odb& oit : o)
     173            0 :       std::cout << oit.get_name() << ": " << oit << std::endl;
     174              : 
     175              :    // print whole sub-tree
     176            0 :    std::cout << o.print() << std::endl;
     177              : 
     178              :    // print whole subtree
     179            0 :    std::cout << o.dump() << std::endl;
     180              : 
     181              :    // update structure - create keys if needed, keep existing values if key already exists,
     182              :    // delete keys that are in ODB but not the list of defaults.
     183              :    midas::odb o3 = {
     184            0 :       {"Int32 Key", 456},
     185              :       {"New Bool Key", true},
     186            0 :       {"String Array", {"Hello1", "Hello2", "Hello3"}},
     187              :       {"Bool Key", true},
     188            0 :       {"Subdir", {
     189            0 :                {"Int32 key", 135 },
     190              :                {"New Sub Bool Key", false},
     191            0 :                {"Double Key", 1.5}
     192              :       }}
     193            0 :    };
     194            0 :    o3.connect_and_fix_structure("/Test/Settings");
     195              : 
     196              :    // Print new structure
     197            0 :    std::cout << "After changing structure with o3:" << std::endl;
     198            0 :    std::cout << o3.print() << std::endl;
     199              : 
     200              :    // delete test key from ODB
     201            0 :    o.delete_key();
     202              : 
     203              :    // don't clutter watch callbacks
     204            0 :    midas::odb::set_debug(false);
     205              : 
     206              :    // watch ODB key for any change with lambda function
     207            0 :    midas::odb ow("/Experiment");
     208            0 :    ow.watch([](midas::odb &o) {
     209            0 :       std::cout << "Value of key \"" + o.get_full_path() + "\" changed to " << o << std::endl;
     210            0 :    });
     211              : 
     212              :    do {
     213            0 :       int status = cm_yield(100);
     214            0 :       if (status == SS_ABORT || status == RPC_SHUTDOWN)
     215              :          break;
     216            0 :    } while (!ss_kbhit());
     217              : 
     218            0 :    cm_disconnect_experiment();
     219            0 :    return 1;
     220            0 : }
        

Generated by: LCOV version 2.0-1