LCOV - code coverage report
Current view: top level - otsdaq-utilities/tools - ots_table_update_cells.cc (source / functions) Coverage Total Hit
Test: mu2edaq.info.cleaned Lines: 0.0 % 116 0
Test Date: 2026-09-10 01:53:42 Functions: 0.0 % 21 0

            Line data    Source code
       1              : #include "otsdaq/MessageFacility/MessageFacility.h"
       2              : 
       3              : #include <dirent.h>
       4              : #include <cassert>
       5              : #include <iostream>
       6              : #include <map>
       7              : #include <memory>
       8              : #include <string>
       9              : 
      10              : #include "otsdaq/ConfigurationInterface/ConfigurationInterface.h"
      11              : #include "otsdaq/ConfigurationInterface/ConfigurationManagerRW.h"
      12              : 
      13              : // Shared test utilities
      14              : #include "otsdaq/Macros/TestUtilities.h"
      15              : 
      16              : /// Updates specific cells in a table by UID and column name, then creates a new version.
      17              : /// Optionally assigns a version alias to the newly created version.
      18              : ///
      19              : /// usage:
      20              : ///     ots_table_update_cells <tableName> <updates> [--version <version>] [--source-alias <name>] [--alias <aliasName>]
      21              : ///
      22              : /// where <updates> is a semicolon-separated list of row updates:
      23              : ///     UID1:col1=val1,col2=val2;UID2:col1=val3
      24              : ///
      25              : /// options:
      26              : ///     --version <version>      : source version to modify (default: active version)
      27              : ///     --source-alias <name>    : load source version from a version alias
      28              : ///     --alias <aliasName>      : assign a version alias to the newly created version
      29              : ///
      30              : /// examples:
      31              : ///     ots_table_update_cells TrackerDTC "dtc0:FirmwareVersion=v3.2,Enabled=1;dtc1:Enabled=0"
      32              : ///     ots_table_update_cells TrackerDTC "dtc0:FirmwareVersion=v3.2" --version 5
      33              : ///     ots_table_update_cells TrackerDTC "dtc0:FirmwareVersion=v3.2" --alias MyConfig
      34              : 
      35              : using namespace ots;
      36              : 
      37              : std::map<std::string /*uid*/, std::map<std::string /*colName*/, std::string /*value*/>>
      38            0 : parseUpdates(const std::string& updateString)
      39              : {
      40            0 :         std::map<std::string, std::map<std::string, std::string>> updates;
      41              : 
      42            0 :         size_t rowStart = 0;
      43            0 :         while(rowStart < updateString.size())
      44              :         {
      45            0 :                 size_t rowEnd = updateString.find(';', rowStart);
      46            0 :                 if(rowEnd == std::string::npos)
      47            0 :                         rowEnd = updateString.size();
      48              : 
      49            0 :                 std::string rowEntry = updateString.substr(rowStart, rowEnd - rowStart);
      50            0 :                 rowStart             = rowEnd + 1;
      51              : 
      52            0 :                 if(rowEntry.empty())
      53            0 :                         continue;
      54              : 
      55            0 :                 size_t colonPos = rowEntry.find(':');
      56            0 :                 if(colonPos == std::string::npos)
      57              :                 {
      58            0 :                         __SS__ << "Invalid update entry '" << rowEntry
      59            0 :                                << "'. Expected format: UID:col1=val1,col2=val2" << __E__;
      60            0 :                         __SS_THROW__;
      61            0 :                 }
      62              : 
      63            0 :                 std::string uid         = rowEntry.substr(0, colonPos);
      64            0 :                 std::string assignments = rowEntry.substr(colonPos + 1);
      65              : 
      66            0 :                 size_t assignStart = 0;
      67            0 :                 while(assignStart < assignments.size())
      68              :                 {
      69            0 :                         size_t assignEnd = assignments.find(',', assignStart);
      70            0 :                         if(assignEnd == std::string::npos)
      71            0 :                                 assignEnd = assignments.size();
      72              : 
      73              :                         std::string assignment =
      74            0 :                             assignments.substr(assignStart, assignEnd - assignStart);
      75            0 :                         assignStart = assignEnd + 1;
      76              : 
      77            0 :                         if(assignment.empty())
      78            0 :                                 continue;
      79              : 
      80            0 :                         size_t eqPos = assignment.find('=');
      81            0 :                         if(eqPos == std::string::npos)
      82              :                         {
      83            0 :                                 __SS__ << "Invalid column assignment '" << assignment
      84            0 :                                        << "'. Expected format: colName=value" << __E__;
      85            0 :                                 __SS_THROW__;
      86            0 :                         }
      87              : 
      88            0 :                         updates[uid][assignment.substr(0, eqPos)] = assignment.substr(eqPos + 1);
      89            0 :                 }
      90              : 
      91            0 :                 if(updates[uid].empty())
      92              :                 {
      93            0 :                         __SS__ << "No column assignments found for UID '" << uid << "'." << __E__;
      94            0 :                         __SS_THROW__;
      95            0 :                 }
      96            0 :         }
      97              : 
      98            0 :         return updates;
      99            0 : }
     100              : 
     101            0 : void UpdateTableCells(int argc, char* argv[])
     102              : {
     103            0 :         std::cout << "=================================================\n";
     104            0 :         std::cout << "=================================================\n";
     105            0 :         std::cout << "=================================================\n";
     106            0 :         __COUT_INFO__ << "Update Table Cells!" << std::endl;
     107              : 
     108              :         std::cout
     109              :             << "\n\nusage:\n"
     110              :             << "\t ots_table_update_cells <tableName> <updates> [--version <ver>] [--alias "
     111              :                "<aliasName>] [--notes <text>]\n\n"
     112              :             << "\t <updates> format: UID1:col1=val1,col2=val2;UID2:col1=val3\n"
     113              :             << "\t --version <ver>       : source version to modify (default: active "
     114              :                "version)\n"
     115              :             << "\t --source-alias <name> : load source version from a version alias\n"
     116              :             << "\t --alias <alias>       : assign version alias to newly created version\n"
     117            0 :             << "\t --notes <text>        : comment/notes to store with the new version\n\n"
     118            0 :             << std::endl;
     119              : 
     120            0 :         std::cout << "argc = " << argc << std::endl;
     121            0 :         for(int i = 0; i < argc; i++)
     122            0 :                 std::cout << "argv[" << i << "] = " << argv[i] << std::endl;
     123              : 
     124            0 :         if(argc < 3)
     125              :         {
     126              :                 std::cout
     127            0 :                     << "Error! Must provide at least 2 parameters: <tableName> <updates>\n\n"
     128            0 :                     << std::endl;
     129            0 :                 return;
     130              :         }
     131              : 
     132              :         // parse table name (auto-append "Table" suffix if needed)
     133            0 :         std::string tableName = argv[1];
     134            0 :         __COUTV__(tableName);
     135            0 :         auto tablePos = tableName.find("Table");
     136            0 :         if(tablePos == std::string::npos || tablePos != tableName.size() - strlen("Table"))
     137            0 :                 tableName += "Table";
     138            0 :         __COUTV__(tableName);
     139              : 
     140              :         // parse update string
     141            0 :         auto cellUpdates = parseUpdates(argv[2]);
     142            0 :         __COUT_INFO__ << "Parsed " << cellUpdates.size() << " row update(s)." << std::endl;
     143              : 
     144              :         // parse optional flags
     145            0 :         std::string  aliasName   = "";
     146            0 :         std::string  sourceAlias = "";
     147            0 :         std::string  notes       = "";
     148            0 :         TableVersion sourceVersion;  // default = invalid, meaning use active version
     149            0 :         for(int i = 3; i < argc; i++)
     150              :         {
     151            0 :                 std::string arg = argv[i];
     152            0 :                 if(arg == "--alias" && i + 1 < argc)
     153              :                 {
     154            0 :                         aliasName = argv[++i];
     155            0 :                         __COUTV__(aliasName);
     156              :                 }
     157            0 :                 else if(arg == "--version" && i + 1 < argc)
     158              :                 {
     159            0 :                         sourceVersion = TableVersion(std::string(argv[++i]));
     160            0 :                         __COUT__ << "Source version: " << sourceVersion << __E__;
     161              :                 }
     162            0 :                 else if(arg == "--source-alias" && i + 1 < argc)
     163              :                 {
     164            0 :                         sourceAlias = argv[++i];
     165            0 :                         __COUTV__(sourceAlias);
     166              :                 }
     167            0 :                 else if(arg == "--notes" && i + 1 < argc)
     168              :                 {
     169            0 :                         notes = argv[++i];
     170            0 :                         __COUTV__(notes);
     171              :                 }
     172              :                 else
     173              :                 {
     174            0 :                         __SS__ << "Unknown option '" << arg
     175              :                                << "'. Expected '--alias <name>', '--version <ver>', "
     176            0 :                                   "'--source-alias <name>', or '--notes <text>'."
     177            0 :                                << __E__;
     178            0 :                         __SS_THROW__;
     179            0 :                 }
     180            0 :         }
     181              : 
     182              :         // get kerberos author
     183            0 :         std::string author = "";
     184              :         try
     185              :         {
     186            0 :                 author = __ENV__("OTS_KCACHE_USER");
     187              :         }
     188            0 :         catch(...)
     189              :         {
     190            0 :                 __SS__ << "No valid ots kerberos user found, please kinit and source "
     191            0 :                           "setup_ots.sh or kint_setup.sh."
     192            0 :                        << __E__;
     193            0 :                 __SS_THROW__;
     194            0 :         }
     195            0 :         __COUTV__(author);
     196              : 
     197              :         //==============================================================================
     198              :         // initialize configuration manager
     199              : 
     200            0 :         __COUT_INFO__ << "Initializing..." << std::endl;
     201              : 
     202            0 :         std::string ARTDAQ_DATABASE_URI = __ENV__("ARTDAQ_DATABASE_URI");
     203            0 :         __COUTV__(ARTDAQ_DATABASE_URI);
     204              : 
     205            0 :         ConfigurationManagerRW  cfgMgrInst("export_admin");
     206            0 :         ConfigurationManagerRW* cfgMgr = &cfgMgrInst;
     207              : 
     208              :         {
     209            0 :                 std::string                             accumulatedWarnings;
     210              :                 const std::map<std::string, TableInfo>& allTableInfo =
     211            0 :                     cfgMgr->getAllTableInfo(true /* refresh */,
     212              :                                             &accumulatedWarnings,
     213              :                                             "" /* errorFilterName */,
     214              :                                             false /* getGroupKeys */,
     215              :                                             false /* getGroupInfo */,
     216              :                                             true /* initializeActiveGroups */);
     217            0 :                 __COUTV__(allTableInfo.size());
     218            0 :         }
     219              : 
     220              :         //==============================================================================
     221              :         // call the reusable updateTableCells workflow
     222              : 
     223              :         TableVersion newVersion = cfgMgr->updateTableCells(
     224            0 :             tableName, cellUpdates, author, sourceVersion, aliasName, sourceAlias, notes);
     225              : 
     226            0 :         __COUT_INFO__ << "Done. New version: " << tableName << "-v" << newVersion
     227            0 :                       << std::endl;
     228              : 
     229            0 : }  // end UpdateTableCells()
     230              : 
     231            0 : int main(int argc, char* argv[])
     232              : {
     233            0 :         test::util::check_and_make_envs();
     234              : 
     235            0 :         INIT_MF("UpdateTableCells");
     236            0 :         UpdateTableCells(argc, argv);
     237            0 :         return 0;
     238              : }
        

Generated by: LCOV version 2.0-1