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

            Line data    Source code
       1              : //
       2              : // DUNE DAQ modification notice:
       3              : // This file has been modified from the original ATLAS oks_utils source for the DUNE DAQ project.
       4              : // Fork baseline commit: c2e7dfc7 (2022-03-30).
       5              : // Renamed since fork: yes (from src/bin/oks_tutorial.cpp to apps/oks_tutorial.cxx).
       6              : //
       7              : 
       8              : /************************************************************************
       9              : *                                                                       *
      10              : * tutorial.cpp                                                          *
      11              : *        Explains basics of OKS C++ API including:                      *
      12              : *                - kernel initialization                                *
      13              : *                - schema design                                        *
      14              : *                - data creation                                        *
      15              : *                - data manipulation                                    *
      16              : *                - notification                                         *
      17              : *                                                                       *
      18              : * Author Igor Soloviev                                                  *
      19              : *                                                                       *
      20              : * Created: 14 Oct 1996                                                  *
      21              : *                                                                       *
      22              : * Modified:                                                             *
      23              : *        11 Feb 1998                                                    *
      24              : *                - add database quering                                 *
      25              : *                                                                       *
      26              : ************************************************************************/
      27              : 
      28              : #include <boost/date_time/gregorian/gregorian.hpp>
      29              : 
      30              : #include "oks/kernel.hpp"
      31              : #include "oks/object.hpp"
      32              : #include "oks/class.hpp"
      33              : #include "oks/attribute.hpp"
      34              : #include "oks/relationship.hpp"
      35              : #include "oks/query.hpp"
      36              : #include "oks/exceptions.hpp"
      37              : 
      38              : using namespace dunedaq;
      39              : using namespace dunedaq::oks;
      40              : 
      41              :   //
      42              :   // This function sets attribute values of class 'Person'
      43              :   //
      44              : 
      45              : void
      46            0 : setPersonValues(
      47              :   OksObject *o,                    // OKS object describing person
      48              :   const char *name,                // new person name
      49              :   boost::gregorian::date birthday, // new person birthday
      50              :   const char *familySituation      // new person family situation
      51              : )
      52              : {
      53            0 :   OksData d;                       // creates OKS data with unknown type
      54              : 
      55            0 :   d.Set(name);                     // sets OKS data to string 'name'
      56            0 :   o->SetAttributeValue("Name", &d);
      57              : 
      58            0 :   d.Set(birthday);                 // sets OKS data to date 'birthday'
      59            0 :   o->SetAttributeValue("Birthday", &d);
      60              : 
      61            0 :   d.Set(familySituation);          // sets OKS data to 'familySituation'
      62            0 :   d.type = OksData::enum_type;     // sets OKS data type to enumeration
      63            0 :   o->SetAttributeValue("Family_Situation", &d);
      64            0 : }
      65              : 
      66              : 
      67              :   //
      68              :   // This function prints an instance of class 'Person'
      69              :   //
      70              : 
      71              : void
      72            0 : printPerson(
      73              :   const OksObject *o               // OKS object describing person
      74              : )
      75              : {
      76            0 :   OksData * name(o->GetAttributeValue("Name"));                 // is used to store 'Name'
      77            0 :   OksData * birthday(o->GetAttributeValue("Birthday"));         // is used to store 'Birthday'
      78            0 :   OksData * family(o->GetAttributeValue("Family_Situation"));   // is used to store 'Family_Situation'
      79              : 
      80            0 :   std::cout << "Object " << o << " \n"
      81            0 :              " Name: " << *name << " \n"
      82            0 :              " Birthday: \'" << *birthday << "\" \n"
      83            0 :              " Family_Situation: " << *family << std::endl;
      84            0 : }
      85              : 
      86              : 
      87              :   //
      88              :   // This function sets attribute values of class 'Employee'
      89              :   //
      90              : 
      91              : void
      92            0 : setEmployeeValues(
      93              :   OksObject *o,                    // OKS object that describes employee
      94              :   const char *name,                // new employee name
      95              :   boost::gregorian::date birthday, // new employee birthday
      96              :   const char *familySituation,     // new employee family situation
      97              :   uint32_t salary                  // new employee salary situation
      98              : ) 
      99              : {
     100              :     // we can use setPersonValues() because 'Employee' class
     101              :     // derived from 'Person' class
     102              : 
     103            0 :   setPersonValues(o, name, birthday, familySituation);
     104              : 
     105            0 :   OksData d(salary);               // creates OKS data with ulong 'salary'
     106            0 :   o->SetAttributeValue("Salary", &d);
     107            0 : }
     108              : 
     109              : 
     110              :   //
     111              :   // This function prints an instance of class 'Employee'
     112              :   //
     113              : 
     114              : void
     115            0 : printEmployee(
     116              :   const OksObject *o               // OKS object that describes employee
     117              : )
     118              : {
     119              :     // we can use printPerson() because 'Employee' class
     120              :     // is derived from 'Person' class
     121              : 
     122            0 :   printPerson(o);
     123              : 
     124            0 :   OksData *department(o->GetRelationshipValue("Works at")),  // is used to store 'Works at'
     125            0 :           *salary(o->GetAttributeValue("Salary"));           // is used to store 'salary'
     126              : 
     127            0 :   std::cout << " Salary: " << *salary << " \n"
     128            0 :                " Works at: \"" << department->data.OBJECT->GetId() << "\"\n";
     129            0 : }
     130              : 
     131              : 
     132              :   //
     133              :   // This function sets attribute values of class 'Department'
     134              :   //
     135              : 
     136              : void
     137            0 : setDepartmentValues(
     138              :   OksObject *o,                    // OKS object that describes department
     139              :   const char *name                 // new department name
     140              : ) 
     141              : {
     142            0 :   OksData d(name);                 // creates OKS data with string 'name'
     143              : 
     144            0 :   o->SetAttributeValue("Name", &d);
     145            0 : }
     146              : 
     147              : 
     148              :   //
     149              :   // This function prints an instance of class 'Department'
     150              :   //
     151              : 
     152              : void
     153            0 : printDepartment(
     154              :   const OksObject *o               // OKS object that describes department
     155              : )
     156              : {
     157            0 :   OksData *name(o->GetAttributeValue("Name")),       // is used to store 'Staff'
     158            0 :           *staff(o->GetRelationshipValue("Staff"));  // is used to store 'Name'
     159              : 
     160            0 :   std::cout << "Object " << o << "\n"
     161            0 :                " Name: " << *name << " \n"
     162            0 :                " Staff: \"" << *staff << "\"\n";
     163            0 : }
     164              : 
     165              : 
     166              : int
     167            0 : main(int argc, char **argv)
     168              : {
     169            0 :   const char * schema_file = "/tmp/tutorial.oks"; // default schema file
     170            0 :   const char * data_file   = "/tmp/tutorial.okd"; // default data file
     171              : 
     172            0 :   if(
     173            0 :     argc > 1 &&
     174              :     (
     175            0 :       !strcmp(argv[1], "--help") ||
     176            0 :       !strcmp(argv[1], "-help") ||
     177            0 :       !strcmp(argv[1], "--h") ||
     178            0 :       !strcmp(argv[1], "-h")
     179              :     )
     180              :   ) {
     181            0 :     std::cout << "Usage: " << argv[0] << " [new_schema new_data]\n";
     182            0 :     return 0;
     183              :   }
     184              : 
     185            0 :   if(argc == 3) {
     186            0 :     schema_file = argv[1];
     187            0 :     data_file = argv[2];
     188              :   }
     189              : 
     190              : 
     191              :     // Creates OKS kernel
     192              : 
     193            0 :   std::cout << "[OKS TUTORIAL]: Creating OKS kernel...\n";
     194              : 
     195            0 :   OksKernel kernel(false, false, false, false);
     196              : 
     197            0 :   std::cout << "[OKS TUTORIAL]: Done creating OKS kernel\n\n";
     198              : 
     199              : 
     200            0 :   try {        
     201              : 
     202              : 
     203              :       // Creates new schema file and tests return status
     204              : 
     205            0 :     std::cout << "[OKS TUTORIAL]: Creating new schema file...\n";
     206              : 
     207            0 :     OksFile * schema_h = kernel.new_schema(schema_file);
     208              : 
     209            0 :     std::cout << "[OKS TUTORIAL]: Done creating new schema file...\n\n"
     210              :                  "[OKS TUTORIAL]: Define database class schema...\n\n"
     211              :                  "  **********        ************     1..1 **************\n"
     212              :                  "  * Person *<|------* Employee *--------<>* Department *\n"
     213            0 :                  "  **********        ************ 0..N     **************\n\n";
     214              : 
     215              : 
     216              :       // Creates class Person with three attributes "Name", "Birthday" and "Family_Situation"
     217              : 
     218            0 :     OksClass * Person = new OksClass(
     219              :       "Person",
     220              :       "It is a class to describe a person",
     221              :       false,
     222              :       &kernel
     223            0 :     );
     224              : 
     225            0 :     Person->add(
     226              :       new OksAttribute(
     227              :         "Name",
     228              :         OksAttribute::string_type,
     229              :         false,
     230              :         "",
     231              :         "Unknown",
     232              :         "A string to describe person name",
     233              :         true
     234            0 :       )
     235              :     );
     236              : 
     237            0 :     OksAttribute * PersonBirthday = new OksAttribute(
     238              :       "Birthday",
     239              :       OksAttribute::date_type,
     240              :       false,
     241              :       "",
     242              :       "2009/01/01",
     243              :       "A date to describe person birthday",
     244              :       true
     245            0 :     );
     246              : 
     247            0 :     Person->add(PersonBirthday);
     248              : 
     249            0 :     Person->add(
     250              :       new OksAttribute(
     251              :         "Family_Situation",
     252              :         OksAttribute::enum_type,
     253              :         false,
     254              :         "Single,Married,Widow(er)",
     255              :         "Single",
     256              :         "A enumeration to describe a person family state",
     257              :         true
     258            0 :       )
     259              :     );
     260              : 
     261              : 
     262              :       // Creates class Person with superclass Person, add "Salary" attribute and "Works at" relationship
     263              : 
     264            0 :     OksClass * Employee = new OksClass(
     265              :       "Employee",
     266              :       "It is a class to describe an employee",
     267              :       false,
     268              :       &kernel
     269            0 :     );
     270              : 
     271            0 :     OksAttribute * EmployeeSalary = new OksAttribute(
     272              :       "Salary",
     273              :       OksAttribute::u32_int_type,
     274              :       false,
     275              :       "",
     276              :       "1000",
     277              :       "An integer to describe employee salary",
     278              :       false
     279            0 :     );
     280              : 
     281            0 :     OksRelationship * WorksAt = new OksRelationship(
     282              :       "Works at",
     283              :       "Department",
     284              :       OksRelationship::One,
     285              :       OksRelationship::One,
     286              :       false,
     287              :       false,
     288              :       false,
     289              :       "A employee works at one and only one department"
     290            0 :     );
     291              :   
     292            0 :     Employee->add_super_class("Person");
     293            0 :     Employee->add(EmployeeSalary);
     294            0 :     Employee->add(WorksAt);
     295              : 
     296              : 
     297              :       // Creates class Department with one attribute and one relationship
     298              : 
     299            0 :     OksClass * Department = new OksClass(
     300              :       "Department",
     301              :       "It is a class to describe a department",
     302              :       false,
     303              :       &kernel
     304            0 :     );
     305              : 
     306            0 :     OksAttribute * DepartmentName = new OksAttribute(
     307              :       "Name",
     308              :       OksAttribute::string_type,
     309              :       false,
     310              :       "",
     311              :       "Unknown",
     312              :       "A string to describe department name",
     313              :       true
     314            0 :     );
     315              : 
     316            0 :     OksRelationship *DepartmentStaff = new OksRelationship(
     317              :       "Staff",
     318              :       "Employee",
     319              :       OksRelationship::Zero,
     320              :       OksRelationship::Many,
     321              :       true,
     322              :       true,
     323              :       true,
     324              :       "A department has zero or many employess"
     325            0 :     );
     326              : 
     327            0 :     Department->add(DepartmentName);
     328            0 :     Department->add(DepartmentStaff);
     329              : 
     330              : 
     331              :       // Saves created schema file
     332              : 
     333            0 :     std::cout << "[OKS TUTORIAL]: Saves created OKS schema file...\n";
     334              : 
     335            0 :     kernel.save_schema(schema_h);
     336              : 
     337              : 
     338              :       // Creates new data file and tests return status
     339              : 
     340            0 :     std::cout << "[OKS TUTORIAL]: Creating new data file...\n";
     341              : 
     342            0 :     OksFile * data_h = kernel.new_data(data_file, "OKS TUTORIAL DATA FILE");
     343              : 
     344            0 :     data_h->add_include_file(schema_file);
     345              : 
     346              : 
     347              :       // Creates instances of the classes
     348              : 
     349            0 :     OksObject * person1     = new OksObject(Person, "peter");
     350            0 :     OksObject * person2     = new OksObject(Person, "mick");
     351            0 :     OksObject * person3     = new OksObject(Person, "baby");
     352            0 :     OksObject * employee1   = new OksObject(Employee, "alexander");
     353            0 :     OksObject * employee2   = new OksObject(Employee, "michel");
     354            0 :     OksObject * employee3   = new OksObject(Employee, "maria");
     355            0 :     OksObject * department1 = new OksObject(Department, "IT");
     356            0 :     OksObject * department2 = new OksObject(Department, "EP");
     357              : 
     358              : 
     359              :       // Sets attribute values for instances of class 'Person'
     360              : 
     361            0 :     setPersonValues(person1, "Peter", boost::gregorian::from_string("1960/02/01"), "Married");
     362            0 :     setPersonValues(person2, "Mick", boost::gregorian::from_string("1956-09-01"), "Single");
     363            0 :     setPersonValues(person3, "Julia", boost::gregorian::from_string("2000-May-25"), "Single");
     364              : 
     365              : 
     366              :       // Sets attribute values for instances of class 'Employee'
     367              : 
     368            0 :     setEmployeeValues(employee1, "Alexander", boost::gregorian::from_string("1972/05/12"), "Single", 3540) ;
     369            0 :     setEmployeeValues(employee2, "Michel", boost::gregorian::from_string("1963/01/28"), "Married", 4950) ;
     370            0 :     setEmployeeValues(employee3, "Maria", boost::gregorian::from_string("1951/08/18"), "Widow(er)", 4020) ;
     371              : 
     372              : 
     373              :       // Sets attribute values for instance of class 'Department'
     374              : 
     375            0 :     setDepartmentValues(department1, "IT Department"); 
     376            0 :     setDepartmentValues(department2, "EP Department"); 
     377              : 
     378              : 
     379              :       // Sets relationships
     380              : 
     381            0 :     department1->AddRelationshipValue("Staff", employee1);
     382            0 :     department1->AddRelationshipValue("Staff", employee2);
     383            0 :     department2->AddRelationshipValue("Staff", employee3);
     384            0 :     employee1->SetRelationshipValue("Works at", department1);
     385            0 :     employee2->SetRelationshipValue("Works at", department1);
     386            0 :     employee3->SetRelationshipValue("Works at", department2);
     387              : 
     388              : 
     389              :       // Print out database contents
     390              : 
     391            0 :     std::cout << "\n[OKS TUTORIAL]: Database contains the following data:\n";
     392              : 
     393            0 :     printPerson(person1);
     394            0 :     printPerson(person2);
     395            0 :     printPerson(person3);
     396            0 :     printEmployee(employee1);
     397            0 :     printEmployee(employee2);
     398            0 :     printEmployee(employee3);
     399            0 :     printDepartment(department1);
     400            0 :     printDepartment(department2);
     401              :   
     402              :   
     403              :       // Saves created data file
     404              : 
     405            0 :     std::cout << "\n[OKS TUTORIAL]: Saves created OKS data file...\n";
     406              : 
     407            0 :     kernel.save_data(data_h);
     408              : 
     409              : 
     410            0 :     std::cout << "[OKS TUTORIAL]: Done with saving created OKS data file\n";
     411              : 
     412              : 
     413              :       // **********************************************************************
     414              :       //   ***** At this moment the database has been created and saved *****
     415              :       // **********************************************************************
     416              : 
     417              : 
     418            0 :     std::cout << "\n[OKS TUTORIAL]: Start database querying tests\n\n";
     419              : 
     420              : 
     421              :       // This is a test for OksComparator and OksQuery
     422              : 
     423            0 :     {
     424            0 :       std::cout << "[QUERY]: Start simple database querying...\n";
     425              : 
     426              :         // Looking for persons were born after 01 January 1960
     427              : 
     428            0 :       boost::gregorian::date aDate(boost::gregorian::from_string("1960/01/01")); // query date
     429            0 :       OksQuery query(true, new OksComparator(PersonBirthday, new OksData(aDate), OksQuery::greater_cmp));
     430              :         
     431              : 
     432              :         // executes query
     433              : 
     434            0 :       std::cout << "[QUERY]: Looking for persons were born after " << aDate << " ...\n\n";
     435              :         
     436            0 :       OksObject::List * queryResult = Person->execute_query(&query);
     437              : 
     438              : 
     439              :         // builds iterator over results if something was found
     440              : 
     441            0 :       if(queryResult) {
     442            0 :         std::cout << "[QUERY]: Query \'" << query
     443              :                   << "\'\n  founds the following objects in class \'"
     444            0 :                   << Person->get_name() << "\' and subclasses:\n";
     445              : 
     446            0 :         for(OksObject::List::iterator i = queryResult->begin(); i != queryResult->end(); ++i) {
     447            0 :           OksObject * o = *i;
     448            0 :           OksData * d(o->GetAttributeValue("Birthday"));
     449            0 :           std::cout << "   - " << o << " was born " << *d << std::endl;
     450              :         }
     451              : 
     452              : 
     453              :           // free list: we do not need it anymore
     454              : 
     455            0 :         delete queryResult;
     456              :       }
     457              :         
     458            0 :       std::cout << "[QUERY]: Done with simple database querying\n\n";
     459            0 :     }
     460              :   
     461            0 :     {
     462            0 :       std::cout << "[QUERY]: Start database querying with logical function...\n";
     463              : 
     464              : 
     465              :           // Looking for persons were born after 01 January 1960
     466              :           // and before 01 January 1970
     467              : 
     468            0 :       boost::gregorian::date lowDate(boost::gregorian::from_string("1960/01/01"));  // low date
     469            0 :       boost::gregorian::date highDate(boost::gregorian::from_string("1970/01/01")); // high date
     470              : 
     471            0 :       OksAndExpression * andExpression = new OksAndExpression();
     472              : 
     473            0 :       andExpression->add(new OksComparator(PersonBirthday, new OksData(lowDate), OksQuery::greater_cmp));
     474            0 :       andExpression->add(new OksComparator(PersonBirthday, new OksData(highDate), OksQuery::less_cmp));
     475              : 
     476            0 :       OksQuery query(true, andExpression);
     477              : 
     478              : 
     479              :         // executes query
     480              : 
     481            0 :       std::cout << "[QUERY]: Looking for persons were born between " << lowDate
     482            0 :                 << " and " << highDate << " ...\n\n";
     483              :         
     484            0 :       OksObject::List * queryResult = Person->execute_query(&query);
     485              : 
     486              : 
     487              :         // builds iterator over results if something was found
     488              : 
     489            0 :      if(queryResult) {
     490            0 :         std::cout << "[QUERY]: Query \'" << query
     491              :                   << "\'\n  founds the following objects in class \'"
     492            0 :                   << Person->get_name() << "\' and subclasses:\n";
     493              : 
     494            0 :         for(OksObject::List::iterator i = queryResult->begin(); i != queryResult->end(); ++i) {
     495            0 :           OksObject * o = *i;
     496            0 :           OksData * d(o->GetAttributeValue("Birthday"));
     497            0 :           std::cout << "   - " << o << " was born " << *d << std::endl;
     498              :         }
     499              : 
     500              : 
     501              :           // free list: we do not need it anymore
     502              : 
     503            0 :         delete queryResult;
     504              :       }
     505              : 
     506            0 :       std::cout << "[QUERY]: Done database querying with logical function\n\n";
     507              : 
     508            0 :     }
     509              :   
     510            0 :     {
     511              : 
     512            0 :       std::cout << "[QUERY]: Start database querying with relationship expression...\n";
     513              : 
     514              : 
     515              :         // Looking for employee were born after 01 January 1971
     516              :         // and which works at IT Department
     517              : 
     518            0 :       boost::gregorian::date aDate(boost::gregorian::from_string("1971/01/01"));  // a date
     519            0 :       const char * departmentName = "IT Department"; 
     520              : 
     521            0 :       OksAndExpression * andExpression = new OksAndExpression();
     522              :   
     523            0 :       andExpression->add(new OksComparator(PersonBirthday, new OksData(aDate), OksQuery::greater_cmp));
     524            0 :       andExpression->add(new OksRelationshipExpression(WorksAt, new OksComparator(DepartmentName, new OksData(departmentName), OksQuery::equal_cmp)));
     525              :                 
     526            0 :       OksQuery query(true, andExpression);
     527              : 
     528              : 
     529              :         // executes query
     530              : 
     531            0 :       std::cout << "[QUERY]: Looking for employee were born after " << aDate
     532            0 :                 << " and works at department " << departmentName << " ...\n\n";
     533              : 
     534            0 :       OksObject::List * queryResult = Employee->execute_query(&query);
     535              : 
     536              : 
     537              :         // builds iterator over results if something was found
     538              : 
     539            0 :      if(queryResult) {
     540            0 :         std::cout << "[QUERY]: Query \'" << query
     541              :                   << "\'\n  founds the following objects in class \'"
     542            0 :                   << Employee->get_name() << "\' and subclasses:\n";
     543              : 
     544            0 :         for(OksObject::List::iterator i = queryResult->begin(); i != queryResult->end(); ++i) {
     545            0 :           OksObject * o = *i;
     546            0 :           OksData * d(o->GetAttributeValue("Birthday"));
     547            0 :           std::cout << "   - " << o << " was born " << *d << std::endl;
     548              :         }
     549              : 
     550              : 
     551              :           // free list: we do not need it anymore
     552              : 
     553            0 :         delete queryResult;
     554              :       }
     555              :   
     556            0 :       std::cout << "[QUERY]: Done database querying with relationship expression...\n";
     557            0 :     }
     558              : 
     559            0 :     std::cout << "\n[OKS TUTORIAL]: Done with database querying tests\n\n";
     560              : 
     561              :       // It is not necessary to free data or schema because all instances of OKS
     562              :       // classes are automatic C++ objects and they will deleted before last
     563              :       // close bracket `}`.
     564              : 
     565              :   }
     566            0 :   catch (const std::exception & ex) {
     567            0 :     std::cerr << "Caught exception:\n" << ex.what() << std::endl;
     568            0 :   }
     569              : 
     570              :     // returns success
     571              : 
     572            0 :   return 0;
     573            0 : }
        

Generated by: LCOV version 2.0-1