LCOV - code coverage report
Current view: top level - conffwk/apps - config_dump.cxx (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 165 0
Test Date: 2025-12-21 13:07:08 Functions: 0.0 % 20 0

            Line data    Source code
       1              : #include <stdlib.h>
       2              : 
       3              : #include <iostream>
       4              : #include <string>
       5              : 
       6              : #include <boost/program_options.hpp>
       7              : 
       8              : #include "conffwk/Configuration.hpp"
       9              : #include "conffwk/ConfigObject.hpp"
      10              : #include "conffwk/Schema.hpp"
      11              : 
      12              : using namespace dunedaq::conffwk;
      13              : 
      14            0 : ERS_DECLARE_ISSUE(
      15              :   config_dump,
      16              :   BadCommandLine,
      17              :   "bad command line: " << reason,
      18              :   ((const char*)reason)
      19              : )
      20              : 
      21            0 : ERS_DECLARE_ISSUE(
      22              :   config_dump,
      23              :   ConfigException,
      24              :   "caught dunedaq::conffwk::Exception exception",
      25              : )
      26              : 
      27              : struct SortByName
      28              : {
      29              :   bool
      30            0 :   operator()(const ConfigObject *o1, const ConfigObject *o2) const
      31              :   {
      32            0 :     return o1->UID() < o2->UID();
      33              :   }
      34              : };
      35              : 
      36              : static void
      37            0 : print_referenced_by(const ConfigObject &obj, const char *prefix)
      38              : {
      39            0 :   std::vector<ConfigObject> values;
      40            0 :   obj.referenced_by(values, "*", false, 0, 0);
      41            0 :   if (values.size() == 0)
      42              :     {
      43            0 :       std::cout << prefix << "is not referenced by others objects\n";
      44              :     }
      45              :   else
      46              :     {
      47            0 :       std::cout << prefix << "is referenced by " << values.size() << " object" << (values.size() == 1 ? "" : "s") << ":\n";
      48            0 :       for (const auto &iobj : values)
      49            0 :         std::cout << prefix << " * " << iobj << std::endl;
      50              : 
      51              :     }
      52            0 : }
      53              : 
      54              : static void
      55            0 : print_versions(const std::vector<dunedaq::conffwk::Version>& versions)
      56              : {
      57            0 :   const auto len = versions.size();
      58            0 :   unsigned int idx = 1;
      59            0 :   for (const auto& x : versions)
      60              :     {
      61            0 :       char buf[50];
      62            0 :       std::time_t t(x.get_timestamp());
      63            0 :       std::strftime(buf, 50, "%F %T %Z", std::localtime(&t));
      64            0 :       std::cout << " * version [" << idx++ << '/' << len << "]\n"
      65            0 :           "    id: " << x.get_id() << "\n"
      66            0 :           "    user: " << x.get_user() << "\n"
      67              :           "    date: " << buf << "\n"
      68            0 :           "    comment: " << x.get_comment() << "\n"
      69            0 :           "    files:\n";
      70              : 
      71            0 :       for (const auto& f : x.get_files())
      72            0 :         std::cout << "     - \"" << f << "\"\n";
      73              :     }
      74            0 : }
      75              : 
      76            0 : int main(int argc, char *argv[])
      77              : {
      78            0 :   const std::string any("*");
      79            0 :   std::string db_name, class_name, object_id, since, until;
      80              : 
      81            0 :   bool changes = false;
      82              : 
      83            0 :   bool skip_irrelevant = true;
      84            0 :   dunedaq::conffwk::Version::QueryType query_type = dunedaq::conffwk::Version::query_by_tag;
      85              : 
      86            0 :   bool direct_info = false;
      87            0 :   bool objects_details = false;
      88            0 :   bool contained_in = false;
      89            0 :   bool referenced_by = false;
      90              : 
      91            0 :   boost::program_options::options_description desc(
      92              :       "Dumps class and objects descriptions using abstract conffwk API.\n"
      93              :       "Without -c or -o options, the utility lists all classes.\n"
      94              :       "\n"
      95            0 :       "Options/Arguments");
      96              : 
      97            0 :   try
      98              :     {
      99            0 :       std::vector<std::string> vesrions_str;
     100            0 :       std::string class_name2;
     101              : 
     102            0 :       desc.add_options()
     103            0 :         (
     104              :           "database,d",
     105            0 :           boost::program_options::value<std::string>(&db_name)->required(),
     106              :           "database specification in format plugin-name:parameters"
     107              :         )
     108            0 :         (
     109              :           "changes,a",
     110              :           "print details of new repository versions or modified files"
     111              :         )
     112            0 :         (
     113              :           "versions,v",
     114            0 :           boost::program_options::value<std::vector<std::string>>(&vesrions_str)->multitoken()->zero_tokens(),
     115              :           "print details of versions from archive providing 4 parameters \"all|skip\" \"date|id|tag\" \"since\" \"until\""
     116              :         )
     117            0 :         (
     118              :           "class-direct-info,c",
     119            0 :           boost::program_options::value<std::string>(&class_name)->default_value("")->implicit_value(any),
     120              :           "print direct properties of all classes, or given class if name is provided"
     121              :         )
     122            0 :         (
     123              :           "class-all-info,C",
     124            0 :           boost::program_options::value<std::string>(&class_name2)->default_value("")->implicit_value(any),
     125              :           "similar to -c, but prints all properties of class (all attributes, all superclasses, etc.)"
     126              :         )
     127            0 :         (
     128              :           "list-objects,o",
     129              :           "list objects of class"
     130              :         )
     131            0 :         (
     132              :           "print-referenced-by,r",
     133              :           "print objects referencing given object (only with -o option)"
     134              :         )
     135            0 :         (
     136              :           "dump-objects,O",
     137            0 :           boost::program_options::value<std::string>(&object_id)->default_value("")->implicit_value(any),
     138              :           "dump all objects of class or details of given object, if id is provided (-c is required)"
     139              :         )
     140            0 :         (
     141              :           "show-contained-in,n",
     142              :           "when dump an object, print out the database file it belongs to"
     143              :         )
     144            0 :         (
     145              :           "help,h",
     146              :           "print help message"
     147              :         );
     148              : 
     149            0 :       boost::program_options::variables_map vm;
     150            0 :       boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
     151              : 
     152            0 :       if (vm.count("help"))
     153              :         {
     154            0 :           std::cout << desc << std::endl;
     155            0 :           return EXIT_SUCCESS;
     156              :         }
     157              : 
     158            0 :       boost::program_options::notify(vm);
     159              : 
     160            0 :       if (!class_name.empty())
     161            0 :         direct_info = true;
     162              : 
     163            0 :       if (!class_name2.empty())
     164              :         {
     165            0 :           if (!class_name.empty())
     166            0 :             throw std::runtime_error("cannot use -c and -C options simultaneously");
     167              :           else
     168            0 :             class_name = std::move(class_name2);
     169              :         }
     170              : 
     171            0 :       if (vm.count("changes"))
     172            0 :         changes = true;
     173              : 
     174            0 :       if (!vesrions_str.empty())
     175              :         {
     176            0 :           if (vesrions_str.size() != 4)
     177              :             {
     178            0 :               throw std::runtime_error("-v option must have 4 parameters, see help");
     179              :             }
     180              :           else
     181              :             {
     182            0 :               if (vesrions_str[0] == "all")
     183              :                 skip_irrelevant = false;
     184            0 :               else if (vesrions_str[0] != "skip")
     185            0 :                 throw std::runtime_error("first parameter of -v has to be \"all\" or \"skip\"");
     186              : 
     187            0 :               if (vesrions_str[1] == "date")
     188              :                 query_type = dunedaq::conffwk::Version::query_by_date;
     189            0 :               else if (vesrions_str[1] == "id")
     190              :                 query_type = dunedaq::conffwk::Version::query_by_id;
     191            0 :               else if (vesrions_str[1] != "tag")
     192            0 :                 throw std::runtime_error("second versions parameter must be \"date\", \"id\" or \"tag\"");
     193              : 
     194            0 :               since = vesrions_str[2];
     195            0 :               until = vesrions_str[3];
     196              :             }
     197              :         }
     198              : 
     199            0 :       if (!object_id.empty())
     200            0 :         objects_details = true;
     201              : 
     202            0 :       if (vm.count("list-objects"))
     203              :         {
     204            0 :           objects_details = false;
     205            0 :           object_id = any;
     206              :         }
     207              : 
     208            0 :       if (vm.count("print-referenced-by"))
     209            0 :         referenced_by = true;
     210              : 
     211            0 :       if (vm.count("show-contained-in"))
     212            0 :         contained_in = true;
     213              : 
     214            0 :       if (class_name.empty() && !object_id.empty() && object_id != any)
     215            0 :         throw std::runtime_error("object id is set, but no class name given (use -c option)");
     216            0 :     }
     217            0 :   catch (std::exception &ex)
     218              :     {
     219            0 :       ers::fatal(config_dump::BadCommandLine(ERS_HERE, ex.what()));
     220            0 :       return EXIT_FAILURE;
     221            0 :     }
     222              : 
     223              : 
     224            0 :   try
     225              :     {
     226            0 :       Configuration conf(db_name);
     227              : 
     228              :       // get versions if any
     229            0 :       if (changes)
     230              :         {
     231            0 :           std::cout << "Changes:\n";
     232            0 :           print_versions(conf.get_changes());
     233            0 :           return EXIT_SUCCESS;
     234              :         }
     235              : 
     236            0 :       if (!since.empty())
     237              :         {
     238            0 :           std::cout << "Versions:\n";
     239            0 :           print_versions(conf.get_versions(since, until, query_type, skip_irrelevant));
     240            0 :           return EXIT_SUCCESS;
     241              :         }
     242              : 
     243            0 :       std::set<std::string> classes;
     244              : 
     245            0 :       if (!class_name.empty() && class_name != any)
     246            0 :         classes.insert(class_name);
     247              :       else
     248            0 :         for (const auto &i : conf.superclasses())
     249            0 :           classes.insert(*i.first);
     250              : 
     251              :       // if there are no options, just list classes
     252            0 :       if (class_name.empty() && object_id.empty())
     253              :         {
     254            0 :           std::cout << "The database schema has " << classes.size() << " class(es):\n";
     255            0 :           for (const auto &i : classes)
     256            0 :             std::cout << " - \'" << i << "\'\n";
     257            0 :           return EXIT_SUCCESS;
     258              :         }
     259              : 
     260              :       // only print details of classes
     261            0 :       if (!class_name.empty() && object_id.empty())
     262              :         {
     263            0 :           if (class_name == any)
     264            0 :             std::cout << "The database schema has " << classes.size() << " class(es):\n";
     265              : 
     266            0 :           for (const auto &i : classes)
     267            0 :             conf.get_class_info(i, direct_info).print(std::cout, "  ");
     268              : 
     269            0 :           return EXIT_SUCCESS;
     270              :         }
     271              : 
     272            0 :       const char *prefix = "";
     273            0 :       const char *prefix2 = "  ";
     274            0 :       const char *prefix3 = "    ";
     275              : 
     276              :       // list or print all objects of class(es)
     277            0 :       if (object_id == any)
     278              :         {
     279            0 :           if (class_name.empty() || class_name == any)
     280              :             {
     281            0 :               std::cout << "The database schema has " << classes.size() << " class(es):\n";
     282              :               prefix = "  ";
     283              :               prefix2 = "    ";
     284              :               prefix3 = "      ";
     285              :             }
     286              : 
     287            0 :           for (std::set<std::string>::const_iterator i = classes.begin(); i != classes.end(); ++i)
     288              :             {
     289            0 :               std::vector<ConfigObject> objects;
     290            0 :               conf.get(*i, objects);
     291            0 :               if (objects.empty())
     292              :                 {
     293            0 :                   std::cout << prefix << "The class \'" << *i << "\' has no objects\n";
     294              :                 }
     295              :               else
     296              :                 {
     297            0 :                   std::cout << prefix << "The class \'" << *i << "\' has " << objects.size() << " object(s) including sub-classes:\n";
     298              : 
     299              :                   // sort by ID for consistent output
     300            0 :                   std::set<const ConfigObject*, SortByName> sorted_by_id;
     301              : 
     302            0 :                   for (const auto &j : objects)
     303            0 :                     sorted_by_id.insert(&j);
     304              : 
     305            0 :                   for (const auto &j : sorted_by_id)
     306            0 :                     if (j->class_name() == *i)
     307              :                       {
     308            0 :                         if (objects_details)
     309            0 :                           j->print_ref(std::cout, conf, prefix2, contained_in);
     310              :                         else
     311            0 :                           std::cout << prefix << " - \'" << j->UID() << "\'\n";
     312              : 
     313            0 :                         if (referenced_by)
     314            0 :                           print_referenced_by(*j, prefix3);
     315              :                       }
     316              :                     else
     317              :                       {
     318            0 :                         std::cout << prefix << " - \'" << j->UID() << "\' (database class name = \'" << j->class_name() << "\')\n";
     319              :                       }
     320            0 :                 }
     321            0 :             }
     322              :         }
     323              :       else
     324              :         {
     325            0 :           ConfigObject obj;
     326            0 :           conf.get(class_name, object_id, obj);
     327            0 :           obj.print_ref(std::cout, conf, "", contained_in);
     328            0 :           if (referenced_by)
     329            0 :             print_referenced_by(obj, prefix2);
     330            0 :         }
     331            0 :     }
     332            0 :   catch (dunedaq::conffwk::Exception &ex)
     333              :     {
     334            0 :       ers::fatal(config_dump::ConfigException(ERS_HERE, ex));
     335            0 :       return EXIT_FAILURE;
     336            0 :     }
     337              : 
     338            0 :   return EXIT_SUCCESS;
     339            0 : }
        

Generated by: LCOV version 2.0-1