LCOV - code coverage report
Current view: top level - oks/apps - oks_dump.cxx (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 177 0
Test Date: 2026-07-12 15:23:06 Functions: 0.0 % 4 0

            Line data    Source code
       1              : // DUNE DAQ modification notice:
       2              : // This file has been modified from the original ATLAS oks source for the DUNE DAQ project.
       3              : // Fork baseline commit: oks-08-03-04 (2022-04-14).
       4              : // Renamed since fork: yes (from bin/oks_dump.cpp to apps/oks_dump.cxx).
       5              : 
       6              : /**
       7              :  *  \file oks_dump.cpp
       8              :  *
       9              :  *  This file is part of the OKS package.
      10              :  *  Author: <Igor.Soloviev@cern.ch>
      11              :  *
      12              :  *  This file contains the implementation of the OKS application to dump
      13              :  *  contents of the OKS database files.
      14              :  *
      15              :  */
      16              : 
      17              : #include "oks/kernel.hpp"
      18              : #include "oks/query.hpp"
      19              : #include "oks/exceptions.hpp"
      20              : 
      21              : #include <vector>
      22              : #include <iostream>
      23              : 
      24              : #include <string.h>
      25              : #include <stdlib.h>
      26              : 
      27              : using namespace dunedaq::oks;
      28              : 
      29              : enum __OksDumpExitStatus__ {
      30              :   __Success__ = 0,
      31              :   __BadCommandLine__,
      32              :   __BadOksFile__,
      33              :   __BadQuery__,
      34              :   __NoSuchClass__,
      35              :   __FoundDanglingReferences__,
      36              :   __ExceptionCaught__
      37              : };
      38              : 
      39              : 
      40              : static void
      41            0 : printUsage(std::ostream& s)
      42              : {
      43            0 :   s << "Usage: oks_dump\n"
      44              :        "    [--files-only | --files-stat-only | --schema-files-only | --schema-files-stat-only | --data-files-only | --data-files-stat-only]\n"
      45              :        "    [--class name-of-class [--query query [--print-references recursion-depth [class-name*] [--]] [--print-referenced_by [name] [--]]]]\n"
      46              :        "    [--path object-from object-to query]\n"
      47              :        "    [--allow-duplicated-objects-via-inheritance]\n"
      48              :        "    [--version]\n"
      49              :        "    [--help]\n"
      50              :        "    [--input-from-files] database-file [database-file(s)]\n"
      51              :        "\n"
      52              :        "Options:\n"
      53              :        "    -f | --files-only                                 print list of oks files names\n"
      54              :        "    -F | --files-stat-only                            print list of oks files with statistic details (size, number of items\n" 
      55              :        "    -s | --schema-files-only                          print list of schema oks files names\n"
      56              :        "    -S | --schema-files-stat-only                     print list of oks schema files with statistic details\n"
      57              :        "    -d | --data-files-only                            print list of data oks files names\n"
      58              :        "    -D | --data-files-stat-only                       print list of oks data files with statistic details\n"
      59              :        "    -c | --class class_name                           dump given class (all objects or matching some query)\n"
      60              :        "    -q | --query query                                print objects matching query (can only be used with class)\n"
      61              :        "    -r | --print-references N C1 C2 ... CX            print objects referenced by found objects (can only be used with query), where:\n"
      62              :        "                                                       * the parameter N defines recursion depth for referenced objects (> 0)\n"
      63              :        "                                                       * the optional set of names {C1 .. CX} defines [sub-]classes for above objects\n"
      64              :        "    -b | --print-referenced_by [name]                 print objects referencing found objects (can only be used with query), where:\n"
      65              :        "                                                       * the optional parameter name defines name of relationship\n"
      66              :        "    -p | --path obj query                             print path from object \'obj\' to object of query expression\n"
      67              :        "    -i | --input-from-files                           read oks files to be loaded from file(s) instead of command line\n"
      68              :        "                                                      (to avoid problems with long command line, when there is huge number of files)\n"
      69              :        "    -a | --allow-duplicated-objects-via-inheritance   do not stop if there are duplicated object via inheritance hierarchy\n"
      70              :        "    -v | --version                                    print version\n"
      71              :        "    -h | --help                                       print this text\n"
      72              :        "\n"
      73              :        "Description:\n"
      74              :        "    Dumps contents of the OKS database.\n"
      75              :        "\n"
      76              :        "Return Status:\n"
      77              :        "    0 - no problems found\n"
      78              :        "    1 - bad command line parameter\n"
      79              :        "    2 - bad oks file(s)\n"
      80              :        "    3 - bad query passed via -q or -p options\n"
      81              :        "    4 - cannot find class passed via -c option\n"
      82              :        "    5 - loaded objects have dangling references\n"
      83              :        "    6 - caught an exception\n"
      84            0 :        "\n";
      85            0 : }
      86              : 
      87              : static void
      88            0 : no_param(const char * s)
      89              : {
      90            0 :   Oks::error_msg("oks_dump") << "no parameter(s) for command line argument \'" << s << "\' provided\n\n";
      91            0 :   exit(EXIT_FAILURE);
      92              : }
      93              : 
      94              : OksObject*
      95            0 : find_object(char * s, OksKernel& k)
      96              : {
      97            0 :   char * id = s;
      98              : 
      99            0 :   if((s = strchr(id, '@')) == 0) return 0;
     100              : 
     101            0 :   *s = '\0';
     102            0 :   s++;
     103              : 
     104            0 :   if(OksClass * c = k.find_class(s)) {
     105            0 :     if(OksObject * o = c->get_object(id)) {
     106              :       return o;
     107              :     }
     108              :     else {
     109            0 :       Oks::error_msg("oks_dump::find_object()") << "cannot find object \"" << id << '@' << s << "\"\n";
     110              :     }
     111              :   }
     112              :   else {
     113            0 :     Oks::error_msg("oks_dump::find_object()") << "cannot find class \"" << s << "\"\n";
     114              :   }
     115              : 
     116              :   return 0;
     117              : }
     118              : 
     119              : int
     120            0 : main(int argc, char **argv)
     121              : {
     122            0 :   if(argc == 1) {
     123            0 :     printUsage(std::cerr);
     124            0 :     return __BadCommandLine__;
     125              :   }
     126              : 
     127            0 :   OksKernel kernel;
     128            0 :   kernel.set_test_duplicated_objects_via_inheritance_mode(true);
     129              : 
     130            0 :   try {
     131              : 
     132            0 :     int dump_files_only = 0; // 0 - none, 12 - data, 1 - schema, 2 - schema & data
     133            0 :     const char * class_name = 0;
     134            0 :     const char * query = 0;
     135            0 :     const char * object_from = 0;
     136            0 :     const char * path_query = 0;
     137            0 :     long recursion_depth = 0;
     138            0 :     bool print_referenced_by = false;
     139            0 :     const char * ref_by_rel_name = "*";
     140            0 :     std::vector<std::string> ref_classes;
     141            0 :     bool input_from_files = false;
     142            0 :     bool print_files_stat = false;
     143              : 
     144            0 :     for(int i = 1; i < argc; i++) {
     145            0 :       const char * cp = argv[i];
     146              : 
     147            0 :       if(!strcmp(cp, "-h") || !strcmp(cp, "--help")) {
     148            0 :         printUsage(std::cout);          
     149              :         return __Success__;
     150              :       }
     151            0 :       else if(!strcmp(cp, "-v") || !strcmp(cp, "--version")) {
     152            0 :         std::cout << "OKS kernel version " << OksKernel::GetVersion() << std::endl;         
     153              :         return __Success__;
     154              :       }
     155            0 :       else if(!strcmp(cp, "-a") || !strcmp(cp, "--allow-duplicated-objects-via-inheritance")) {
     156            0 :         kernel.set_test_duplicated_objects_via_inheritance_mode(false);
     157              :       }
     158            0 :       else if(!strcmp(cp, "-f") || !strcmp(cp, "--files-only")) {
     159              :         dump_files_only = 2;
     160              :       }
     161            0 :       else if(!strcmp(cp, "-F") || !strcmp(cp, "--files-stat-only")) {
     162              :         dump_files_only = 2;
     163              :         print_files_stat = true;
     164              :       }
     165            0 :       else if(!strcmp(cp, "-s") || !strcmp(cp, "--schema-files-only")) {
     166              :         dump_files_only = 1;
     167              :       }
     168            0 :       else if(!strcmp(cp, "-S") || !strcmp(cp, "--schema-files-stat-only")) {
     169              :         dump_files_only = 1;
     170              :         print_files_stat = true;
     171              :       }
     172            0 :       else if(!strcmp(cp, "-d") || !strcmp(cp, "--data-files-only")) {
     173              :         dump_files_only = 12;
     174              :       }
     175            0 :       else if(!strcmp(cp, "-D") || !strcmp(cp, "--data-files-stat-only")) {
     176              :         dump_files_only = 12;
     177              :         print_files_stat = true;
     178              :       }
     179            0 :       else if(!strcmp(cp, "-c") || !strcmp(cp, "--class")) {
     180            0 :         if(++i == argc) { no_param(cp); } else { class_name = argv[i]; }
     181              :       }
     182            0 :       else if(!strcmp(cp, "-q") || !strcmp(cp, "--query")) {
     183            0 :         if(++i == argc) { no_param(cp); } else { query = argv[i]; }
     184              :       }
     185            0 :       else if(!strcmp(cp, "-i") || !strcmp(cp, "--input-from-files")) {
     186              :         input_from_files = true;
     187              :       }
     188            0 :       else if(!strcmp(cp, "-r") || !strcmp(cp, "--print-references")) {
     189            0 :         if(++i == argc) { no_param(cp); } else { recursion_depth = atol(argv[i]); }
     190            0 :         int j = 0;
     191            0 :         for(; j < argc - i - 1; ++j) {
     192            0 :           if(argv[i+1+j][0] != '-') { ref_classes.push_back(argv[i+1+j]); } else { break; }
     193              :         }
     194            0 :         i += j;
     195            0 :       }
     196            0 :       else if(!strcmp(cp, "-b") || !strcmp(cp, "--print-referenced_by")) {
     197            0 :         print_referenced_by = true;
     198            0 :         if((i+1) < argc && argv[i+1][0] != '-') {
     199            0 :           ref_by_rel_name = argv[++i];
     200              :         }
     201              :       }
     202            0 :       else if(!strcmp(cp, "-p") || !strcmp(cp, "--path")) {
     203            0 :         if(++i > argc - 1) { no_param(cp); } else { object_from = argv[i]; path_query = argv[++i];}
     204              :       }
     205            0 :       else if(strcmp(cp, "--")) {
     206            0 :         if(input_from_files) {
     207            0 :           std::ifstream f(cp);
     208            0 :           if(f.good()) {
     209            0 :             while(f.good() && !f.eof()) {
     210            0 :               std::string file_name;
     211            0 :               std::getline(f, file_name);
     212            0 :               if(!file_name.empty() && kernel.load_file(file_name) == 0) {
     213            0 :                 Oks::error_msg("oks_dump") << "\tCan not load file \"" << file_name << "\", exiting...\n";
     214            0 :                 return __BadOksFile__;
     215              :               }
     216            0 :             }
     217              :           }
     218              :           else {
     219            0 :             Oks::error_msg("oks_dump") << "\tCan not open file \"" << cp << "\" for reading, exiting...\n";
     220              :             return __BadCommandLine__;
     221              :           }
     222            0 :         }
     223              :         else {
     224            0 :           if(kernel.load_file(cp) == 0) {
     225            0 :             Oks::error_msg("oks_dump") << "\tCan not load file \"" << cp << "\", exiting...\n";
     226              :             return __BadOksFile__;
     227              :           }
     228              :         }
     229              :       }
     230              :     }
     231              : 
     232            0 :     if(kernel.schema_files().empty()) {
     233            0 :       Oks::error_msg("oks_dump") << "\tAt least one oks file have to be provided, exiting...\n";
     234              :       return __BadCommandLine__;
     235              :     }
     236              : 
     237            0 :     if(query && !class_name) {
     238            0 :       Oks::error_msg("oks_dump") << "\tQuery can only be executed when class name is provided (use -c option), exiting...\n";
     239              :       return __BadCommandLine__;
     240              :     }
     241              : 
     242            0 :     if(dump_files_only) {
     243            0 :       long total_size = 0;
     244            0 :       long total_items = 0;
     245            0 :       const OksFile::Map * files [2] = {&kernel.schema_files(), &kernel.data_files()};
     246            0 :       for(int j = (dump_files_only / 10); j < (dump_files_only % 10); ++j) {
     247            0 :         if(!files[j]->empty()) {
     248            0 :           for(OksFile::Map::const_iterator i = files[j]->begin(); i != files[j]->end(); ++i) {
     249            0 :             if(print_files_stat) {
     250            0 :               total_size += i->second->get_size();
     251            0 :               total_items += i->second->get_number_of_items();
     252            0 :               std::cout << *(i->first) << " (" << i->second->get_number_of_items() << " items, " << i->second->get_size() << " bytes)" << std::endl;
     253              :             }
     254              :             else {
     255            0 :               std::cout << *(i->first) << std::endl;
     256              :             }
     257              :           }
     258              :         }
     259              :       }
     260              : 
     261            0 :       if(print_files_stat) {
     262            0 :         std::cout << "Total number of items: " << total_items << "\n"
     263            0 :                      "Total size of files: " << total_size << " bytes" << std::endl;
     264              :       }
     265              :     }
     266            0 :     else if(class_name && *class_name) {
     267            0 :       if(OksClass * c = kernel.find_class(class_name)) {
     268            0 :         if(query && *query) {
     269            0 :           OksQuery * q = new OksQuery(c, query);
     270            0 :           if(q->good()) {
     271            0 :             OksObject::List * objs = c->execute_query(q);
     272            0 :             size_t num = (objs ? objs->size() : 0);
     273            0 :             std::cout << "Found " << num << " matching query \"" << query << "\" in class \"" << class_name << "\"";
     274            0 :             if(num) {
     275            0 :               std::cout << ':' << std::endl;
     276            0 :               while(!objs->empty()) {
     277            0 :                 OksObject * o = objs->front();
     278            0 :                 objs->pop_front();
     279              :                 
     280            0 :                 if(recursion_depth > 0 || print_referenced_by) {
     281            0 :                   if(recursion_depth) {
     282            0 :                     ClassSet all_ref_classes;
     283            0 :                     kernel.get_all_classes(ref_classes, all_ref_classes);
     284            0 :                     OksObject::FSet refs;
     285            0 :                     o->references(refs, recursion_depth, false, &all_ref_classes);
     286            0 :                     std::cout << o << " references " << refs.size() << " object(s)" << std::endl;
     287            0 :                     for(OksObject::FSet::const_iterator i = refs.begin(); i != refs.end(); ++i) {
     288            0 :                       std::cout << " - " << *i << std::endl;
     289              :                     }
     290            0 :                   }
     291            0 :                   if(print_referenced_by) {
     292            0 :                     if(OksObject::FList * ref_by_objs = o->get_all_rels(ref_by_rel_name)) {
     293            0 :                       std::cout << o << " is referenced by " << ref_by_objs->size() << " object(s) via relationship \"" << ref_by_rel_name << "\":" << std::endl;
     294              : 
     295            0 :                       for(OksObject::FList::const_iterator i = ref_by_objs->begin(); i != ref_by_objs->end(); ++i) {
     296            0 :                         std::cout << " - " << *i << std::endl;
     297              :                       }
     298              :                       
     299            0 :                       delete ref_by_objs;
     300              :                     }
     301              :                     else {
     302            0 :                       std::cout << o << " is not referenced by any object via relationship \"" << ref_by_rel_name << '\"' << std::endl;
     303              :                     }
     304              :                   }
     305              :                 }
     306              :                 else {
     307            0 :                   std::cout << *o << std::endl;
     308              :                 }
     309              :               }
     310            0 :               delete objs;
     311              :             }
     312              :             else {
     313            0 :               std::cout << std::endl;
     314              :             }
     315              :           }
     316              :           else {
     317            0 :             Oks::error_msg("oks_dump") << "\tFailed to parse query \"" << query << "\" in class \"" << class_name << "\"\n";
     318              :             return __BadQuery__;
     319              :           }
     320            0 :           delete q;
     321              :         }
     322              :         else {
     323            0 :           std::cout << *c << std::endl;
     324              :         }
     325              :       }
     326              :       else {
     327            0 :         Oks::error_msg("oks_dump") << "\tCan not find class \"" << class_name << "\"\n";
     328              :         return __NoSuchClass__;
     329              :       }
     330              :     }
     331            0 :     else if(object_from && *object_from && path_query && *path_query) {
     332            0 :       OksObject * obj_from = find_object((char *)object_from, kernel);
     333            0 :       try {
     334            0 :         QueryPath q(path_query, kernel);
     335            0 :         OksObject::List * objs = obj_from->find_path(q);
     336              : 
     337            0 :         size_t num = (objs ? objs->size() : 0);
     338            0 :         std::cout << "Found " << num << " objects in the path \"" << q << "\" from object " << obj_from << ":" << std::endl;
     339              : 
     340            0 :         if(num) {
     341            0 :           while(!objs->empty()) {
     342            0 :             OksObject * o = objs->front();
     343            0 :             objs->pop_front();
     344            0 :             std::cout << *o << std::endl;
     345              :           }
     346            0 :           delete objs;
     347              :         }
     348            0 :       }
     349            0 :       catch ( bad_query_syntax& e ) {
     350            0 :         Oks::error_msg("oks_dump") << "\tFailed to parse query: " << e.what() << std::endl;
     351            0 :         return __BadQuery__;
     352            0 :       }
     353            0 :     }
     354              :     else {
     355            0 :       std::cout << kernel;
     356              :     }
     357              : 
     358            0 :     if(!kernel.get_bind_classes_status().empty())
     359              :       {
     360            0 :         Oks::error_msg("oks_dump") << "The schema contains dangling references to non-loaded classes:\n" << kernel.get_bind_classes_status();
     361              :       }
     362              : 
     363            0 :     if(!kernel.get_bind_objects_status().empty())
     364              :       {
     365            0 :         Oks::error_msg("oks_dump") << "\tThe data contain dangling references to non-loaded objects\n";
     366              :       }
     367              : 
     368            0 :     if(!kernel.get_bind_classes_status().empty() || !kernel.get_bind_objects_status().empty())
     369              :       {
     370              :         return __FoundDanglingReferences__;
     371              :       }
     372            0 :   }
     373            0 :   catch (exception & ex) {
     374            0 :     std::cerr << "Caught oks exception:\n" << ex << std::endl;
     375            0 :     return __ExceptionCaught__;
     376            0 :   }
     377            0 :   catch (std::exception & e) {
     378            0 :     std::cerr << "Caught standard C++ exception: " << e.what() << std::endl;
     379            0 :     return __ExceptionCaught__;
     380            0 :   }
     381            0 :   catch (...) {
     382            0 :     std::cerr << "Caught unknown exception" << std::endl;
     383            0 :     return __ExceptionCaught__;
     384            0 :   }
     385              : 
     386            0 :   return __Success__;
     387            0 : }
        

Generated by: LCOV version 2.0-1