BmnRoot
Loading...
Searching...
No Matches
UniParser.cxx
Go to the documentation of this file.
1#include "UniParser.h"
2
3#include "ElogConnection.h"
4#include "UniConnection.h"
5#include "UniDetectorParameter.h"
6#include "UniParameter.h"
7#include "UniRun.h"
8#define ONLY_DECLARATIONS
9#include "TPRegexp.h"
10#include "TSQLResult.h"
11#include "TSQLRow.h"
12#include "TSQLServer.h"
13#include "TSQLStatement.h"
14#include "TSystem.h"
15#include "function_set.h"
16
17// XML
18#include <algorithm>
19#include <fstream>
20#include <iostream>
21#include <libxml/parser.h>
22#include <libxml/tree.h>
23#include <sstream>
24#include <string>
25using namespace std;
26
28
30
31int parse_cycle_statement(xmlNodePtr& cur_schema_node,
32 vector<structParseSchema>& vecElements,
33 int& skip_count,
34 char& delimiter_char,
35 int& column_count)
36{
37 vecElements.clear();
38
39 // define count of the elements to skip
40 skip_count = 0;
41 if ((char*)xmlGetProp(cur_schema_node, (unsigned char*)"skip") != 0)
42 skip_count = atoi((char*)xmlGetProp(cur_schema_node, (unsigned char*)"skip"));
43
44 // define delimiter char
45 delimiter_char = ';';
46 if ((char*)xmlGetProp(cur_schema_node, (unsigned char*)"delimiter") != 0) {
47 string delimiter_string = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"delimiter");
48 if (delimiter_string[0] == '\\') {
49 switch (delimiter_string[1]) {
50 case 't': {
51 delimiter_char = '\t';
52 break;
53 }
54 }
55 } else
56 delimiter_char = delimiter_string[0];
57 }
58
59 // write cycle structure to array vecElements
60 column_count = 0;
61 for (xmlNodePtr cycle_child = cur_schema_node->children; cycle_child; cycle_child = cycle_child->next) {
62 TString strAction = (char*)xmlGetProp(cycle_child, (unsigned char*)"action");
63 TString column_name = (char*)xmlGetProp(cycle_child, (unsigned char*)"column_name");
64 TString statement_type = (char*)xmlGetProp(cycle_child, (unsigned char*)"type");
65 // cout<<"The current scheme line properties:"<<endl<<"Action: "<<strAction<<endl<<"Column name:
66 // "<<column_name<<endl<<"Type: "<<statement_type<<endl<<endl;
67
68 if (strAction == "skip") {
69 structParseSchema par(true);
70
71 vecElements.push_back(par);
72 } else if (strAction == "update") {
73 structParseSchema par(false, column_name, statement_type);
74 par.isUpdate = true;
75
76 vecElements.push_back(par);
77 column_count++;
78 } // if (strAction == "update")
79 else if (strAction == "write")
80 {
81 structParseSchema par(false, column_name, statement_type);
82
83 vecElements.push_back(par);
84 column_count++;
85 } // if (strAction == "write")
86 else if (strAction == "parse")
87 {
89 par.isSkip = false;
90
91 int start_index = 0;
92 if ((char*)xmlGetProp(cycle_child, (unsigned char*)"start_index") != 0)
93 start_index = atoi((char*)xmlGetProp(cycle_child, (unsigned char*)"start_index"));
94 TString parse_type = (char*)xmlGetProp(cycle_child, (unsigned char*)"parse_type");
95 TString delimiter = (char*)xmlGetProp(cycle_child, (unsigned char*)"delimiter");
96 structParseRow row(column_name, statement_type, true, start_index, parse_type, delimiter);
97 par.vecRows.push_back(row);
98
99 vecElements.push_back(par);
100 column_count++;
101 } // if (strAction == "parse")
102 else if (strAction == "multi")
103 {
105 par.isSkip = false;
106
107 for (xmlNodePtr cycle_sub_child = cycle_child->children; cycle_sub_child;
108 cycle_sub_child = cycle_sub_child->next)
109 {
110 strAction = (char*)xmlGetProp(cycle_sub_child, (unsigned char*)"action");
111 column_name = (char*)xmlGetProp(cycle_sub_child, (unsigned char*)"column_name");
112 statement_type = (char*)xmlGetProp(cycle_sub_child, (unsigned char*)"type");
113
114 if (strAction == "write") {
115 structParseRow row(column_name, statement_type);
116 par.vecRows.push_back(row);
117 } else if (strAction == "parse") {
118 int start_index = 0;
119 if ((char*)xmlGetProp(cycle_sub_child, (unsigned char*)"start_index") != 0)
120 start_index = atoi((char*)xmlGetProp(cycle_sub_child, (unsigned char*)"start_index"));
121 TString parse_type = (char*)xmlGetProp(cycle_sub_child, (unsigned char*)"parse_type");
122 TString delimiter = (char*)xmlGetProp(cycle_sub_child, (unsigned char*)"delimiter");
123 structParseRow row(column_name, statement_type, true, start_index, parse_type, delimiter);
124 par.vecRows.push_back(row);
125 }
126 }
127
128 vecElements.push_back(par);
129 column_count++;
130 } // if (strAction == "multi")
131 } // write cycle structure to array vecElements
132
133 return 0;
134}
135
136TString prepare_sql_code(vector<structParseSchema> vecElements, TString strTableName, bool isUpdate)
137{
138 TString sql;
139 if (!isUpdate) {
140 sql = "insert into " + strTableName + "(";
141 int count = 0;
142 for (vector<structParseSchema>::iterator it = vecElements.begin(); it != vecElements.end(); ++it) {
143 structParseSchema schema = *it;
144 if (schema.isSkip)
145 continue;
146
147 for (size_t j = 0; j < schema.vecRows.size(); j++) {
148 structParseRow row = schema.vecRows[j];
149 if (count == 0)
150 sql += row.strColumnName;
151 else
152 sql += ", " + row.strColumnName;
153
154 count++;
155 }
156 }
157 sql += ") values(";
158 for (int i = 1; i <= count; i++) {
159 if (i == 1)
160 sql += TString::Format("$%d", i);
161 else
162 sql += TString::Format(", $%d", i);
163 }
164 sql += ")";
165 } else {
166 sql = "update " + strTableName + " set ";
167 int count = 0;
168 for (vector<structParseSchema>::iterator it = vecElements.begin(); it != vecElements.end(); ++it) {
169 structParseSchema schema = *it;
170 if ((schema.isSkip) || (schema.isUpdate))
171 continue;
172
173 for (size_t j = 0; j < schema.vecRows.size(); j++) {
174 structParseRow row = schema.vecRows[j];
175 if (count == 0)
176 sql += TString::Format("%s = $%d", row.strColumnName.Data(), count + 2);
177 else
178 sql += TString::Format(", %s = $%d", row.strColumnName.Data(), count + 2);
179
180 count++;
181 }
182 }
183 sql += " where ";
184 count = 0;
185 for (vector<structParseSchema>::iterator it = vecElements.begin(); it != vecElements.end(); ++it) {
186 structParseSchema schema = *it;
187 if (!schema.isUpdate)
188 continue;
189
190 for (size_t j = 0; j < schema.vecRows.size(); j++) {
191 structParseRow row = schema.vecRows[j];
192 if (count == 0)
193 sql += TString::Format("%s = $1", row.strColumnName.Data());
194 // else
195 // sql += TString::Format(", %s = $%d", row.strColumnName, count+2);
196
197 count++;
198 }
199 }
200 } // prepare SQL query for cycle
201
202 return sql;
203}
204
205int write_string_to_db(string& write_string,
206 TSQLStatement* stmt,
207 structParseSchema& schema,
208 int& count,
209 int cycle_counter)
210{
211 int tmp_count;
212
213 if (schema.isUpdate) {
214 tmp_count = count;
215 count = 0;
216 }
217
218 // cycle for schema
219 string token;
220 for (size_t i = 0; i < schema.vecRows.size(); i++) {
221 token = write_string;
222 structParseRow row = schema.vecRows[i];
223
224 unsigned char* pArray = nullptr;
225 Long_t size_array = -1;
226 if (row.isParse) {
227 if (row.iStartIndex > 0)
228 token = token.substr(row.iStartIndex, token.length() - row.iStartIndex);
229
230 if (row.strParseType != "") {
231 if (row.strParseType == "counter")
232 token = int_to_string(cycle_counter);
233 if (row.strParseType(0, 5) == "value")
234 token = row.strParseType(6, row.strParseType.Length() - 6).Data();
235
236 if (row.strParseType == "int") {
237 size_t last_digit;
238 for (last_digit = 0; last_digit < token.length(); last_digit++) {
239 if (!isdigit(token[last_digit]))
240 break;
241 }
242 last_digit++;
243
244 if (last_digit > 1)
245 token = token.substr(0, last_digit - 1);
246 else
247 token = "";
248 }
249 if (row.strParseType == "int_array") {
250 // parse token and form integer array
251 istringstream token_stream(token);
252 string subtoken;
253 vector<int> vecInt;
254 while (getline(token_stream, subtoken, row.strDelimiter[0])) {
255 int cur_int = atoi(subtoken.c_str());
256 vecInt.push_back(cur_int);
257 }
258
259 int size_int = vecInt.size();
260 int* pIntArray = new int[size_int];
261 for (int j = 0; j < size_int; j++)
262 pIntArray[j] = vecInt[j];
263 size_array = size_int * sizeof(int);
264
265 pArray = new unsigned char[size_array];
266 memcpy(pArray, pIntArray, size_array);
267 delete[] pIntArray;
268 vecInt.clear();
269 }
270 if (row.strParseType == "double_array") {
271 // parse token and form double array
272 token = trim(token);
273 istringstream token_stream(token);
274 string subtoken;
275 vector<double> vecDouble;
276 while (getline(token_stream, subtoken, row.strDelimiter[0])) {
277 double cur_double = atof(subtoken.c_str());
278 // cout<<". CurDouble: "<<cur_double;
279 vecDouble.push_back(cur_double);
280 }
281 // cout<<endl;
282
283 int size_double = vecDouble.size();
284 double* pDoubleArray = new double[size_double];
285 for (int j = 0; j < size_double; j++)
286 pDoubleArray[j] = vecDouble[j];
287 size_array = size_double * sizeof(double);
288
289 pArray = new unsigned char[size_array];
290 memcpy(pArray, pDoubleArray, size_array);
291 delete[] pDoubleArray;
292 vecDouble.clear();
293 }
294 }
295 } // if row.isParse
296
297 if (row.strStatementType == "int") {
298 stmt->SetInt(count, atoi(token.c_str()));
299 cout << "SetInt: " << token << endl;
300 count++;
301 } else {
302 if (row.strStatementType == "hex") {
303
304 stmt->SetInt(count, hex_string_to_int(token.c_str()));
305 cout << "SetHex: " << token << endl;
306 count++;
307 } else {
308 if (row.strStatementType == "double") {
309 // replace ',' by '.' if present
310 replace_string_in_text(token, ",", ".");
311
312 stmt->SetDouble(count, atof(token.c_str()));
313 cout << "SetDouble: " << token << endl;
314 count++;
315 } else {
316 if (row.strStatementType == "string") {
317 stmt->SetString(count, token.c_str());
318 cout << "SetString: " << token << endl;
319 count++;
320 } else {
321 if (row.strStatementType == "datetime") {
322 TDatime d(token.c_str());
323 stmt->SetDatime(count, d);
324 cout << "SetDatime: " << token << endl;
325 count++;
326 } else {
327 if (row.strStatementType == "binary") {
328 cout << "SetBinary: " << (void*)pArray << " with size: " << size_array << endl;
329 stmt->SetLargeObject(count, (void*)pArray, size_array);
330 count++;
331 delete[] pArray;
332 } // "binary"
333 } // "datetime"
334 } // "string"
335 } // "double"
336 } // "hex"
337 } // "int"
338 } // // cycle by schema rows because it can consist multiple writing
339
340 if (schema.isUpdate)
341 count = tmp_count;
342
343 return 0;
344}
345
346// recursive search for a node in XML document from root node by given node name
347xmlNodePtr findNodeByName(xmlNodePtr rootnode, const char* nodename)
348{
349 xmlNodePtr node = rootnode;
350 if (node == nullptr) {
351 cout << "XML document is empty!" << endl;
352 return nullptr;
353 }
354
355 while (node != nullptr) {
356 if (node->type != XML_ELEMENT_NODE) {
357 node = node->next;
358 continue;
359 }
360
361 if ((node->name != nullptr) && (strcmp((char*)node->name, nodename) == 0))
362 return node;
363 else {
364 if (node->children != nullptr) {
365 xmlNodePtr intNode = findNodeByName(node->children, nodename);
366 if (intNode != nullptr)
367 return intNode;
368 }
369 }
370
371 node = node->next;
372 }
373
374 return nullptr;
375}
376
377int UniParser::ParseXml2Db(TString xmlName, TString schemaPath, bool isUpdate)
378{
379 // pointer to XML document
380 xmlDocPtr docXML = xmlReadFile(xmlName, nullptr, 0);
381 if (!docXML) {
382 cout << "ERROR: reading XML file '" << xmlName << "' was failed" << endl;
383 return -1;
384 }
385
386 // read schema
387 xmlDocPtr docSchema = xmlReadFile(schemaPath, nullptr, 0);
388 if (!docSchema) {
389 cout << "ERROR: reading schema file '" << schemaPath << "' was failed" << endl;
390 xmlFreeDoc(docXML);
391 return -2;
392 }
393
394 xmlNodePtr cur_xml_node = xmlDocGetRootElement(docXML);
395 xmlNodePtr cur_schema_node = xmlDocGetRootElement(docSchema);
396 if (!cur_schema_node) {
397 cout << "ERROR: schema of XML parsing is empty" << endl;
398 xmlFreeDoc(docXML);
399 xmlFreeDoc(docSchema);
400 return -4;
401 }
402 if (strcmp((char*)cur_schema_node->name, "uniparser") != 0) {
403 cout << "ERROR: it is not 'uniparser' scheme: " << (char*)cur_schema_node->name << endl;
404 xmlFreeDoc(docXML);
405 xmlFreeDoc(docSchema);
406 return -5;
407 }
408 cur_schema_node = cur_schema_node->children;
409
410 // open connection to database
412 if (connDb == nullptr) {
413 xmlFreeDoc(docXML);
414 xmlFreeDoc(docSchema);
415 return -3;
416 }
417 TSQLServer* db_server = connDb->GetSQLServer();
418
419 string strTableName = "";
420 // parse SCHEMA file
421 while (cur_schema_node) {
422 // cout<<"Current schema node: "<<(char*)cur_schema_node->name<<endl;
423
424 // parse table name if exists
425 if ((char*)xmlGetProp(cur_schema_node, (unsigned char*)"table_name") != 0) {
426 strTableName = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"table_name");
427 cout << "Current database table: " << strTableName << endl;
428 }
429
430 if (strcmp((char*)cur_schema_node->name, "search") == 0) {
431 string strSearchName = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"name");
432 // search for XML node with given name and move cursor to the new position
433 cur_xml_node = findNodeByName(cur_xml_node, strSearchName.c_str());
434 if (cur_xml_node == nullptr) {
435 cout << "ERROR: end of the XML document was reached while parsing (search for)" << endl;
436 delete connDb;
437 xmlFreeDoc(docXML);
438 xmlFreeDoc(docSchema);
439 return -8;
440 }
441
442 cout << "Current node after search: " << (char*)cur_xml_node->name << endl;
443 } else if (strcmp((char*)cur_schema_node->name, "move") == 0) {
444 xmlAttr* attribute = cur_schema_node->properties;
445 while (attribute && attribute->name && attribute->children) {
446 if (strcmp((char*)attribute->name, "down") == 0) {
447 xmlChar* value = xmlNodeListGetString(cur_schema_node->doc, attribute->children, 1);
448
449 int count = atoi((char*)value);
450 for (int i = 0; i < count; i++) {
451 cur_xml_node = cur_xml_node->children;
452 if (cur_xml_node->type != XML_ELEMENT_NODE)
453 cur_xml_node = cur_xml_node->next;
454
455 if (cur_xml_node == nullptr) {
456 cout << "ERROR: end of the XML document was reached while parsing (move - down)" << endl;
457 xmlFree(value);
458 delete connDb;
459 xmlFreeDoc(docXML);
460 xmlFreeDoc(docSchema);
461 return -6;
462 }
463 }
464
465 xmlFree(value);
466 } // if attribute name is "down"
467
468 attribute = attribute->next;
469 }
470
471 cout << "Current node after move: " << (char*)cur_xml_node->name << endl;
472 }
473 // PARSE CYCLE
474 else if (strcmp((char*)cur_schema_node->name, "cycle") == 0)
475 {
476 TString strChildName = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"child");
477
478 // parse CYCLE attributes to vector of Elements
479 int skip_count, column_count;
480 char delimiter_char;
481 vector<structParseSchema> vecElements;
482 parse_cycle_statement(cur_schema_node, vecElements, skip_count, delimiter_char, column_count);
483
484 // prepare SQL query for TXT cycle
485 if (column_count == 0) {
486 cout << "ERROR: no columns were chosen for insert or update" << endl;
487 delete connDb;
488 xmlFreeDoc(docXML);
489 xmlFreeDoc(docSchema);
490 return -7;
491 }
492 TString sql = prepare_sql_code(vecElements, strTableName, isUpdate);
493 cout << "SQL code: " << sql << endl;
494
495 TSQLStatement* stmt = db_server->Statement(sql);
496
497 // run XML file cycle and write the fields to DB
498 int cycle_counter = 0;
499 for (cur_xml_node = cur_xml_node->children; cur_xml_node; cur_xml_node = cur_xml_node->next) {
500 if (strcmp((char*)cur_xml_node->name, strChildName.Data()))
501 continue;
502
503 if (skip_count > 0) {
504 skip_count--;
505 continue;
506 }
507
508 stmt->NextIteration();
509 cycle_counter++;
510
511 int count;
512 if (!isUpdate)
513 count = 0;
514 else
515 count = 1;
516
517 int i = 0;
518 // cycle for XML child elements
519 cout << "Cur node: " << cur_xml_node->name << endl;
520 for (xmlNodePtr cycle_child = cur_xml_node->children; cycle_child; cycle_child = cycle_child->next, i++)
521 {
522 cout << "cycle_child node: " << cycle_child->name << endl;
523 structParseSchema schema = vecElements[i];
524 if (schema.isSkip)
525 continue;
526
527 TString xml_child_value = (char*)cycle_child->children->content;
528 string token = xml_child_value.Data();
529
530 write_string_to_db(token, stmt, schema, count, cycle_counter);
531 } // cycle for XML child elements
532 } // run XML file cycle and write the fields to DB
533
534 stmt->Process();
535 delete stmt;
536 } // CYCLE PROCESSING
537
538 cur_schema_node = cur_schema_node->next;
539 } // for docSchema level 0
540
541 delete connDb;
542 xmlFreeDoc(docXML);
543 xmlFreeDoc(docSchema);
544
545 return 0;
546}
547
548int UniParser::ParseCsv2Db(TString csvName, TString schemaPath, bool isUpdate)
549{
550 ifstream csvFile;
551 csvFile.open(csvName, ios::in);
552 if (!csvFile.is_open()) {
553 cout << "ERROR: reading CSV file '" << csvName << "' was failed" << endl;
554 return -1;
555 }
556
557 // read schema
558 xmlDocPtr docSchema = xmlReadFile(schemaPath, nullptr, 0);
559 if (!docSchema) {
560 cout << "ERROR: reading schema file '" << schemaPath << "' was failed" << endl;
561 return -2;
562 }
563
564 xmlNodePtr cur_schema_node = xmlDocGetRootElement(docSchema);
565 if (!cur_schema_node) {
566 cout << "ERROR: schema of XML parsing is empty" << endl;
567 xmlFreeDoc(docSchema);
568 return -4;
569 }
570 if (strcmp((char*)cur_schema_node->name, "uniparser") != 0) {
571 cout << "ERROR: it is not 'uniparser' scheme: " << (char*)cur_schema_node->name << endl;
572 xmlFreeDoc(docSchema);
573 return -5;
574 }
575 cur_schema_node = cur_schema_node->children;
576
577 // open connection to database
579 if (connDb == nullptr)
580 return -3;
581 TSQLServer* db_server = connDb->GetSQLServer();
582
583 // parse SCHEMA file
584 string strTableName = "", cur_line;
585 while (cur_schema_node) {
586 // cout<<"Current schema node: "<<cur_schema_node->name<<endl;
587
588 // parse table name if exists
589 if ((char*)xmlGetProp(cur_schema_node, (unsigned char*)"table_name") != 0) {
590 strTableName = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"table_name");
591 cout << "Current database table: " << strTableName << endl;
592 }
593
594 if (strcmp((char*)cur_schema_node->name, "search") == 0) {
595 string strSearchName = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"name");
596 }
597 // PARSE CYCLE
598 else if (strcmp((char*)cur_schema_node->name, "cycle") == 0)
599 {
600 int skip_count, column_count;
601 char delimiter_char;
602 vector<structParseSchema> vecElements;
603
604 // parse CYCLE attributes to vector of Elements
605 parse_cycle_statement(cur_schema_node, vecElements, skip_count, delimiter_char, column_count);
606
607 // prepare SQL query for TXT cycle
608 TString sql = prepare_sql_code(vecElements, strTableName, isUpdate);
609 cout << "SQL code: " << sql << endl;
610
611 for (int i = 0; i < skip_count; i++)
612 getline(csvFile, cur_line);
613
614 TSQLStatement* stmt = db_server->Statement(sql);
615
616 // run CSV file cycle and write the fields to DB
617 int cycle_counter = 0;
618 while (getline(csvFile, cur_line)) {
619 if (cur_line == "")
620 continue;
621
622 // parse current line
623 string trim_line = trim(cur_line);
624
625 istringstream line_stream(trim_line);
626
627 stmt->NextIteration();
628 cycle_counter++;
629
630 // parse tokens by symbol separated
631 int count;
632 if (!isUpdate)
633 count = 0;
634 else
635 count = 1;
636
637 int i = 0;
638 string token;
639 while (getline(line_stream, token, ';')) {
640 structParseSchema schema = vecElements[i];
641 if (schema.isSkip) {
642 i++;
643 continue;
644 }
645
646 write_string_to_db(token, stmt, schema, count, cycle_counter);
647
648 i++;
649 } // parse CSV line by tokens separated by symbols
650 } // run CSV file cycle and write the fields to DB
651
652 stmt->Process();
653 delete stmt;
654 } // CYCLE PROCESSING
655
656 cur_schema_node = cur_schema_node->next;
657 } // for docSchema level 0
658
659 delete connDb;
660 csvFile.close();
661 xmlFreeDoc(docSchema);
662
663 return 0;
664}
665
666int UniParser::ParseTxt2Db(TString txtName, TString schemaPath, bool isUpdate)
667{
668 ifstream txtFile;
669 txtFile.open(txtName, ios::in);
670 if (!txtFile.is_open()) {
671 cout << "ERROR: reading TXT file '" << txtName << "' was failed" << endl;
672 return -1;
673 }
674
675 // read schema
676 xmlDocPtr docSchema = xmlReadFile(schemaPath, nullptr, 0);
677 if (!docSchema) {
678 cout << "ERROR: reading schema file '" << schemaPath << "' was failed" << endl;
679 return -2;
680 }
681
682 xmlNodePtr cur_schema_node = xmlDocGetRootElement(docSchema);
683 if (!cur_schema_node) {
684 cout << "ERROR: schema of XML parsing is empty" << endl;
685 xmlFreeDoc(docSchema);
686 return -4;
687 }
688 if (strcmp((char*)cur_schema_node->name, "uniparser") != 0) {
689 cout << "ERROR: it is not 'uniparser' scheme: " << (char*)cur_schema_node->name << endl;
690 xmlFreeDoc(docSchema);
691 return -5;
692 }
693 cur_schema_node = cur_schema_node->children;
694
695 // open connection to database
697 if (connDb == nullptr)
698 return -3;
699
700 TSQLServer* db_server = connDb->GetSQLServer();
701
702 // parse SCHEMA file
703 string strTableName = "", cur_line;
704 while (cur_schema_node) {
705 cout << "Current schema node: " << cur_schema_node->name << endl;
706
707 // parse table name if exists
708 if ((char*)xmlGetProp(cur_schema_node, (unsigned char*)"table_name") != 0) {
709 strTableName = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"table_name");
710 cout << "Current database table: " << strTableName << endl;
711 }
712
713 if (strcmp((char*)cur_schema_node->name, "skip") == 0) {
714 int skip_line_count = 0;
715 string strLineCount = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"line_count");
716 if (strLineCount != "")
717 skip_line_count = atoi(strLineCount.c_str());
718
719 for (int i = 0; i < skip_line_count; i++)
720 getline(txtFile, cur_line);
721 }
722
723 if (strcmp((char*)cur_schema_node->name, "search") == 0) {
724 string strSearchName = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"name");
725 }
726 // PARSE CYCLE
727 else if (strcmp((char*)cur_schema_node->name, "cycle") == 0)
728 {
729 int skip_count, column_count;
730 char delimiter_char;
731 vector<structParseSchema> vecElements;
732
733 // parse CYCLE attributes to vector of Elements
734 parse_cycle_statement(cur_schema_node, vecElements, skip_count, delimiter_char, column_count);
735
736 // prepare SQL query for TXT cycle
737 TString sql = prepare_sql_code(vecElements, strTableName, isUpdate);
738 cout << "SQL code: " << sql << endl;
739
740 for (int i = 0; i < skip_count; i++)
741 getline(txtFile, cur_line);
742
743 TSQLStatement* stmt = db_server->Statement(sql);
744
745 // run TXT file cycle and write the fields to DB
746 int cycle_counter = 0;
747 while (getline(txtFile, cur_line)) {
748 string trim_line = trim(cur_line);
749
750 if (trim_line == "")
751 continue;
752
753 // parse current line
754 istringstream line_stream(cur_line);
755
756 stmt->NextIteration();
757 cycle_counter++;
758
759 // parse tokens by symbol separated
760 int count;
761 if (!isUpdate)
762 count = 0;
763 else
764 count = 1;
765
766 int i = 0;
767 string token;
768 while (getline(line_stream, token, delimiter_char)) {
769 structParseSchema schema = vecElements[i];
770 if (schema.isSkip) {
771 i++;
772 continue;
773 }
774
775 write_string_to_db(token, stmt, schema, count, cycle_counter);
776
777 i++;
778 } // parse TXT line by tokens separated by symbols
779
780 cout << endl;
781 } // run TXT file cycle and write the fields to DB
782
783 stmt->Process();
784 delete stmt;
785 } // CYCLE PROCESSING
786
787 cur_schema_node = cur_schema_node->next;
788 } // parse SCHEMA file
789
790 delete connDb;
791 txtFile.close();
792 xmlFreeDoc(docSchema);
793
794 return 0;
795}
796
797int UniParser::ParseTxtNoise2Db(int period_number, TString txtName, TString schemaPath)
798{
799 ifstream txtFile;
800 txtFile.open(txtName, ios::in);
801 if (!txtFile.is_open()) {
802 cout << "ERROR: reading TXT file '" << txtName << "' was failed" << endl;
803 return -1;
804 }
805
806 // read schema
807 xmlDocPtr docSchema = xmlReadFile(schemaPath, nullptr, 0);
808 if (!docSchema) {
809 cout << "ERROR: reading schema file '" << schemaPath << "' was failed" << endl;
810 return -2;
811 }
812
813 xmlNodePtr cur_schema_node = xmlDocGetRootElement(docSchema);
814 if (!cur_schema_node) {
815 cout << "ERROR: schema of XML parsing is empty" << endl;
816 xmlFreeDoc(docSchema);
817 return -4;
818 }
819 if (strcmp((char*)cur_schema_node->name, "UniParser_schema") != 0) {
820 cout << "ERROR: it is not a UniParser schema" << endl;
821 xmlFreeDoc(docSchema);
822 return -5;
823 }
824 cur_schema_node = cur_schema_node->children;
825
826 // open connection to database
828 if (connDb == nullptr)
829 return -3;
830
831 // parse SCHEMA file
832 string strTableName = "";
833 int skip_line_count = 0;
834 while (cur_schema_node) {
835 // parse table name if exists
836 if ((char*)xmlGetProp(cur_schema_node, (unsigned char*)"table_name") != 0) {
837 strTableName = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"table_name");
838 cout << "Current database table: " << strTableName << endl;
839 }
840
841 if (strcmp((char*)cur_schema_node->name, "skip") == 0) {
842 string strLineCount = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"line_count");
843 if (strLineCount != "")
844 skip_line_count = atoi(strLineCount.c_str());
845 }
846
847 cur_schema_node = cur_schema_node->next;
848 }
849
850 string cur_line;
851 for (int i = 0; i < skip_line_count; i++)
852 getline(txtFile, cur_line);
853
854 while (getline(txtFile, cur_line)) {
855 // parse run and row count
856 string reduce_line = reduce(cur_line);
857
858 cout << "Current run and count line: " << reduce_line << endl;
859 int run_number = -1, row_count = -1;
860 istringstream line_stream(reduce_line);
861 int num = 1;
862 string token;
863 // parse tokens by space separated
864 while (getline(line_stream, token, ' ')) {
865 if (num == 1)
866 run_number = atoi(token.c_str());
867 if (num == 2)
868 row_count = atoi(token.c_str());
869
870 num++;
871 }
872
873 // parse slots and channels
874 vector<UniValue*> arr;
875 for (int i = 0; i < row_count; i++) {
876 getline(txtFile, cur_line);
877 cout << "Current run: " << run_number << ", row: " << i << ", line: " << cur_line << endl;
878 reduce_line = reduce(cur_line);
879
880 line_stream.str(reduce_line);
881 num = 1;
882 int slot_number;
883 // parse tokens by space separated
884 while (getline(line_stream, token, ' ')) {
885 if (num == 1)
886 slot_number = atoi(token.c_str());
887
888 if (num > 1) {
889 size_t index_sym = token.find_first_of('-');
890 if (index_sym == string::npos) {
891 int channel_number = atoi(token.c_str());
892 if (channel_number == 0) {
893 if (!is_string_number(token))
894 continue;
895 }
896
897 IIValue* st = new IIValue;
898 st->value1 = slot_number;
899 st->value2 = channel_number;
900 arr.push_back(st);
901 } else {
902 string strFirst = token.substr(0, index_sym);
903 string strSecond = token.substr(index_sym + 1, token.length() - index_sym - 1);
904 int num_first = atoi(strFirst.c_str());
905 int num_second = atoi(strSecond.c_str());
906 for (int j = num_first; j <= num_second; j++) {
907 IIValue* st = new IIValue;
908 st->value1 = slot_number;
909 st->value2 = j;
910 arr.push_back(st);
911 }
912 }
913 }
914
915 num++;
916 } // parse tokens by space separated
917 } // for (int i = 0; i < row_count; i++)
918
919 // skip empty line
920 if (getline(txtFile, cur_line)) {
921 reduce_line = trim(cur_line, " \t\r");
922 if (reduce_line != "") {
923 cout << "CRITICAL ERROR: file format is not correct, current line:" << reduce_line << endl;
924 txtFile.close();
925 return -4;
926 }
927 }
928
929 /*
930 // print array
931 cout<<"Slot:Channel"<<endl;
932 for (int i = 0; i < arr.size(); i++)
933 {
934 IIValue* pValue = (IIValue*)arr[i];
935 cout<<pValues->value1<<":"<<pValues->value2<<endl;
936 }
937 cout<<endl;
938 */
939
941 "DCH1", "noise", period_number, run_number, period_number, run_number,
942 arr); //(detector_name, parameter_name, start_run, end_run, parameter_value)
943 if (pDetectorParameter == nullptr)
944 continue;
945
946 // clean memory after work
947 for (size_t i = 0; i < arr.size(); i++)
948 delete arr[i];
949 if (pDetectorParameter)
950 delete pDetectorParameter;
951 }
952
953 txtFile.close();
954 delete connDb;
955
956 return 0;
957}
958
960{
961 TSQLServer* source_db = TSQLServer::Connect("pgsql://nc13.jinr.ru/bmn_elog", "login", "password");
962 if (source_db == nullptr) {
963 cout << "ERROR: source database connection was not established (nc13.jinr.ru) for bmn_elog" << endl;
964 return -1;
965 }
966
967 TString sql_source = TString::Format("select record_id, field_comment "
968 "from record_");
969 TSQLStatement* stmt_source = source_db->Statement(sql_source);
970 // cout<<"SQL code: "<<sql<<endl;
971
972 // get record from the database
973 if (!stmt_source->Process()) {
974 cout << "ERROR: getting records from the database has been failed" << endl;
975
976 delete stmt_source;
977 delete source_db;
978
979 return -2;
980 }
981
982 // store result of statement in buffer
983 stmt_source->StoreResult();
984
985 TSQLServer* dest_db = TSQLServer::Connect("pgsql://nc13.jinr.ru/bmn_elog", "login", "password");
986 if (dest_db == nullptr) {
987 cout << "ERROR: destination database connection was not established (nc13.jinr.ru) for bmn_elog" << endl;
988 return -3;
989 }
990
991 // extract rows one after another
992 while (stmt_source->NextResultRow()) {
993 if (stmt_source->IsNull(1))
994 continue;
995
996 int record_id = stmt_source->GetInt(0);
997 TString field_comment = stmt_source->GetString(1);
998
999 // search for SP-57 and VKM2 magnetic field in A
1000 size_t beg_pos, end_pos;
1001 string field_lower(field_comment.Data()), sp57 = "", vkm2 = "";
1002 int iField = -1;
1003 transform(field_lower.begin(), field_lower.end(), field_lower.begin(), ::tolower);
1004
1005 size_t ind = field_lower.find("sp-57");
1006 if (ind != string::npos) {
1007 beg_pos = ind + 5;
1008 sp57 = find_first_number(field_lower, beg_pos, end_pos, false);
1009 iField = atoi(sp57.c_str());
1010
1011 if (field_lower[end_pos + 1] != 'a') {
1012 cout << "ERROR: field is not ended with A" << field_lower << endl;
1013 continue;
1014 }
1015
1016 TString sql_dest = TString::Format("update record_ "
1017 "set sp_57 = $1 "
1018 "where record_id = $2");
1019 TSQLStatement* stmt_dest = dest_db->Statement(sql_dest);
1020
1021 stmt_dest->NextIteration();
1022 stmt_dest->SetInt(0, iField);
1023 stmt_dest->SetInt(1, record_id);
1024
1025 // write new value to the database
1026 if (!stmt_dest->Process()) {
1027 cout << "ERROR: updating information has been failed" << endl;
1028
1029 delete stmt_dest;
1030 continue;
1031 }
1032
1033 ind = end_pos;
1034 delete stmt_dest;
1035 } else
1036 ind = 0;
1037
1038 ind = field_lower.find("vkm2", ind);
1039 if (ind != string::npos) {
1040 beg_pos = ind + 4;
1041 vkm2 = find_first_number(field_lower, beg_pos, end_pos, false);
1042 iField = atoi(vkm2.c_str());
1043
1044 if (field_lower[end_pos + 1] != 'a') {
1045 cout << "ERROR: field is not ended with A" << field_lower << endl;
1046 continue;
1047 }
1048
1049 TString sql_dest = TString::Format("update record_ "
1050 "set vkm2 = $1 "
1051 "where record_id = $2");
1052 TSQLStatement* stmt_dest = dest_db->Statement(sql_dest);
1053
1054 stmt_dest->NextIteration();
1055 stmt_dest->SetInt(0, iField);
1056 stmt_dest->SetInt(1, record_id);
1057
1058 // write new value to the database
1059 if (!stmt_dest->Process()) {
1060 cout << "ERROR: updating information has been failed" << endl;
1061
1062 delete stmt_dest;
1063 continue;
1064 }
1065
1066 delete stmt_dest;
1067 }
1068 }
1069
1070 delete stmt_source;
1071 delete source_db;
1072 delete dest_db;
1073
1074 return 0;
1075}
1076
1077// parse text file to the C++ structure
1078int UniParser::ParseTxt2Struct(TString txtName,
1079 TString schemaPath,
1080 vector<structParseValue*>& parse_values,
1081 vector<structParseSchema>& vecElements,
1082 int iVerbose)
1083{
1084 gSystem->ExpandPathName(txtName);
1085 gSystem->ExpandPathName(schemaPath);
1086
1087 ifstream txtFile;
1088 txtFile.open(txtName.Data(), ios::in);
1089 if (!txtFile.is_open()) {
1090 if (iVerbose > 0)
1091 cout << "ERROR: reading TXT file '" << txtName << "' was failed" << endl;
1092 return -1;
1093 }
1094
1095 // read schema
1096 xmlDocPtr docSchema = xmlReadFile(schemaPath.Data(), nullptr, 0);
1097 if (!docSchema) {
1098 if (iVerbose > 0)
1099 cout << "ERROR: reading schema file '" << schemaPath << "' was failed" << endl;
1100 return -2;
1101 }
1102
1103 xmlNodePtr cur_schema_node = xmlDocGetRootElement(docSchema);
1104 if (!cur_schema_node) {
1105 if (iVerbose > 0)
1106 cout << "ERROR: schema of XML parsing is empty" << endl;
1107 xmlFreeDoc(docSchema);
1108 return -3;
1109 }
1110 if (strcmp((char*)cur_schema_node->name, "uniparser") != 0) {
1111 if (iVerbose > 0)
1112 cout << "ERROR: it is not 'uniparser' scheme: " << (char*)cur_schema_node->name << endl;
1113 xmlFreeDoc(docSchema);
1114 return -4;
1115 }
1116 cur_schema_node = cur_schema_node->children;
1117
1118 // parse SCHEMA file
1119 string strTableName = "", cur_line;
1120 TDatime dtSpillPrevious;
1121 while (cur_schema_node) {
1122 if (iVerbose > 1)
1123 cout << "Current schema node: " << cur_schema_node->name << endl;
1124
1125 // parse table name if exists
1126 if ((char*)xmlGetProp(cur_schema_node, (unsigned char*)"table_name") != 0) {
1127 strTableName = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"table_name");
1128 if (iVerbose > 0)
1129 cout << "Current database table: " << strTableName << endl;
1130 }
1131
1132 if (strcmp((char*)cur_schema_node->name, "skip") == 0) {
1133 int skip_line_count = 0;
1134 string strLineCount = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"line_count");
1135 if (strLineCount != "")
1136 skip_line_count = atoi(strLineCount.c_str());
1137
1138 for (int i = 0; i < skip_line_count; i++)
1139 getline(txtFile, cur_line);
1140 }
1141
1142 if (strcmp((char*)cur_schema_node->name, "search") == 0) {
1143 string strSearchName = (char*)xmlGetProp(cur_schema_node, (unsigned char*)"name");
1144 }
1145 // PARSE CYCLE
1146 else if (strcmp((char*)cur_schema_node->name, "cycle") == 0)
1147 {
1148 int skip_count, column_count;
1149 char delimiter_char;
1150 // parse CYCLE attributes to vector of Elements
1151 parse_cycle_statement(cur_schema_node, vecElements, skip_count, delimiter_char, column_count);
1152
1153 for (int i = 0; i < skip_count; i++)
1154 getline(txtFile, cur_line);
1155
1156 // run TXT file cycle and make the action
1157 int cycle_counter = 0;
1158 bool notFirstLine = false, isSkipLines = false;
1159 while (getline(txtFile, cur_line)) {
1160 // string trim_line = trim(cur_line);
1161 string reduce_line = reduce(cur_line);
1162 if (iVerbose > 1)
1163 cout << "Current line: " << reduce_line << endl;
1164
1165 if (reduce_line == "")
1166 continue;
1167
1168 // parse current line
1169 istringstream line_stream(reduce_line);
1170 cycle_counter++;
1171
1172 // parse tokens by symbol separated
1173 TString strDate = "", strTime = "", strSpillEnd = "";
1174 string token;
1175 size_t i = 0;
1177 while (getline(line_stream, token, delimiter_char)) {
1178 if (i >= vecElements.size()) {
1179 if (iVerbose > 0)
1180 cout << "WARNING: Some columns were not parsed (starting with " << token << ")" << endl;
1181 break;
1182 }
1183 structParseSchema schema = vecElements[i];
1184 if (schema.isSkip) {
1185 i++;
1186 if (iVerbose > 1)
1187 cout << "schema.isSkip: " << schema.isSkip << endl;
1188 continue;
1189 }
1190
1191 if (iVerbose > 1)
1192 cout << "The current type of the column '" << schema.vecRows[0].strColumnName
1193 << "': " << schema.vecRows[0].strStatementType << endl;
1194 // parse columns
1195 if (schema.vecRows[0].strStatementType == "datetime") {
1196 strDate = token.c_str();
1197 TPRegexp date_prefix("^[0-9][0-9]?[.][0-9][0-9]?[.][0-9][0-9][0-9]?[0-9]?");
1198 if (!strDate.Contains(date_prefix)) {
1199 TString strSQLDate = dtSpillPrevious.AsSQLString();
1200 strDate = TString::Format("%s.%s.%s", strSQLDate(8, 2).Data(), strSQLDate(5, 2).Data(),
1201 strSQLDate(0, 4).Data());
1202 if (iVerbose > 0)
1203 cout << "WARNING: recovery date: " << strDate << endl;
1204 } else
1205 getline(line_stream, token, delimiter_char);
1206
1207 strTime = token.c_str();
1208 TPRegexp time_prefix("^[0-9][0-9]?[:][0-9][0-9]?[:][0-9][0-9]?");
1209 if (!strTime.Contains(time_prefix)) {
1210 strTime = "00:00:00";
1211 } else
1212 getline(line_stream, token, delimiter_char);
1213
1214 i++;
1215 schema = vecElements[i];
1216 if (schema.isSkip) {
1217 i++;
1218 continue;
1219 }
1220 }
1221
1222 if (schema.vecRows[0].strStatementType == "int") {
1223 st->arrValues.push_back(atoi(token.c_str()));
1224 } else {
1225 if (schema.vecRows[0].strStatementType == "double") {
1226 st->arrValues.push_back(atof(token.c_str()));
1227 } else {
1228 if (iVerbose > 0)
1229 cout << "ERROR: type of the column is not supported: "
1230 << schema.vecRows[0].strStatementType << endl;
1231 return -5;
1232 }
1233 }
1234
1235 i++;
1236 } // parse TXT line by tokens separated by symbols
1237
1238 strSpillEnd = TString::Format("%s %s", strDate.Data(), strTime.Data());
1239 tm tmbuf[1] = {{0}};
1240 strptime(strSpillEnd.Data(), "%d.%m.%Y %H:%M:%S", tmbuf);
1241 TDatime dtSpillEnd(tmbuf->tm_year, tmbuf->tm_mon + 1, tmbuf->tm_mday, tmbuf->tm_hour, tmbuf->tm_min,
1242 tmbuf->tm_sec);
1243 st->dtSpillEnd = dtSpillEnd;
1244 if ((notFirstLine) && (dtSpillPrevious > dtSpillEnd)) {
1245 if ((!isSkipLines) && (iVerbose > 0))
1246 cout << endl
1247 << "ERROR: The time sequence of the lines is corrupted. The following lines is skipped:"
1248 << endl;
1249 cout << reduce_line << endl;
1250 isSkipLines = true;
1251 delete st;
1252 continue;
1253 } else {
1254 if (isSkipLines) {
1255 if (iVerbose > 0)
1256 cout << "Skipped fragment is finished" << endl << endl;
1257 isSkipLines = false;
1258 }
1259 }
1260 dtSpillPrevious = dtSpillEnd;
1261 notFirstLine = true;
1262
1263 // if (iVerbose > 1) cout<<"Spill End: "<<st->dtSpillEnd.AsSQLString()<<". Beam DAQ: "<<st->beam_daq<<".
1264 // Beam All: "<<st->beam_all<<". Trigger DAQ: "<<st->trigger_daq<<". Trigger All:
1265 // "<<st->trigger_all<<endl;
1266 parse_values.push_back(st);
1267
1268 if (iVerbose > 1)
1269 cout << endl;
1270 } // run TXT file cycle and write the fields to the structure
1271 } // CYCLE PROCESSING
1272
1273 cur_schema_node = cur_schema_node->next;
1274 } // (while) parse SCHEMA file
1275
1276 txtFile.close();
1277 xmlFreeDoc(docSchema);
1278
1279 return 0;
1280}
1281
1282bool check_element(const string& str, size_t pos, string element)
1283{
1284 size_t str_length = str.length(), element_length = element.length();
1285 if ((pos + element_length) > str_length)
1286 return false;
1287
1288 for (size_t i = 1; i < element_length; i++) {
1289 if (str[pos + i] != element[i])
1290 return false;
1291 }
1292
1293 if (((pos == 0) || (str[pos - 1] == ' ') || (str[pos - 1] == ',') || (str[pos - 1] == '.') || (str[pos - 1] == ')'))
1294 && ((pos == (str_length - element_length)) || (str[pos + element_length] == ' ')
1295 || (str[pos + element_length] == ',') || (str[pos + element_length] == '.')
1296 || (str[pos + element_length] == '(')))
1297 {
1298 return true;
1299 }
1300
1301 return false;
1302}
1303
1304// convert datetime string "Day DD Mon YYYY HH:MM:SS +ZZZZ" to TDatime without zone, e.g. "Fri 20 Feb 2015 12:03:41
1305// +0300"
1306TDatime stringToDatime(string str_time)
1307{
1308 tm tmbuf[1] = {{0}};
1309
1310 // tm tmbuf;
1311 // sscanf(str_time.Data(), "%2d.%2d.%4d %2d:%2d:%2d", &tmbuf.tm_mday, &tmbuf.tm_mon, &tmbuf.tm_year, &tmbuf.tm_hour,
1312 // &tmbuf.tm_min, &tmbuf.tm_sec); str>>get_time(&tmbuf, "%a %d %b %Y %H:%M:%S +");
1313 strptime(str_time.c_str(), "%a %d %b %Y %H:%M:%S %z", tmbuf);
1314 TDatime ttime(tmbuf->tm_year, tmbuf->tm_mon + 1, tmbuf->tm_mday, tmbuf->tm_hour, tmbuf->tm_min, tmbuf->tm_sec);
1315
1316 return ttime;
1317}
1318
1319// specific functions for experiments (BM@N)
1320int UniParser::ConvertElogCsv(TString csvName, char separate_symbol)
1321{
1322 ifstream csvFile;
1323 csvFile.open(csvName, ios::in);
1324 if (!csvFile.is_open()) {
1325 cout << "ERROR: reading CSV file '" << csvName << "' was failed" << endl;
1326 return -1;
1327 }
1328
1330 if (connDb == nullptr)
1331 return -1;
1332 TSQLServer* elog_server = connDb->GetSQLServer();
1333 if (elog_server == nullptr) {
1334 cout << "ERROR: ELOG connection was not established" << endl;
1335 return -2;
1336 }
1337 // cout<<"Server info: "<<pSQLServer->ServerInfo()<<endl;
1338 TSQLStatement* stmt = nullptr;
1339
1340 // run and parse CSV file, and update the fields in DB
1341 int skip_line = 1, updated_count = 0;
1342 string cur_line;
1343 while (getline(csvFile, cur_line)) {
1344 if (cur_line == "")
1345 continue;
1346 if (skip_line > 0) {
1347 skip_line--;
1348 continue;
1349 }
1350
1351 // parse current line
1352 string trim_line = trim(cur_line);
1353 istringstream line_stream(trim_line);
1354
1355 // parse tokens by symbol separated
1356 string token, record_id = "", record_date = "", author = "", record_type = "", subject = "", run_number = "",
1357 shift_leader = "", trigger_info = "", daq_status = "", magnet_field = "", beam = "",
1358 record_comment = "";
1359 int index = 0, iError = 0;
1360 while (getline(line_stream, token, separate_symbol)) {
1361 switch (index) {
1362 case 0:
1363 record_id = token;
1364 break;
1365 case 1:
1366 record_date = token;
1367 break;
1368 case 2:
1369 author = trim(token, "\"");
1370 break;
1371 case 3:
1372 record_type = trim(token, "\"");
1373 break;
1374 case 4:
1375 break;
1376 case 5:
1377 subject = trim(token, "\"");
1378 break;
1379 case 6:
1380 run_number = trim(token, "\"");
1381 break;
1382 case 7:
1383 shift_leader = trim(token, "\"");
1384 break;
1385 case 8:
1386 trigger_info = trim(token, "\"");
1387 break;
1388 case 9:
1389 daq_status = trim(token, "\"");
1390 break;
1391 case 10:
1392 magnet_field = trim(token, "\"");
1393 break;
1394 case 11:
1395 beam = trim(token, "\"");
1396 break;
1397 case 12:
1398 record_comment = trim(token, "\"");
1399 break;
1400 default: {
1401 cout << "ERROR: more tokens separated by '" << separate_symbol << "' for record_id: " << record_id
1402 << endl;
1403 iError = 2;
1404 break;
1405 }
1406 }
1407 index++;
1408 } // parse tokens by symbol separated
1409 if (iError != 0)
1410 continue;
1411
1412 int iRecordId = -1, iAuthor = -1, iRecordType = -1, iRunNumber = -1, iLastRunNumber = -1, iShiftLeader = -1,
1413 iTriggerInfo = -1;
1414 // RECORD ID
1415 if (!is_string_number(record_id)) {
1416 cout << "ERROR: record id is not number: " << record_id << endl;
1417 continue;
1418 }
1419 iRecordId = atoi(record_id.c_str());
1420 if (iRecordId < 1) {
1421 cout << "ERROR: record id should be greater zero: " << iRecordId << endl;
1422 continue;
1423 }
1424
1425 cout << "RECORD ID: " << iRecordId << endl;
1426
1427 // RECORD DATE
1428 if (record_date == "") {
1429 cout << "ERROR: record date is empty: " << record_date << endl;
1430 continue;
1431 }
1432 TDatime dtRecordDate = stringToDatime(record_date);
1433
1434 // AUTHOR
1435 TString strAuthorLower = author;
1436 strAuthorLower.ToLower();
1437 if ((strAuthorLower == "shift") || (strAuthorLower == "none"))
1438 author = "";
1439 if (author != "") {
1440 TString sql_author = TString::Format("select person_id "
1441 "from person_ "
1442 "where position(lower(person_name) in lower('%s')) > 0",
1443 author.c_str());
1444 stmt = elog_server->Statement(sql_author);
1445
1446 if (!stmt->Process()) {
1447 cout << "ERROR: getting author from the database has been failed: " << author << endl;
1448 delete stmt;
1449 continue;
1450 }
1451
1452 // store result of statement in buffer
1453 stmt->StoreResult();
1454
1455 // extract row
1456 if (!stmt->NextResultRow()) {
1457 cout << "ERROR: author was not found in the database: " << author << endl;
1458 delete stmt;
1459 continue;
1460 }
1461
1462 iAuthor = stmt->GetInt(0);
1463 delete stmt;
1464 }
1465
1466 // TYPE
1467 string subject_lower = subject, type_lower = record_type;
1468 transform(subject_lower.begin(), subject_lower.end(), subject_lower.begin(), ::tolower);
1469 transform(type_lower.begin(), type_lower.end(), type_lower.begin(), ::tolower);
1470
1471 size_t ind;
1472 if (type_lower == "other") {
1473 ind = subject_lower.find("new run");
1474 if (ind != string::npos) {
1475 type_lower = "new run";
1476 if (subject_lower.length() == 7)
1477 subject = "";
1478 }
1479 }
1480 TString sql_type = TString::Format("select type_id "
1481 "from type_ "
1482 "where lower(type_text) = lower('%s')",
1483 type_lower.c_str());
1484 stmt = elog_server->Statement(sql_type);
1485
1486 if (!stmt->Process()) {
1487 cout << "ERROR: getting type from the database has been failed: " << record_type << endl;
1488 delete stmt;
1489 continue;
1490 }
1491
1492 // store result of statement in buffer
1493 stmt->StoreResult();
1494
1495 // extract row
1496 if (!stmt->NextResultRow()) {
1497 cout << "ERROR: type was not found in the database: " << record_type << endl;
1498 delete stmt;
1499 continue;
1500 }
1501
1502 iRecordType = stmt->GetInt(0);
1503 delete stmt;
1504
1505 // RUN NUMBER
1506 string strRunNumber = run_number, strLastRunNumber = "";
1507 transform(strRunNumber.begin(), strRunNumber.end(), strRunNumber.begin(), ::tolower);
1508 if (strRunNumber == "none")
1509 strRunNumber = "";
1510
1511 if (strRunNumber != "") {
1512 if (strRunNumber.substr(0, 3) == "run")
1513 strRunNumber = strRunNumber.substr(3);
1514 ind = strRunNumber.find_first_of('-');
1515 if (ind != string::npos) {
1516 strLastRunNumber = strRunNumber.substr(ind + 1);
1517 if (!is_string_number(strLastRunNumber)) {
1518 cout << "ERROR: last run number is not number: " << run_number << endl;
1519 continue;
1520 }
1521 iLastRunNumber = atoi(strLastRunNumber.c_str());
1522 if (iLastRunNumber < 1) {
1523 cout << "ERROR: last run number should be greater than zero: " << iLastRunNumber << endl;
1524 continue;
1525 }
1526 strRunNumber = strRunNumber.substr(0, ind);
1527 }
1528
1529 if (!is_string_number(strRunNumber)) {
1530 cout << "ERROR: run number is not number: " << run_number << endl;
1531 continue;
1532 }
1533 iRunNumber = atoi(strRunNumber.c_str());
1534 if (iRunNumber < 1) {
1535 cout << "ERROR: run number should be greater than zero: " << iRunNumber << endl;
1536 continue;
1537 }
1538
1539 if ((iLastRunNumber > 0) && (iLastRunNumber <= iRunNumber)) {
1540 cout << "ERROR: last run number (" << iLastRunNumber << ") should be greater than first run number ("
1541 << iRunNumber << ")." << endl;
1542 continue;
1543 }
1544 }
1545
1546 // SHIFT_LEADER
1547 TString strLeaderLower = shift_leader;
1548 strLeaderLower.ToLower();
1549 if ((strLeaderLower == "shift") || (strLeaderLower == "none"))
1550 shift_leader = "";
1551 if (shift_leader != "") {
1552 TString sql_leader = TString::Format("select person_id "
1553 "from person_ "
1554 "where position(lower(person_name) in lower('%s')) > 0",
1555 shift_leader.c_str());
1556 stmt = elog_server->Statement(sql_leader);
1557
1558 if (!stmt->Process()) {
1559 cout << "ERROR: getting shift leader from the database has been failed: " << shift_leader << endl;
1560 delete stmt;
1561 continue;
1562 }
1563
1564 // store result of statement in buffer
1565 stmt->StoreResult();
1566
1567 // extract row
1568 if (!stmt->NextResultRow()) {
1569 cout << "ERROR: shift leader was not found in the database: " << shift_leader << endl;
1570 delete stmt;
1571 continue;
1572 }
1573
1574 iShiftLeader = stmt->GetInt(0);
1575 delete stmt;
1576 }
1577
1578 // TRIGGER
1579 TString strTriggerLower = trigger_info;
1580 strTriggerLower.ToLower();
1581 if (strTriggerLower == "none")
1582 trigger_info = "";
1583 if (trigger_info != "") {
1584 TString sql_trigger = TString::Format("select trigger_id "
1585 "from trigger_ "
1586 "where lower(trigger_info) = lower('%s')",
1587 trigger_info.c_str());
1588 stmt = elog_server->Statement(sql_trigger);
1589
1590 if (!stmt->Process()) {
1591 cout << "ERROR: getting trigger from the database has been failed: " << trigger_info << endl;
1592 delete stmt;
1593 continue;
1594 }
1595
1596 // store result of statement in buffer
1597 stmt->StoreResult();
1598
1599 // extract row
1600 if (!stmt->NextResultRow()) {
1601 cout << "ERROR: trigger was not found in the database: " << trigger_info << endl;
1602 delete stmt;
1603 continue;
1604 }
1605
1606 iTriggerInfo = stmt->GetInt(0);
1607 delete stmt;
1608 }
1609
1610 // MAGNET FIELD
1611 // search for SP-41, SP-57, VKM2 and magnetic field in mvolt
1612 size_t beg_pos, end_pos;
1613 string field_lower = magnet_field, sp41 = "", sp57 = "", vkm2 = "", field_mv = "";
1614 int iSP41 = -1, iVKM2 = -1;
1615 double dVoltage = -1;
1616 transform(field_lower.begin(), field_lower.end(), field_lower.begin(), ::tolower);
1617 // replace sp41 by sp-41 and sp57 by sp-57
1618 replace_string_in_text(field_lower, "sp41", "sp-41");
1619 replace_string_in_text(field_lower, "sp57", "sp-57");
1620 ind = field_lower.find("sp-41");
1621 if (ind != string::npos) {
1622 beg_pos = ind + 5;
1623 sp41 = find_first_number(field_lower, beg_pos, end_pos);
1624 } else {
1625 beg_pos = 0;
1626 sp41 = find_first_number(field_lower, beg_pos, end_pos);
1627 }
1628 if (sp41 != "") {
1629 iSP41 = atoi(sp41.c_str());
1630 if (iSP41 < 0) {
1631 cout << "ERROR: SP-41 field can't be negative: " << iSP41 << endl;
1632 continue;
1633 }
1634 }
1635
1636 ind = field_lower.find("vkm2");
1637 if (ind != string::npos) {
1638 beg_pos = ind + 4;
1639 vkm2 = find_first_number(field_lower, beg_pos, end_pos);
1640 }
1641 if (vkm2 != "") {
1642 iVKM2 = atoi(vkm2.c_str());
1643 if (iVKM2 < 0) {
1644 cout << "ERROR: VKM2 field can't be negative: " << iVKM2 << endl;
1645 continue;
1646 }
1647 }
1648
1649 ind = field_lower.find("mv");
1650 if (ind != string::npos) {
1651 end_pos = ind - 1;
1652 field_mv = find_last_double_number(field_lower, beg_pos, end_pos);
1653 if (field_mv.empty()) {
1654 cout << "ERROR: no field voltage before 'mV' found: " << field_lower << " for record id: " << record_id
1655 << endl;
1656 continue;
1657 }
1658 }
1659 if (field_mv != "") {
1660 dVoltage = atof(field_mv.c_str());
1661 if (dVoltage < -1) {
1662 cout << "ERROR: VKM2 field can't be less or equal -1: " << dVoltage << endl;
1663 continue;
1664 }
1665 }
1666
1667 // BEAM
1668 // find energy
1669 double dEnergy = -1;
1670 string beam_lower = beam;
1671 transform(beam_lower.begin(), beam_lower.end(), beam_lower.begin(), ::tolower);
1672 size_t found, next_found;
1673 found = beam_lower.find("gev");
1674 if (found != std::string::npos) {
1675 next_found = beam_lower.find("gev", found + 1);
1676 if (next_found != std::string::npos) {
1677 cout << "ERROR: more than one 'gev' found: " << beam << " for record id: " << record_id << endl;
1678 continue;
1679 }
1680
1681 end_pos = found - 1;
1682 string energy = find_last_double_number(beam_lower, beg_pos, end_pos);
1683 if (energy.empty()) {
1684 cout << "ERROR: no energy before 'gev' found: " << beam << " for record id: " << record_id << endl;
1685 continue;
1686 }
1687 dEnergy = atof(energy.c_str());
1688 if (dEnergy <= 0) {
1689 cout << "ERROR: energy should be greater than 0: " << dEnergy << endl;
1690 continue;
1691 }
1692 }
1693
1694 // parse particles: beam - d or C; target - C|C12, Al, Cu, Pb, C2H4|CH2
1695 string strBeam = "", strTarget = "", strTargetWidth = "";
1696 double dTargetWidth = -1;
1697 /*do
1698 {
1699 ind = beam_lower.find("c");
1700 if (ind != string::npos)
1701 {
1702 if (((ind == 0) || (beam_lower[ind-1] == " ") || (beam_lower[ind-1] == ",") || (beam_lower[ind-1] ==
1703 ".")) &&
1704 ((ind == beam_lower.length()-1) || (beam_lower[ind+1] == " ") || (beam_lower[ind+1] == ",") ||
1705 (beam_lower[ind+1] == "."))) strBeam = "C";
1706 }
1707 } while ((ind != string::npos) && (strBeam != ""));*/
1708 for (size_t i = 0; i < beam_lower.length(); i++) {
1709 if (strBeam.empty()) {
1710 switch (beam_lower[i]) {
1711 case 'c': {
1712 // if "C"
1713 if (check_element(beam_lower, i, "c"))
1714 strBeam = "C";
1715
1716 break;
1717 } // case 'c':
1718 case 'd': {
1719 // if "d"
1720 if (check_element(beam_lower, i, "d"))
1721 strBeam = "d";
1722
1723 break;
1724 } // case 'd':
1725 }
1726 } else {
1727 switch (beam_lower[i]) {
1728 case 'c': {
1729 // if "C"
1730 if (check_element(beam_lower, i, "c")) {
1731 strTarget = "C";
1732 } else {
1733 // if Cu
1734 if (check_element(beam_lower, i, "cu")) {
1735 strTarget = "Cu";
1736 } else {
1737 // if C12
1738 if (check_element(beam_lower, i, "c12")) {
1739 strTarget = "C";
1740 } else {
1741 // if CH2
1742 if (check_element(beam_lower, i, "ch2")) {
1743 strTarget = "C2H4";
1744 } else {
1745 // if C2H4
1746 if (check_element(beam_lower, i, "c2h4")) {
1747 strTarget = "C2H4";
1748 }
1749 }
1750 }
1751 }
1752 }
1753
1754 break;
1755 }
1756 case 'p': {
1757 // if "Pb"
1758 if (check_element(beam_lower, i, "pb"))
1759 strTarget = "Pb";
1760
1761 break;
1762 } // case 'p':
1763 case 'a': {
1764 // if "Al"
1765 if (check_element(beam_lower, i, "al"))
1766 strTarget = "Al";
1767
1768 break;
1769 } // case 'a':
1770 } // switch (beam_lower[i])
1771 } // else if (strBeam.empty())
1772
1773 if (strTarget != "") {
1774 ind = beam_lower.find("mm", i);
1775 if (ind != string::npos) {
1776 end_pos = ind - 1;
1777 strTargetWidth = find_last_double_number(beam_lower, beg_pos, end_pos);
1778 if (strTargetWidth.empty()) {
1779 cout << "ERROR: no target width before 'mm' found: " << beam_lower
1780 << " for record id: " << record_id << endl;
1781 continue;
1782 }
1783 }
1784 if (strTargetWidth != "") {
1785 dTargetWidth = atof(strTargetWidth.c_str());
1786 if (dTargetWidth < 0) {
1787 cout << "ERROR: target field can't be less or equal 0: " << dTargetWidth << endl;
1788 break;
1789 }
1790 }
1791
1792 break;
1793 }
1794 }
1795
1796 TString strComment = "";
1797 if (subject != "") {
1798 strComment += TString::Format("%s", subject.c_str());
1799 if (record_comment != "")
1800 strComment += ". ";
1801 }
1802 strComment += record_comment;
1803
1804 do {
1805 // FORM INSERT STATEMENT
1806 TString sql_insert = TString::Format("insert into log_record(record_date, author, record_type, run_number, "
1807 "shift_leader, trigger_config, daq_status, sp_41, "
1808 "beam, energy, target, target_width, record_comment) "
1809 "values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)");
1810 stmt = elog_server->Statement(sql_insert);
1811 stmt->NextIteration();
1812 int cur_index = 0;
1813 stmt->SetDatime(cur_index++, dtRecordDate);
1814 // stmt->SetString(cur_index++, record_date.c_str());
1815 if (iAuthor < 0)
1816 stmt->SetNull(cur_index++);
1817 else
1818 stmt->SetInt(cur_index++, iAuthor);
1819 /*if (author == "")
1820 stmt->SetNull(cur_index++);
1821 else
1822 stmt->SetString(cur_index++, author.c_str());*/
1823 if (iRecordType < 0)
1824 stmt->SetNull(cur_index++);
1825 else
1826 stmt->SetInt(cur_index++, iRecordType);
1827 /*if (record_type == "")
1828 stmt->SetNull(cur_index++);
1829 else
1830 stmt->SetString(cur_index++, record_type.c_str());*/
1831 if (iRunNumber < 0)
1832 stmt->SetNull(cur_index++);
1833 else
1834 stmt->SetInt(cur_index++, iRunNumber);
1835 /*if (run_number == "")
1836 stmt->SetNull(cur_index++);
1837 else
1838 stmt->SetString(cur_index++, run_number.c_str());*/
1839 if (iShiftLeader < 0)
1840 stmt->SetNull(cur_index++);
1841 else
1842 stmt->SetInt(cur_index++, iShiftLeader);
1843 /*if (shift_leader == "")
1844 stmt->SetNull(cur_index++);
1845 else
1846 stmt->SetString(cur_index++, shift_leader.c_str());*/
1847 if (iTriggerInfo < 0)
1848 stmt->SetNull(cur_index++);
1849 else
1850 stmt->SetInt(cur_index++, iTriggerInfo);
1851 /*if (trigger_info == "")
1852 stmt->SetNull(cur_index++);
1853 else
1854 stmt->SetString(cur_index++, trigger_info.c_str());*/
1855 if (daq_status == "")
1856 stmt->SetNull(cur_index++);
1857 else
1858 stmt->SetString(cur_index++, daq_status.c_str());
1859 // stmt->SetString(cur_index++, daq_status.c_str());
1860 if (iSP41 < 0)
1861 stmt->SetNull(cur_index++);
1862 else
1863 stmt->SetInt(cur_index++, iSP41);
1864 /*if (magnet_field == "")
1865 stmt->SetNull(cur_index++);
1866 else
1867 stmt->SetString(cur_index++, magnet_field.c_str());*/
1868 if (strBeam == "")
1869 stmt->SetNull(cur_index++);
1870 else
1871 stmt->SetString(cur_index++, strBeam.c_str());
1872 if (dEnergy <= 0)
1873 stmt->SetNull(cur_index++);
1874 else
1875 stmt->SetDouble(cur_index++, dEnergy);
1876 if (strTarget == "")
1877 stmt->SetNull(cur_index++);
1878 else
1879 stmt->SetString(cur_index++, strTarget.c_str());
1880 if (dTargetWidth <= 0)
1881 stmt->SetNull(cur_index++);
1882 else
1883 stmt->SetDouble(cur_index++, (Double_t)dTargetWidth);
1884 /*if (beam == "")
1885 stmt->SetNull(cur_index++);
1886 else
1887 stmt->SetString(cur_index++, beam.c_str());*/
1888 if (strComment == "")
1889 stmt->SetNull(cur_index++);
1890 else
1891 stmt->SetString(cur_index++, strComment);
1892 /*if (subject == "")
1893 stmt->SetNull(cur_index++);
1894 else
1895 stmt->SetString(cur_index++, subject.c_str());
1896 if (record_comment == "")
1897 stmt->SetNull(cur_index++);
1898 else
1899 stmt->SetString(cur_index++, record_comment.c_str());*/
1900
1901 // inserting new ELog record to the ELog Database
1902 if (!stmt->Process()) {
1903 cout << "ERROR: inserting a new Elog record to the ELog Database has been failed" << endl;
1904 delete stmt;
1905 return -3;
1906 }
1907 delete stmt;
1908
1909 updated_count++;
1910 if (iLastRunNumber > 0)
1911 iRunNumber++;
1912 } while ((iLastRunNumber > 0) && (iRunNumber <= iLastRunNumber));
1913 } // run CSV file
1914
1915 delete elog_server;
1916 csvFile.close();
1917 return updated_count;
1918}
const Float_t d
Z-ccordinate of the first GEM-station.
Definition BmnMwpcHit.cxx:7
int hex_string_to_int(string hex_string)
int i
Definition P4_F32vec4.h:22
TDatime stringToDatime(string str_time)
TString prepare_sql_code(vector< structParseSchema > vecElements, TString strTableName, bool isUpdate)
int parse_cycle_statement(xmlNodePtr &cur_schema_node, vector< structParseSchema > &vecElements, int &skip_count, char &delimiter_char, int &column_count)
Definition UniParser.cxx:31
xmlNodePtr findNodeByName(xmlNodePtr rootnode, const char *nodename)
bool check_element(const string &str, size_t pos, string element)
int write_string_to_db(string &write_string, TSQLStatement *stmt, structParseSchema &schema, int &count, int cycle_counter)
static ElogConnection * Open()
TSQLServer * GetSQLServer()
static UniConnection * Open()
TSQLServer * GetSQLServer()
static UniDetectorParameter * CreateDetectorParameter(TString detector_name, int parameter_id, int start_period, int start_run, int end_period, int end_run, int value_key, unsigned char *parameter_value, Long_t size_parameter_value, TDatime *expiry_date)
add new detector parameter to the database
int ParseTxtNoise2Db(int period_number, TString txtName, TString schemaPath)
int ParseTxt2Db(TString txtName, TString schemaPath, bool isUpdate=false)
virtual ~UniParser()
Definition UniParser.cxx:29
int ConvertElogCsv(TString csvName="parse_schemes/elog.csv", char separate_symbol=';')
int ParseCsv2Db(TString csvName, TString schemaPath, bool isUpdate=false)
int ParseXml2Db(TString xmlName, TString schemaPath, bool isUpdate=false)
int ParseTxt2Struct(TString txtName, TString schemaPath, vector< structParseValue * > &parse_values, vector< structParseSchema > &vecElements, int iVerbose=1)
int ParseDb2Db()
string int_to_string(int number)
string reduce(const string &str, const string &fill=" ", const string &whitespace=" \t\r")
string find_last_double_number(string const &str, bool isOnlyPositive=true)
string find_first_number(string const &str, bool isOnlyPositive=true)
bool is_string_number(const string &s)
string trim(const string &str, const string &whitespace=" \t\r")
void replace_string_in_text(string &text, string old_substring, string new_substring)
STL namespace.
TString strStatementType
Definition UniParser.h:44
TString strParseType
Definition UniParser.h:47
TString strColumnName
Definition UniParser.h:42
TString strDelimiter
Definition UniParser.h:48
vector< structParseRow > vecRows
Definition UniParser.h:71
TDatime dtSpillEnd
Definition UniParser.h:92
vector< boost::any > arrValues
Definition UniParser.h:93