66 static std::set<OksRCR*, std::less<OksRCR*>> rcr_set;
73 for (std::list<OksRCR*>::const_iterator i = rcr_list->begin(); i != rcr_list->end(); ++i) {
80 if (!rcr_set.empty() && rcr_set.find(rcr) != rcr_set.end()) {
82 std::cout <<
" The composite parent(s) of " << rcr->
obj
83 <<
" were reported in this loop (circular references)\n";
92 std::cout <<
" " << o <<
" has no composite parents\n";
105 <<
" [-a] [-r] [-p] [-all] [-h] [-v] [-c class [-o object_id]] "
106 "[-s schema_file(s)] -d1 data_file1 -d2 data_file2\n"
108 " Options (if two objects differed):\n"
109 "\t-a produce a listing of differences for object's attributes\n"
110 "\t-r produce a listing of differences for object's relationships\n"
111 "\t-p produce a listing of object's composite parents\n"
112 "\t-all the same as \'-a -r -p\'\n"
114 " General Options/Arguments:\n"
115 "\t-c class-name optional name of class which objects to be checked\n"
116 "\t-o object-id optional id to check only this object (only used with -c)\n"
117 "\t-s schema-file optional list of schema files\n"
118 "\t-d1 data-file first compared datafile\n"
119 "\t-d2 data-file second compared datafile\n"
120 "\t-v print version\n"
121 "\t-b verbose mode\n"
122 "\t-h print this text\n"
133 <<
" [--attributes] [--relationships] [--composite-parents] [--all] [--help] [--version]"
134 " [--class-name name_of_class [--object-id id_of_object]]\n"
135 " [--schema-files schema_file(s)] --data-file1 data_file1 --data-file2 data_file2\n"
137 " Options (if two objects differed):\n"
138 "\t--attributes produce a listing of differences for object's attributes\n"
139 "\t--relationships produce a listing of differences for object's relationships\n"
140 "\t--composite-parents produce a listing of object's composite parents\n"
141 "\t-all the same as \'--attributes --relationships --composite-parents\'\n"
143 " General Options/Arguments:\n"
144 "\t--class-name class-name optional name of class which objects to be checked\n"
145 "\t--object-id object-id optional id to check only this object (only used with --class-name)\n"
146 "\t--schema-files schema-file optional list of schema files\n"
147 "\t--data-file1 data-file first compared datafile\n"
148 "\t--data-file2 data-file second compared datafile\n"
149 "\t--version print version\n"
150 "\t--verbose verbose mode\n"
151 "\t--help print this text\n"
156main(
int argc,
const char* argv[])
158 appTitle =
"OKS data files comparer. OKS kernel version ";
161 bool printAttributeDifferences =
false;
162 bool printRelationshipDifferences =
false;
163 bool printCompositeParentsMode =
false;
164 bool verboseMode =
false;
166 const char* appName =
"oks_diff_data";
175 const char** schemaFiles =
new const char*[argc];
178 const char* dataFile1 = 0;
179 const char* dataFile2 = 0;
181 const char* class_name = 0;
182 const char* object_id = 0;
184 for (
int i = 1; i < argc; i++) {
185 if (!strcmp(argv[i],
"-a") || !strcmp(argv[i],
"--attributes"))
186 printAttributeDifferences =
true;
187 else if (!strcmp(argv[i],
"-r") || !strcmp(argv[i],
"--relationships"))
188 printRelationshipDifferences =
true;
189 else if (!strcmp(argv[i],
"-p") || !strcmp(argv[i],
"--composite-parents"))
190 printCompositeParentsMode =
true;
191 else if (!strcmp(argv[i],
"-all") || !strcmp(argv[i],
"--all")) {
192 printAttributeDifferences =
true;
193 printRelationshipDifferences =
true;
194 printCompositeParentsMode =
true;
195 }
else if (!strcmp(argv[i],
"-b") || !strcmp(argv[i],
"--verbose"))
197 else if (!strcmp(argv[i],
"-h")) {
200 }
else if (!strcmp(argv[i],
"--help")) {
203 }
else if (!strcmp(argv[i],
"-v") || !strcmp(argv[i],
"--version")) {
206 }
else if (!strcmp(argv[i],
"-s") || !strcmp(argv[i],
"--schema-files")) {
207 for (
int j = 0; j < argc - i - 1; ++j) {
208 if (argv[i + 1 + j][0] !=
'-')
209 schemaFiles[j] = argv[i + 1 + j];
216 }
else if (!strcmp(argv[i],
"-c") || !strcmp(argv[i],
"--class-name")) {
217 if (argv[i + 1][0] !=
'-')
218 class_name = argv[++i];
219 }
else if (!strcmp(argv[i],
"-o") || !strcmp(argv[i],
"--object-id")) {
220 if (argv[i + 1][0] !=
'-')
221 object_id = argv[++i];
222 }
else if (!strcmp(argv[i],
"-d1") || !strcmp(argv[i],
"--data-file1")) {
223 if (argv[i + 1][0] !=
'-')
224 dataFile1 = argv[++i];
225 }
else if (!strcmp(argv[i],
"-d2") || !strcmp(argv[i],
"--data-file2")) {
226 if (argv[i + 1][0] !=
'-')
227 dataFile2 = argv[++i];
229 std::cerr <<
"ERROR: Unknown parameter: \"" << argv[i] <<
"\"\n\n";
237 if (dataFile1 == 0) {
238 std::cerr <<
"ERROR: First data file is not defined.\n\n";
243 if (dataFile2 == 0) {
244 std::cerr <<
"ERROR: Second data file is not defined.\n\n";
251 if (object_id && !class_name) {
252 std::cerr <<
"ERROR: object ID cannot be used without class name.\n\n";
257 int return_status = 0;
271 for (
int i = 0; schemaFiles[i] != 0; ++i) {
272 const char* s_file = schemaFiles[i];
282 OksClass::Map::const_iterator class_iterator = classes.begin();
284 if (classes.empty()) {
285 std::cerr <<
"ERROR: No classes were found in loaded schema file(s), exiting ...\n";
289 std::cout << std::endl;
294 for (; class_iterator != classes.end(); ++class_iterator) {
295 c1 = class_iterator->second;
296 std::string className(c1->
get_name());
298 if (class_name && className != class_name) {
306 std::cout <<
"TESTING IN CLASS \"" << className <<
"\"... ";
312 std::cout << std::endl;
316 << dataFile2 <<
"\' does not have class \"" << className <<
"\", skip testing ...\n";
322 std::cout << std::endl;
326 << className <<
"\" is different in \"" << dataFile1 <<
"\" and \"" << dataFile2
327 <<
"\", skip testing ...\n";
333 OksObject::Map::const_iterator object_iterator = objects1->begin();
335 for (; object_iterator != objects1->end(); ++object_iterator) {
336 const std::string* objUID = (*object_iterator).first;
337 OksObject* o1 = (*object_iterator).second;
339 if (object_id && o1->
GetId() != object_id) {
347 std::cout << std::endl;
350 " There is no object "
351 << o1 <<
" in the \"" << dataFile2 <<
"\" database file.\n";
359 std::cout << std::endl;
360 std::cout <<
" DIFFERENCE " << ++
classDiffsCount <<
". The OBJECTS " << o1 <<
" differed:\n";
362 int objDiffsCount = 0;
368 for (std::list<OksAttribute*>::const_iterator ai = alist->begin(); ai != alist->end(); ++ai) {
376 if (printAttributeDifferences) {
378 <<
"\" values differed:\n"
379 " the value in the FILE \""
380 << dataFile1 <<
"\" is: " << *d1
382 " the value in the FILE \""
383 << dataFile2 <<
"\" is: " << *d2 << std::endl;
390 for (std::list<OksRelationship*>::const_iterator ri = rlist->begin(); ri != rlist->end(); ++ri) {
398 if (printRelationshipDifferences) {
399 std::cout <<
" " <<
classDiffsCount <<
'.' << objDiffsCount <<
" The RELATIONSHIP \"" << r->get_name()
400 <<
"\" values differed:\n"
401 " the value in the FILE \""
402 << dataFile1 <<
"\" is: " << *d1
404 " the value in the FILE \""
405 << dataFile2 <<
"\" is: " << *d2 << std::endl;
411 if (objDiffsCount && printCompositeParentsMode) {
412 std::cout <<
" COMPOSITE PARENT(S) of the OBJECTS " << o1 <<
":\n";
413 std::cout <<
" In the FILE \"" << dataFile1 <<
"\"\n";
415 std::cout <<
" In the FILE \"" << dataFile2 <<
"\"\n";
420 object_iterator = objects2->begin();
422 for (; object_iterator != objects2->end(); ++object_iterator) {
423 const std::string* objUID = (*object_iterator).first;
426 if (!o1 && (!object_id || *objUID == object_id)) {
428 std::cout << std::endl;
431 " There is no object "
432 << (*object_iterator).second <<
" in the \"" << dataFile1 <<
"\" database file.\n";
437 std::cout <<
" no differences were found\n";
443 std::cerr <<
"Caught oks exception:\n" << ex << std::endl;
447 catch (std::exception& e) {
448 std::cerr <<
"Caught standard C++ exception: " << e.what() << std::endl;
453 std::cerr <<
"Caught unknown exception" << std::endl;
457 delete[] schemaFiles;
460 std::cout <<
"\nExiting " << appName <<
"...\n";
462 return return_status;
const std::string & get_name() const noexcept
out stream operator
const OksObject::Map * objects() const noexcept
const std::list< OksAttribute * > * all_attributes() const noexcept
const std::string & get_name() const noexcept
OksObject * get_object(const std::string &id) const noexcept
Get object by ID.
std::map< const char *, OksClass *, SortStr > Map
const std::list< OksRelationship * > * all_relationships() const noexcept
Provides interface to the OKS kernel.
OksFile * load_data(const std::string &name, bool bind=true)
Load OKS data file.
const OksClass::Map & classes() const
Get classes.
void set_silence_mode(const bool b)
Set status of silence mode. To switch 'On'/'Off' use the method's parameter:
static const char * GetVersion()
Get OKS version. The method returns string containing CVS tag and date of OKS build.
OksClass * find_class(const std::string &class_name) const
Find class by name (C++ string).
OksFile * load_schema(const std::string &name, const OksFile *parent=0)
Load OKS schema file.
OksObject describes instance of OksClass.
const std::list< OksRCR * > * reverse_composite_rels() const
Return information about composite parents. The method returns list of the OKS object's reverse compo...
OksData * GetRelationshipValue(const std::string &) const
Get value of relationship by name.
std::unordered_map< const std::string *, OksObject *, oks::hash_str, oks::equal_str > Map
const std::string & GetId() const
OksData * GetAttributeValue(const std::string &name) const
Get value of attribute by name.
const std::string & get_name() const noexcept
int main(int argc, char *argv[])
static void printUsage(const char *appName, std::ostream &s)
static void ReportCompositeParents(OksObject *o, int recursionLevel=-1)
static void printShortUsage(const char *appName, std::ostream &s)
static void printRecursion(int level)
The struct OksRCR describes Reverse Composite Relationship (i.e. back reference from child to composi...
const OksRelationship * relationship