DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
oks_tutorial.cxx
Go to the documentation of this file.
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
38using namespace dunedaq;
39using namespace dunedaq::oks;
40
41 //
42 // This function sets attribute values of class 'Person'
43 //
44
45void
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 OksData d; // creates OKS data with unknown type
54
55 d.Set(name); // sets OKS data to string 'name'
56 o->SetAttributeValue("Name", &d);
57
58 d.Set(birthday); // sets OKS data to date 'birthday'
59 o->SetAttributeValue("Birthday", &d);
60
61 d.Set(familySituation); // sets OKS data to 'familySituation'
62 d.type = OksData::enum_type; // sets OKS data type to enumeration
63 o->SetAttributeValue("Family_Situation", &d);
64}
65
66
67 //
68 // This function prints an instance of class 'Person'
69 //
70
71void
73 const OksObject *o // OKS object describing person
74)
75{
76 OksData * name(o->GetAttributeValue("Name")); // is used to store 'Name'
77 OksData * birthday(o->GetAttributeValue("Birthday")); // is used to store 'Birthday'
78 OksData * family(o->GetAttributeValue("Family_Situation")); // is used to store 'Family_Situation'
79
80 std::cout << "Object " << o << " \n"
81 " Name: " << *name << " \n"
82 " Birthday: \'" << *birthday << "\" \n"
83 " Family_Situation: " << *family << std::endl;
84}
85
86
87 //
88 // This function sets attribute values of class 'Employee'
89 //
90
91void
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 setPersonValues(o, name, birthday, familySituation);
104
105 OksData d(salary); // creates OKS data with ulong 'salary'
106 o->SetAttributeValue("Salary", &d);
107}
108
109
110 //
111 // This function prints an instance of class 'Employee'
112 //
113
114void
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 printPerson(o);
123
124 OksData *department(o->GetRelationshipValue("Works at")), // is used to store 'Works at'
125 *salary(o->GetAttributeValue("Salary")); // is used to store 'salary'
126
127 std::cout << " Salary: " << *salary << " \n"
128 " Works at: \"" << department->data.OBJECT->GetId() << "\"\n";
129}
130
131
132 //
133 // This function sets attribute values of class 'Department'
134 //
135
136void
138 OksObject *o, // OKS object that describes department
139 const char *name // new department name
140)
141{
142 OksData d(name); // creates OKS data with string 'name'
143
144 o->SetAttributeValue("Name", &d);
145}
146
147
148 //
149 // This function prints an instance of class 'Department'
150 //
151
152void
154 const OksObject *o // OKS object that describes department
155)
156{
157 OksData *name(o->GetAttributeValue("Name")), // is used to store 'Staff'
158 *staff(o->GetRelationshipValue("Staff")); // is used to store 'Name'
159
160 std::cout << "Object " << o << "\n"
161 " Name: " << *name << " \n"
162 " Staff: \"" << *staff << "\"\n";
163}
164
165
166int
167main(int argc, char **argv)
168{
169 const char * schema_file = "/tmp/tutorial.oks"; // default schema file
170 const char * data_file = "/tmp/tutorial.okd"; // default data file
171
172 if(
173 argc > 1 &&
174 (
175 !strcmp(argv[1], "--help") ||
176 !strcmp(argv[1], "-help") ||
177 !strcmp(argv[1], "--h") ||
178 !strcmp(argv[1], "-h")
179 )
180 ) {
181 std::cout << "Usage: " << argv[0] << " [new_schema new_data]\n";
182 return 0;
183 }
184
185 if(argc == 3) {
186 schema_file = argv[1];
187 data_file = argv[2];
188 }
189
190
191 // Creates OKS kernel
192
193 std::cout << "[OKS TUTORIAL]: Creating OKS kernel...\n";
194
195 OksKernel kernel(false, false, false, false);
196
197 std::cout << "[OKS TUTORIAL]: Done creating OKS kernel\n\n";
198
199
200 try {
201
202
203 // Creates new schema file and tests return status
204
205 std::cout << "[OKS TUTORIAL]: Creating new schema file...\n";
206
207 OksFile * schema_h = kernel.new_schema(schema_file);
208
209 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..N **************\n\n";
214
215
216 // Creates class Person with three attributes "Name", "Birthday" and "Family_Situation"
217
218 OksClass * Person = new OksClass(
219 "Person",
220 "It is a class to describe a person",
221 false,
222 &kernel
223 );
224
225 Person->add(
226 new OksAttribute(
227 "Name",
229 false,
230 "",
231 "Unknown",
232 "A string to describe person name",
233 true
234 )
235 );
236
237 OksAttribute * PersonBirthday = new OksAttribute(
238 "Birthday",
240 false,
241 "",
242 "2009/01/01",
243 "A date to describe person birthday",
244 true
245 );
246
247 Person->add(PersonBirthday);
248
249 Person->add(
250 new OksAttribute(
251 "Family_Situation",
253 false,
254 "Single,Married,Widow(er)",
255 "Single",
256 "A enumeration to describe a person family state",
257 true
258 )
259 );
260
261
262 // Creates class Person with superclass Person, add "Salary" attribute and "Works at" relationship
263
264 OksClass * Employee = new OksClass(
265 "Employee",
266 "It is a class to describe an employee",
267 false,
268 &kernel
269 );
270
271 OksAttribute * EmployeeSalary = new OksAttribute(
272 "Salary",
274 false,
275 "",
276 "1000",
277 "An integer to describe employee salary",
278 false
279 );
280
281 OksRelationship * WorksAt = new OksRelationship(
282 "Works at",
283 "Department",
286 false,
287 false,
288 false,
289 "A employee works at one and only one department"
290 );
291
292 Employee->add_super_class("Person");
293 Employee->add(EmployeeSalary);
294 Employee->add(WorksAt);
295
296
297 // Creates class Department with one attribute and one relationship
298
299 OksClass * Department = new OksClass(
300 "Department",
301 "It is a class to describe a department",
302 false,
303 &kernel
304 );
305
306 OksAttribute * DepartmentName = new OksAttribute(
307 "Name",
309 false,
310 "",
311 "Unknown",
312 "A string to describe department name",
313 true
314 );
315
316 OksRelationship *DepartmentStaff = new OksRelationship(
317 "Staff",
318 "Employee",
321 true,
322 true,
323 true,
324 "A department has zero or many employess"
325 );
326
327 Department->add(DepartmentName);
328 Department->add(DepartmentStaff);
329
330
331 // Saves created schema file
332
333 std::cout << "[OKS TUTORIAL]: Saves created OKS schema file...\n";
334
335 kernel.save_schema(schema_h);
336
337
338 // Creates new data file and tests return status
339
340 std::cout << "[OKS TUTORIAL]: Creating new data file...\n";
341
342 OksFile * data_h = kernel.new_data(data_file, "OKS TUTORIAL DATA FILE");
343
344 data_h->add_include_file(schema_file);
345
346
347 // Creates instances of the classes
348
349 OksObject * person1 = new OksObject(Person, "peter");
350 OksObject * person2 = new OksObject(Person, "mick");
351 OksObject * person3 = new OksObject(Person, "baby");
352 OksObject * employee1 = new OksObject(Employee, "alexander");
353 OksObject * employee2 = new OksObject(Employee, "michel");
354 OksObject * employee3 = new OksObject(Employee, "maria");
355 OksObject * department1 = new OksObject(Department, "IT");
356 OksObject * department2 = new OksObject(Department, "EP");
357
358
359 // Sets attribute values for instances of class 'Person'
360
361 setPersonValues(person1, "Peter", boost::gregorian::from_string("1960/02/01"), "Married");
362 setPersonValues(person2, "Mick", boost::gregorian::from_string("1956-09-01"), "Single");
363 setPersonValues(person3, "Julia", boost::gregorian::from_string("2000-May-25"), "Single");
364
365
366 // Sets attribute values for instances of class 'Employee'
367
368 setEmployeeValues(employee1, "Alexander", boost::gregorian::from_string("1972/05/12"), "Single", 3540) ;
369 setEmployeeValues(employee2, "Michel", boost::gregorian::from_string("1963/01/28"), "Married", 4950) ;
370 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 setDepartmentValues(department1, "IT Department");
376 setDepartmentValues(department2, "EP Department");
377
378
379 // Sets relationships
380
381 department1->AddRelationshipValue("Staff", employee1);
382 department1->AddRelationshipValue("Staff", employee2);
383 department2->AddRelationshipValue("Staff", employee3);
384 employee1->SetRelationshipValue("Works at", department1);
385 employee2->SetRelationshipValue("Works at", department1);
386 employee3->SetRelationshipValue("Works at", department2);
387
388
389 // Print out database contents
390
391 std::cout << "\n[OKS TUTORIAL]: Database contains the following data:\n";
392
393 printPerson(person1);
394 printPerson(person2);
395 printPerson(person3);
396 printEmployee(employee1);
397 printEmployee(employee2);
398 printEmployee(employee3);
399 printDepartment(department1);
400 printDepartment(department2);
401
402
403 // Saves created data file
404
405 std::cout << "\n[OKS TUTORIAL]: Saves created OKS data file...\n";
406
407 kernel.save_data(data_h);
408
409
410 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 std::cout << "\n[OKS TUTORIAL]: Start database querying tests\n\n";
419
420
421 // This is a test for OksComparator and OksQuery
422
423 {
424 std::cout << "[QUERY]: Start simple database querying...\n";
425
426 // Looking for persons were born after 01 January 1960
427
428 boost::gregorian::date aDate(boost::gregorian::from_string("1960/01/01")); // query date
429 OksQuery query(true, new OksComparator(PersonBirthday, new OksData(aDate), OksQuery::greater_cmp));
430
431
432 // executes query
433
434 std::cout << "[QUERY]: Looking for persons were born after " << aDate << " ...\n\n";
435
436 OksObject::List * queryResult = Person->execute_query(&query);
437
438
439 // builds iterator over results if something was found
440
441 if(queryResult) {
442 std::cout << "[QUERY]: Query \'" << query
443 << "\'\n founds the following objects in class \'"
444 << Person->get_name() << "\' and subclasses:\n";
445
446 for(OksObject::List::iterator i = queryResult->begin(); i != queryResult->end(); ++i) {
447 OksObject * o = *i;
448 OksData * d(o->GetAttributeValue("Birthday"));
449 std::cout << " - " << o << " was born " << *d << std::endl;
450 }
451
452
453 // free list: we do not need it anymore
454
455 delete queryResult;
456 }
457
458 std::cout << "[QUERY]: Done with simple database querying\n\n";
459 }
460
461 {
462 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 boost::gregorian::date lowDate(boost::gregorian::from_string("1960/01/01")); // low date
469 boost::gregorian::date highDate(boost::gregorian::from_string("1970/01/01")); // high date
470
471 OksAndExpression * andExpression = new OksAndExpression();
472
473 andExpression->add(new OksComparator(PersonBirthday, new OksData(lowDate), OksQuery::greater_cmp));
474 andExpression->add(new OksComparator(PersonBirthday, new OksData(highDate), OksQuery::less_cmp));
475
476 OksQuery query(true, andExpression);
477
478
479 // executes query
480
481 std::cout << "[QUERY]: Looking for persons were born between " << lowDate
482 << " and " << highDate << " ...\n\n";
483
484 OksObject::List * queryResult = Person->execute_query(&query);
485
486
487 // builds iterator over results if something was found
488
489 if(queryResult) {
490 std::cout << "[QUERY]: Query \'" << query
491 << "\'\n founds the following objects in class \'"
492 << Person->get_name() << "\' and subclasses:\n";
493
494 for(OksObject::List::iterator i = queryResult->begin(); i != queryResult->end(); ++i) {
495 OksObject * o = *i;
496 OksData * d(o->GetAttributeValue("Birthday"));
497 std::cout << " - " << o << " was born " << *d << std::endl;
498 }
499
500
501 // free list: we do not need it anymore
502
503 delete queryResult;
504 }
505
506 std::cout << "[QUERY]: Done database querying with logical function\n\n";
507
508 }
509
510 {
511
512 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 boost::gregorian::date aDate(boost::gregorian::from_string("1971/01/01")); // a date
519 const char * departmentName = "IT Department";
520
521 OksAndExpression * andExpression = new OksAndExpression();
522
523 andExpression->add(new OksComparator(PersonBirthday, new OksData(aDate), OksQuery::greater_cmp));
524 andExpression->add(new OksRelationshipExpression(WorksAt, new OksComparator(DepartmentName, new OksData(departmentName), OksQuery::equal_cmp)));
525
526 OksQuery query(true, andExpression);
527
528
529 // executes query
530
531 std::cout << "[QUERY]: Looking for employee were born after " << aDate
532 << " and works at department " << departmentName << " ...\n\n";
533
534 OksObject::List * queryResult = Employee->execute_query(&query);
535
536
537 // builds iterator over results if something was found
538
539 if(queryResult) {
540 std::cout << "[QUERY]: Query \'" << query
541 << "\'\n founds the following objects in class \'"
542 << Employee->get_name() << "\' and subclasses:\n";
543
544 for(OksObject::List::iterator i = queryResult->begin(); i != queryResult->end(); ++i) {
545 OksObject * o = *i;
546 OksData * d(o->GetAttributeValue("Birthday"));
547 std::cout << " - " << o << " was born " << *d << std::endl;
548 }
549
550
551 // free list: we do not need it anymore
552
553 delete queryResult;
554 }
555
556 std::cout << "[QUERY]: Done database querying with relationship expression...\n";
557 }
558
559 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 catch (const std::exception & ex) {
567 std::cerr << "Caught exception:\n" << ex.what() << std::endl;
568 }
569
570 // returns success
571
572 return 0;
573}
OKS query logical AND expression class.
Definition query.hpp:287
OKS attribute class.
static const char * u32_int_type
static const char * string_type
static const char * enum_type
static const char * date_type
The OKS class.
Definition class.hpp:205
void add_super_class(const std::string &name)
Definition class.cpp:883
void add(OksAttribute *a)
Add attribute.
Definition class.cpp:1057
const std::string & get_name() const noexcept
Definition class.hpp:368
OksObject::List * execute_query(OksQuery *query) const
Execute query.
Definition query.cpp:436
OKS query expression comparator class.
Definition query.hpp:144
Provides interface to the OKS XML schema and data files.
Definition file.hpp:345
void add_include_file(const std::string &name)
Add include file.
Definition file.cpp:1199
Provides interface to the OKS kernel.
Definition kernel.hpp:582
OksFile * new_data(const std::string &name, const std::string &logical_name="", const std::string &type="")
Create OKS data file.
Definition kernel.cpp:3723
void save_schema(OksFile *file_h, bool force=false, OksFile *true_file_h=0)
Save OKS schema file.
Definition kernel.cpp:2543
void save_data(OksFile *file_h, bool ignore_bad_objects=false, OksFile *true_file_h=nullptr, bool force_defaults=false)
Save OKS data file.
Definition kernel.cpp:3799
OksFile * new_schema(const std::string &name)
Create OKS schema file.
Definition kernel.cpp:2490
void add(OksQueryExpression *q)
Definition query.hpp:269
OksObject describes instance of OksClass.
Definition object.hpp:841
void AddRelationshipValue(const std::string &name, OksObject *object)
Add object value to multi-value relationship by name.
Definition object.cpp:2341
OksData * GetRelationshipValue(const std::string &) const
Get value of relationship by name.
Definition object.cpp:2009
std::list< OksObject * > List
Definition object.hpp:880
void SetRelationshipValue(const std::string &name, OksData *data, bool skip_non_null_check=false)
Set value of relationship by name.
Definition object.cpp:2194
void SetAttributeValue(const std::string &name, OksData *data)
Set value of attribute by name.
Definition object.cpp:1995
const std::string & GetId() const
Definition object.hpp:1000
OksData * GetAttributeValue(const std::string &name) const
Get value of attribute by name.
Definition object.cpp:1924
OKS query class.
Definition query.hpp:41
static bool equal_cmp(const OksData *, const OksData *)
Definition query.cpp:56
static bool greater_cmp(const OksData *, const OksData *)
Definition query.cpp:61
static bool less_cmp(const OksData *, const OksData *)
Definition query.cpp:60
OKS query relationship expression class.
Definition query.hpp:192
Including Qt Headers.
Definition module.cpp:16
void printEmployee(const OksObject *o)
void setPersonValues(OksObject *o, const char *name, boost::gregorian::date birthday, const char *familySituation)
void setEmployeeValues(OksObject *o, const char *name, boost::gregorian::date birthday, const char *familySituation, uint32_t salary)
int main(int argc, char **argv)
void setDepartmentValues(OksObject *o, const char *name)
void printPerson(const OksObject *o)
void printDepartment(const OksObject *o)
the structure to pass common parameters to various read() methods of OksData and OksObject class
Definition object.hpp:454
union dunedaq::oks::OksData::Data data