Inheritance diagram for SqlHistory:
Definition at line 1158 of file history_sql.cxx.
Public Member Functions | |
SqlHistory (SqlBase *b) | |
~SqlHistory () | |
int | hs_set_debug (int debug) |
int | hs_connect (const char *connect_string) |
int | hs_disconnect () |
int | Reconnect () |
int | hs_clear_cache () |
int | XReadIndex () |
int | hs_define_event (const char *event_name, int ntags, const TAG tags[]) |
int | hs_write_event (const char *event_name, time_t timestamp, int buffer_size, const char *buffer) |
int | hs_get_events (std::vector< std::string > *pevents) |
int | hs_get_tags (const char *event_name, std::vector< TAG > *ptags) |
int | hs_read_old_style (double start_time, double end_time, double interval, const char *event_name, const char *tag_name, int var_index, int *num_entries, time_t **time_buffer, double **data_buffer) |
int | hs_read (double start_time, double end_time, double interval, const char *event_name, const char *tag_name, int tag_index, int *num_entries, time_t **time_buffer, double **data_buffer) |
int | hs_read (time_t start_time, time_t end_time, time_t interval, int num_var, const char *event_name[], const char *tag_name[], const int tag_index[], int num_entries[], time_t *time_buffer[], double *data_buffer[], int st[]) |
Data Fields | |
SqlBase * | fSql |
int | fDebug |
std::string | fConnectString |
int | fConnectRetry |
int | fNextConnect |
std::vector< Event * > | fEvents |
std::vector< std::string > | fIndexEvents |
bool | fHaveIndex |
bool | fHaveXIndex |
SqlHistory::SqlHistory | ( | SqlBase * | b | ) |
Definition at line 1171 of file history_sql.cxx.
01172 { 01173 fDebug = 0; 01174 fConnectRetry = 0; 01175 fNextConnect = 0; 01176 fSql = b; 01177 fHaveIndex = false; 01178 fHaveXIndex = false; 01179 }
SqlHistory::~SqlHistory | ( | ) |
Definition at line 1181 of file history_sql.cxx.
01182 { 01183 hs_disconnect(); 01184 delete fSql; 01185 fSql = NULL; 01186 }
int SqlHistory::hs_clear_cache | ( | ) | [virtual] |
clear internal cache, returns HS_SUCCESS
Implements MidasHistoryInterface.
Definition at line 1265 of file history_sql.cxx.
Referenced by hs_disconnect().
01266 { 01267 if (fDebug) 01268 printf("hs_clear_cache!\n"); 01269 01270 gHaveIndex = true; 01271 gHaveIndexAll = false; 01272 fHaveXIndex = false; 01273 01274 for (unsigned i=0; i<gHistoryIndex.size(); i++) { 01275 IndexEntry* ie = gHistoryIndex[i]; 01276 delete ie; 01277 } 01278 gHistoryIndex.clear(); 01279 01280 fIndexEvents.clear(); 01281 01282 return HS_SUCCESS; 01283 }
int SqlHistory::hs_connect | ( | const char * | connect_string | ) | [virtual] |
returns HS_SUCCESS
Implements MidasHistoryInterface.
Definition at line 1197 of file history_sql.cxx.
01198 { 01199 if (fDebug) 01200 printf("hs_connect %s!\n", connect_string); 01201 01202 assert(fSql); 01203 01204 if (fSql->IsConnected()) 01205 if (strcmp(fConnectString.c_str(), connect_string) == 0) 01206 return HS_SUCCESS; 01207 01208 hs_disconnect(); 01209 01210 fConnectString = connect_string; 01211 01212 if (fDebug) 01213 printf("hs_connect: connecting to SQL database \'%s\'\n", fConnectString.c_str()); 01214 01215 int status = fSql->Connect(fConnectString.c_str()); 01216 if (status != DB_SUCCESS) 01217 return status; 01218 01219 std::vector<std::string> tables; 01220 01221 status = fSql->ListTables(&tables); 01222 if (status != DB_SUCCESS) 01223 return status; 01224 01225 for (unsigned i=0; i<tables.size(); i++) { 01226 if (tables[i] == "_history_index") { 01227 fHaveIndex = true; 01228 break; 01229 } 01230 } 01231 01232 return HS_SUCCESS; 01233 }
int SqlHistory::hs_define_event | ( | const char * | event_name, | |
int | ntags, | |||
const TAG | tags[] | |||
) | [virtual] |
see hs_define_event(), returns HS_SUCCESS or HS_FILE_ERROR
Implements MidasHistoryInterface.
Definition at line 1346 of file history_sql.cxx.
01347 { 01348 int status; 01349 01350 if (fDebug) { 01351 printf("define event [%s] with %d tags:\n", event_name, ntags); 01352 PrintTags(ntags, tags); 01353 } 01354 01355 // delete all events with the same name 01356 for (unsigned int i=0; i<fEvents.size(); i++) 01357 if (fEvents[i]) 01358 if (fEvents[i]->event_name == event_name) { 01359 if (fDebug) 01360 printf("deleting exising event %s\n", event_name); 01361 delete fEvents[i]; 01362 fEvents[i] = NULL; 01363 } 01364 01365 Event* e = new Event(); 01366 01367 e->event_name = event_name; 01368 01369 if (!fHaveIndex) { 01370 char buf[1024]; 01371 sprintf(buf, "CREATE TABLE _history_index (event_name VARCHAR(256) NOT NULL, table_name VARCHAR(256), tag_name VARCHAR(256), column_name VARCHAR(256), itimestamp INTEGER NOT NULL);"); 01372 int status = fSql->Exec(buf); 01373 if (status == DB_KEY_EXIST) 01374 /* do nothing */ ; 01375 else if (status != DB_SUCCESS) 01376 return status; 01377 fHaveIndex = true; 01378 } 01379 01380 IndexEntry* ie = FindIndexByEventName(event_name); 01381 01382 if (!ie) { 01383 ReadIndex(fSql, event_name); 01384 ie = FindIndexByEventName(event_name); 01385 } 01386 01387 if (!ie) { 01388 std::string table_name = MidasNameToSqlName(event_name); 01389 01390 double now = time(NULL); 01391 01392 char sss[102400]; 01393 sprintf(sss, "INSERT INTO _history_index (event_name, table_name, itimestamp) VALUES (\'%s\', \'%s\', \'%.0f\');", 01394 event_name, 01395 table_name.c_str(), 01396 now); 01397 01398 int status = fSql->Exec(sss); 01399 if (status != DB_SUCCESS) 01400 return HS_FILE_ERROR; 01401 01402 ReadIndex(fSql, event_name); 01403 ie = FindIndexByEventName(event_name); 01404 } 01405 01406 if (!ie) { 01407 cm_msg(MERROR, "hs_define_event", "could not add event name to SQL history index table, see messages"); 01408 return HS_FILE_ERROR; 01409 } 01410 01411 e->table_name = ie->table_name; 01412 e->active = true; 01413 01414 bool create_event = false; 01415 01416 int offset = 0; 01417 for (int i=0; i<ntags; i++) { 01418 for (unsigned int j=0; j<tags[i].n_data; j++) { 01419 std::string tagname = tags[i].name; 01420 std::string colname = MidasNameToSqlName(tags[i].name); 01421 01422 if (tags[i].n_data > 1) { 01423 char s[256]; 01424 sprintf(s, "[%d]", j); 01425 tagname += s; 01426 01427 sprintf(s, "_%d", j); 01428 colname += s; 01429 } 01430 01431 IndexEntryTag *it = FindIndexByTagName(ie, tagname.c_str()); 01432 if (!it) { 01433 // check for duplicate names 01434 01435 while (1) { 01436 bool dupe = false; 01437 01438 for (unsigned i=0; i<e->tags.size(); i++) { 01439 if (colname == e->tags[i].column_name) { 01440 //printf("duplicate name %s\n", colname.c_str()); 01441 dupe = true; 01442 break; 01443 } 01444 } 01445 01446 if (!dupe) 01447 break; 01448 01449 char s[256]; 01450 sprintf(s, "_%d", rand()); 01451 colname += s; 01452 } 01453 01454 // add tag name to column name translation to the history index 01455 01456 double now = time(NULL); 01457 01458 char sss[102400]; 01459 sprintf(sss, "INSERT INTO _history_index (event_name, tag_name, column_name, itimestamp) VALUES (\'%s\', \'%s\', \'%s\', \'%.0f\');", 01460 event_name, 01461 tagname.c_str(), 01462 colname.c_str(), 01463 now); 01464 01465 int status = fSql->Exec(sss); 01466 if (status != DB_SUCCESS) 01467 return HS_FILE_ERROR; 01468 01469 // reload the history index 01470 01471 ReadIndex(fSql, event_name); 01472 ie = FindIndexByEventName(event_name); 01473 assert(ie); 01474 it = FindIndexByTagName(ie, tagname.c_str()); 01475 } 01476 01477 if (!it) { 01478 cm_msg(MERROR, "hs_define_event", "could not add event tags to SQL history index table, see messages"); 01479 return HS_FILE_ERROR; 01480 } 01481 01482 Tag t; 01483 t.column_name = it->column_name; 01484 t.create = false; 01485 t.offset = offset; 01486 t.tag = tags[i]; 01487 t.tag.n_data = 1; 01488 e->tags.push_back(t); 01489 int size = tid_size[tags[i].type]; 01490 offset += size; 01491 } 01492 } 01493 01494 std::vector<std::string> columns; 01495 01496 status = fSql->ListColumns(e->table_name.c_str(), &columns); 01497 if (status != DB_SUCCESS) 01498 return status; 01499 01500 if (columns.size() <= 0) 01501 create_event = true; 01502 01503 for (size_t i=0; i<e->tags.size(); i++) { 01504 // check for duplicate column names 01505 for (size_t j=i+1; j<e->tags.size(); j++) 01506 if (e->tags[i].column_name == e->tags[j].column_name) { 01507 cm_msg(MERROR, "hs_define_event", "Error: History event \'%s\': Duplicated column name \'%s\' from tags %d \'%s\' and %d \'%s\'", event_name, e->tags[i].column_name.c_str(), i, e->tags[i].tag.name, j, e->tags[j].tag.name); 01508 e->active = false; 01509 break; 01510 } 01511 01512 // check if new column needs to be created 01513 bool found = false; 01514 for (size_t j=0; j<columns.size(); j+=2) { 01515 if (e->tags[i].column_name == columns[j]) { 01516 // column exists, check data type 01517 //printf("column \'%s\', data type %s\n", e->tags[i].column_name.c_str(), columns[j+1].c_str()); 01518 01519 if (!isCompatible(e->tags[i].tag.type, columns[j+1].c_str())) { 01520 cm_msg(MERROR, "hs_define_event", "Error: History event \'%s\': Incompatible data type for tag \'%s\' type \'%s\', SQL column \'%s\' type \'%s\'", event_name, e->tags[i].tag.name, midasTypeName(e->tags[i].tag.type), columns[j].c_str(), columns[j+1].c_str()); 01521 e->active = false; 01522 } 01523 01524 found = true; 01525 break; 01526 } 01527 } 01528 01529 if (!found) { 01530 // create it 01531 //printf("column \'%s\', data type %s --- create!\n", e->tags[i].column_name.c_str(), midasTypeName(e->tags[i].tag.type)); 01532 e->tags[i].create = true; 01533 } 01534 } 01535 01536 if (create_event) { 01537 char buf[1024]; 01538 sprintf(buf, "CREATE TABLE %s (_t_time TIMESTAMP NOT NULL, _i_time INTEGER NOT NULL, INDEX (_i_time), INDEX (_t_time));", e->table_name.c_str()); 01539 status = fSql->Exec(buf); 01540 if (status != DB_SUCCESS) { 01541 e->active = false; 01542 return HS_FILE_ERROR; 01543 } 01544 } 01545 01546 for (size_t i=0; i<e->tags.size(); i++) 01547 if (e->tags[i].create) { 01548 char buf[1024]; 01549 01550 sprintf(buf, "ALTER TABLE %s ADD COLUMN %s %s;", 01551 e->table_name.c_str(), 01552 e->tags[i].column_name.c_str(), 01553 midas2sqlType(e->tags[i].tag.type)); 01554 01555 status = fSql->Exec(buf); 01556 01557 if (status != DB_SUCCESS) { 01558 e->active = false; 01559 return HS_FILE_ERROR; 01560 } 01561 } 01562 01563 // find empty slot in events list 01564 for (unsigned int i=0; i<fEvents.size(); i++) 01565 if (!fEvents[i]) { 01566 fEvents[i] = e; 01567 e = NULL; 01568 break; 01569 } 01570 01571 // if no empty slots, add at the end 01572 if (e) 01573 fEvents.push_back(e); 01574 01575 return HS_SUCCESS; 01576 }
int SqlHistory::hs_disconnect | ( | ) | [virtual] |
disconnect from history, returns HS_SUCCESS
Implements MidasHistoryInterface.
Definition at line 1235 of file history_sql.cxx.
Referenced by hs_connect(), and ~SqlHistory().
01236 { 01237 if (fDebug) 01238 printf("hs_disconnect!\n"); 01239 01240 fSql->Disconnect(); 01241 01242 hs_clear_cache(); 01243 01244 return HS_SUCCESS; 01245 }
int SqlHistory::hs_get_events | ( | std::vector< std::string > * | pevents | ) | [virtual] |
get list of all events, returns HS_SUCCESS
Implements MidasHistoryInterface.
Definition at line 1665 of file history_sql.cxx.
01666 { 01667 if (fDebug) 01668 printf("hs_get_events!\n"); 01669 01670 if (fIndexEvents.size() == 0) { 01671 01672 if (fDebug) 01673 printf("hs_get_events: reading event names!\n"); 01674 01675 ReadIndex(fSql, NULL); 01676 01677 std::vector<std::string> tables; 01678 int status = fSql->ListTables(&tables); 01679 if (status != DB_SUCCESS) 01680 return status; 01681 01682 for (unsigned i=0; i<tables.size(); i++) { 01683 if (tables[i] == "_history_index") 01684 continue; 01685 01686 IndexEntry* ie = FindIndexByTableName(tables[i].c_str()); 01687 if (!ie) { 01688 ReadIndex(fSql, NULL); 01689 ie = FindIndexByTableName(tables[i].c_str()); 01690 } 01691 01692 if (ie) 01693 fIndexEvents.push_back(ie->event_name); 01694 else 01695 fIndexEvents.push_back(tables[i]); 01696 } 01697 } 01698 01699 assert(pevents); 01700 *pevents = fIndexEvents; 01701 01702 return HS_SUCCESS; 01703 }
int SqlHistory::hs_get_tags | ( | const char * | event_name, | |
std::vector< TAG > * | ptags | |||
) | [virtual] |
use event names returned by hs_get_events_odbc(), see hs_get_tags(), returns HS_SUCCESS
Implements MidasHistoryInterface.
Definition at line 1705 of file history_sql.cxx.
01706 { 01707 if (fDebug) 01708 printf("hs_get_tags for [%s]\n", event_name); 01709 01710 assert(ptags); 01711 01712 IndexEntry* ie = FindIndexByEventName(event_name); 01713 01714 if (!ie) { 01715 ReadIndex(fSql, event_name); 01716 ie = FindIndexByEventName(event_name); 01717 } 01718 01719 if (!ie) { 01720 XReadIndex(); 01721 ie = FindIndexByEventName(event_name); 01722 } 01723 01724 if (!ie) 01725 return HS_UNDEFINED_EVENT; 01726 01727 if (ie->tags_cache.size() == 0) { 01728 if (fDebug) 01729 printf("hs_get_tags reading tags for [%s]\n", event_name); 01730 01731 std::string tname = ie->table_name; 01732 01733 std::vector<std::string> columns; 01734 01735 int status = fSql->ListColumns(tname.c_str(), &columns); 01736 if (status != DB_SUCCESS) 01737 return status; 01738 01739 if (columns.size() < 1) { 01740 cm_msg(MERROR, "hs_get_tags", "Cannot get columns for table \'%s\', try to reconnect to the database", tname.c_str()); 01741 01742 int status = Reconnect(); 01743 if (status != HS_SUCCESS) 01744 return status; 01745 01746 columns.clear(); 01747 status = fSql->ListColumns(tname.c_str(), &columns); 01748 if (status != DB_SUCCESS) 01749 return status; 01750 } 01751 01752 TAG* t = (TAG*)malloc(sizeof(TAG)*columns.size()); 01753 assert(t); 01754 01755 for (unsigned int j=0; j<columns.size(); j+=2) { 01756 if (columns[j] == "_t_time") 01757 continue; 01758 if (columns[j] == "_i_time") 01759 continue; 01760 01761 IndexEntryTag* it = FindIndexByColumnName(ie, columns[j].c_str()); 01762 01763 TAG t; 01764 if (it) 01765 STRLCPY(t.name, it->tag_name.c_str()); 01766 else 01767 STRLCPY(t.name, columns[j].c_str()); 01768 t.type = sql2midasType(columns[j+1].c_str()); 01769 t.n_data = 1; 01770 01771 ie->tags_cache.push_back(t); 01772 } 01773 } 01774 01775 for (unsigned i=0; i<ie->tags_cache.size(); i++) 01776 ptags->push_back(ie->tags_cache[i]); 01777 01778 return HS_SUCCESS; 01779 }
int SqlHistory::hs_read | ( | time_t | start_time, | |
time_t | end_time, | |||
time_t | interval, | |||
int | num_var, | |||
const char * | event_name[], | |||
const char * | tag_name[], | |||
const int | tag_index[], | |||
int | num_entries[], | |||
time_t * | time_buffer[], | |||
double * | data_buffer[], | |||
int | st[] | |||
) | [virtual] |
see hs_read(), returns HS_SUCCESS
Implements MidasHistoryInterface.
Definition at line 2033 of file history_sql.cxx.
02039 { 02040 if (fDebug) 02041 printf("hs_read: %d variables\n", num_var); 02042 02043 if (!fSql->IsConnected()) 02044 return HS_FILE_ERROR; 02045 02046 for (int i=0; i<num_var; i++) { 02047 02048 if (event_name[i]==NULL) { 02049 st[i] = HS_UNDEFINED_EVENT; 02050 num_entries[i] = 0; 02051 continue; 02052 } 02053 02054 st[i] = hs_read(start_time, end_time, interval, 02055 event_name[i], tag_name[i], tag_index[i], 02056 &num_entries[i], 02057 &time_buffer[i], &data_buffer[i]); 02058 } 02059 02060 return HS_SUCCESS; 02061 }
int SqlHistory::hs_read | ( | double | start_time, | |
double | end_time, | |||
double | interval, | |||
const char * | event_name, | |||
const char * | tag_name, | |||
int | tag_index, | |||
int * | num_entries, | |||
time_t ** | time_buffer, | |||
double ** | data_buffer | |||
) |
Definition at line 1854 of file history_sql.cxx.
Referenced by hs_read(), and hs_read_old_style().
01858 { 01859 *num_entries = 0; 01860 *time_buffer = NULL; 01861 *data_buffer = NULL; 01862 01863 if (fDebug) 01864 printf("hs_read: event [%s], tag [%s], index %d, start %f, end %f, dt %f, interval %f, max points %f\n", 01865 event_name, tag_name, tag_index, 01866 start_time, end_time, end_time-start_time, interval, (end_time-start_time)/interval); 01867 01868 if (event_name==NULL) 01869 return HS_SUCCESS; 01870 01871 IndexEntry*ie = FindIndexByEventName(event_name); 01872 01873 if (!ie) { 01874 ReadIndex(fSql, event_name); 01875 ie = FindIndexByEventName(event_name); 01876 } 01877 01878 if (!ie) { 01879 XReadIndex(); 01880 ie = FindIndexByEventName(event_name); 01881 } 01882 01883 IndexEntryTag *it = NULL; 01884 01885 if (ie) 01886 it = FindIndexByTagName(ie, tag_name); 01887 01888 if (ie && !it) { // maybe this is an array without "Names"? 01889 char xxx[256]; 01890 sprintf(xxx, "%s[%d]", tag_name, tag_index); 01891 it = FindIndexByTagName(ie, xxx); 01892 } 01893 01894 // new-style event name: "equipment_name/variable_name:tag_name" 01895 // old style event name: "equipment_name:tag_name" ("variable_name" is missing) 01896 bool oldStyleEventName = (strchr(event_name, '/')==NULL); 01897 01898 if (oldStyleEventName) 01899 if (!ie || !it) { 01900 return hs_read_old_style(start_time, end_time, interval, 01901 event_name, tag_name, tag_index, 01902 num_entries, 01903 time_buffer, data_buffer); 01904 } 01905 01906 if (!it) 01907 return HS_UNDEFINED_VAR; 01908 01909 assert(ie); 01910 assert(it); 01911 01912 std::string tname = ie->table_name; 01913 std::string cname = it->column_name; 01914 01915 char cmd[256]; 01916 sprintf(cmd, "SELECT _i_time, %s FROM %s WHERE _i_time>=%.0f and _i_time<=%.0f ORDER BY _i_time;", 01917 cname.c_str(), tname.c_str(), 01918 start_time, end_time); 01919 01920 int status = fSql->Exec(cmd); 01921 01922 if (fDebug) { 01923 printf("hs_read: event \"%s\", tag \"%s\", index %d: Read table \"%s\" column \"%s\": status %d, nrows: %d, ncolumns: %d\n", 01924 event_name, tag_name, tag_index, 01925 tname.c_str(), 01926 cname.c_str(), 01927 status, 01928 fSql->GetNumRows(), 01929 fSql->GetNumColumns() 01930 ); 01931 } 01932 01933 if (status != SUCCESS) { 01934 return HS_FILE_ERROR; 01935 } 01936 01937 if (fSql->GetNumRows() == 0) { 01938 fSql->Done(); 01939 01940 if (oldStyleEventName) { 01941 return hs_read_old_style(start_time, end_time, interval, 01942 event_name, tag_name, tag_index, 01943 num_entries, 01944 time_buffer, data_buffer); 01945 } 01946 01947 return HS_SUCCESS; 01948 } 01949 01950 int nrows = fSql->GetNumRows(); 01951 int ncols = fSql->GetNumColumns(); 01952 01953 if (nrows < 0) 01954 return HS_FILE_ERROR; 01955 01956 if (ncols < 1) 01957 return HS_FILE_ERROR; 01958 01959 *num_entries = 0; 01960 *time_buffer = (time_t*)malloc(nrows * sizeof(time_t)); 01961 *data_buffer = (double*)malloc(nrows * sizeof(double)); 01962 01963 /* Loop through the rows in the result-set */ 01964 int row = 0; 01965 time_t tt = 0; 01966 int ann = 0; 01967 double att = 0; 01968 double avv = 0; 01969 while (1) { 01970 status = fSql->Fetch(); 01971 if (status != DB_SUCCESS) 01972 break; 01973 01974 time_t t = 0; 01975 double v = 0; 01976 01977 const char* timedata = fSql->GetColumn(1); 01978 if (timedata) 01979 t = atoi(timedata); 01980 01981 const char* valuedata = fSql->GetColumn(2); 01982 if (valuedata) 01983 v = atof(valuedata); 01984 01985 if (t < start_time || t > end_time) 01986 continue; 01987 01988 //printf("Row %d, time %d, value %f\n", row, t, v); 01989 //printf("tt: %d, ann: %d\n", tt, ann); 01990 01991 if (tt == 0 || t >= tt + interval) { 01992 01993 if (ann > 0) { 01994 assert(row < nrows); 01995 01996 (*time_buffer)[row] = (time_t)(att/ann); 01997 (*data_buffer)[row] = avv/ann; 01998 01999 row++; 02000 (*num_entries) = row; 02001 } 02002 02003 ann = 0; 02004 att = 0; 02005 avv = 0; 02006 tt = t; 02007 02008 } 02009 02010 ann++; 02011 att += t; 02012 avv += v; 02013 } 02014 02015 if (ann > 0) { 02016 assert(row < nrows); 02017 02018 (*time_buffer)[row] = (time_t)(att/ann); 02019 (*data_buffer)[row] = avv/ann; 02020 02021 row++; 02022 (*num_entries) = row; 02023 } 02024 02025 fSql->Done(); 02026 02027 if (fDebug) 02028 printf("hs_read: return %d entries\n", *num_entries); 02029 02030 return HS_SUCCESS; 02031 }
int SqlHistory::hs_read_old_style | ( | double | start_time, | |
double | end_time, | |||
double | interval, | |||
const char * | event_name, | |||
const char * | tag_name, | |||
int | var_index, | |||
int * | num_entries, | |||
time_t ** | time_buffer, | |||
double ** | data_buffer | |||
) |
Definition at line 1781 of file history_sql.cxx.
Referenced by hs_read().
01785 { 01786 if (fDebug) { 01787 printf("hs_read_old_style: event \"%s\", tag \"%s\"\n", event_name, tag_name); 01788 } 01789 01790 ReadIndex(fSql, NULL); 01791 01792 for (unsigned e=0; e<gHistoryIndex.size(); e++) { 01793 01794 const char* s = gHistoryIndex[e]->event_name.c_str(); 01795 01796 bool match = false; 01797 for (int j=0; s[j]; j++) { 01798 01799 if ((event_name[j]==0) && (s[j]=='/')) { 01800 match = true; 01801 break; 01802 } 01803 01804 if ((event_name[j]==0) && (s[j]=='_')) { 01805 match = true; 01806 break; 01807 } 01808 01809 if (event_name[j]==0) { 01810 match = false; 01811 break; 01812 } 01813 01814 if (tolower(event_name[j]) != tolower(s[j])) { 01815 match = false; 01816 break; 01817 } 01818 } 01819 01820 //printf("try %s, match %d\n", s, match); 01821 01822 if (match) { 01823 bool found_tag = false; 01824 IndexEntry *ie = gHistoryIndex[e]; 01825 for (unsigned v=0; v<ie->tags.size(); v++) { 01826 //printf("try tag [%s] looking for [%s]\n", ie->tags[v].tag_name.c_str(), tag_name); 01827 if (equal_ustring(tag_name, ie->tags[v].tag_name.c_str())) { 01828 found_tag = true; 01829 break; 01830 } 01831 } 01832 01833 if (!found_tag) 01834 match = false; 01835 } 01836 01837 if (match) { 01838 if (fDebug) 01839 printf("hs_read_old_style: event \"%s\", tag \"%s\", try matching event \'%s\'\n", event_name, tag_name, s); 01840 01841 int status = hs_read(start_time, end_time, interval, 01842 s, tag_name, var_index, 01843 num_entries, 01844 time_buffer, data_buffer); 01845 01846 if (status==HS_SUCCESS && *num_entries>0) 01847 return HS_SUCCESS; 01848 } 01849 } 01850 01851 return HS_UNDEFINED_VAR; 01852 }
int SqlHistory::hs_set_debug | ( | int | debug | ) | [virtual] |
int SqlHistory::hs_write_event | ( | const char * | event_name, | |
time_t | timestamp, | |||
int | buffer_size, | |||
const char * | buffer | |||
) | [virtual] |
see hs_write_event(), returns HS_SUCCESS or HS_FILE_ERROR
Implements MidasHistoryInterface.
Definition at line 1578 of file history_sql.cxx.
01579 { 01580 if (fDebug) 01581 printf("hs_write_event: write event \'%s\', time %d, size %d\n", event_name, (int)timestamp, buffer_size); 01582 01583 // if disconnected, try to reconnect 01584 01585 if (!fSql->IsConnected()) { 01586 time_t now = time(NULL); 01587 01588 // too early to try reconnecting? 01589 if (fConnectRetry !=0 && now < fNextConnect) { 01590 return HS_FILE_ERROR; 01591 } 01592 01593 cm_msg(MINFO, "hs_write_event", "Trying to reconnect to SQL database \'%s\'", fConnectString.c_str()); 01594 01595 int status = fSql->Connect(fConnectString.c_str()); 01596 01597 if (status != DB_SUCCESS) { 01598 01599 // first retry in 5 seconds 01600 if (fConnectRetry == 0) 01601 fConnectRetry = 5; 01602 01603 fNextConnect = now + fConnectRetry; 01604 01605 // exponential backoff 01606 fConnectRetry *= 2; 01607 01608 // but no more than every 10 minutes 01609 if (fConnectRetry > 10*60) 01610 fConnectRetry = 10*60; 01611 01612 return HS_FILE_ERROR; 01613 } 01614 01615 cm_msg(MINFO, "hs_write_event", "Reconnected to SQL database \'%s\'", fConnectString.c_str()); 01616 } 01617 01618 fNextConnect = 0; 01619 fConnectRetry = 0; 01620 01621 Event *e = NULL; 01622 01623 // find this event 01624 for (size_t i=0; i<fEvents.size(); i++) 01625 if (fEvents[i]->event_name == event_name) { 01626 e = fEvents[i]; 01627 break; 01628 } 01629 01630 // not found 01631 if (!e) 01632 return HS_UNDEFINED_EVENT; 01633 01634 // deactivated because of error? 01635 if (!e->active) 01636 return HS_FILE_ERROR; 01637 01638 int status = WriteEvent(fSql, e, timestamp, buffer, buffer_size); 01639 01640 // if could not write to SQL? 01641 if (status != HS_SUCCESS) { 01642 01643 // if lost SQL connection, try again later 01644 01645 if (!fSql->IsConnected()) { 01646 return HS_FILE_ERROR; 01647 } 01648 01649 // otherwise, deactivate this event 01650 01651 e->active = false; 01652 01653 cm_msg(MERROR, "hs_write_event", "Event \'%s\' disabled after write error %d into SQL database \'%s\'", event_name, status, fConnectString.c_str()); 01654 01655 return HS_FILE_ERROR; 01656 } 01657 01658 return HS_SUCCESS; 01659 }
int SqlHistory::Reconnect | ( | ) |
Definition at line 1247 of file history_sql.cxx.
Referenced by hs_get_tags().
01248 { 01249 if (fDebug) 01250 printf("Reconnect to SQL database!\n"); 01251 01252 fSql->Disconnect(); 01253 fSql->Connect(fConnectString.c_str()); 01254 if (!fSql->IsConnected()) { 01255 return HS_FILE_ERROR; 01256 } 01257 01258 return HS_SUCCESS; 01259 }
int SqlHistory::XReadIndex | ( | ) |
Definition at line 1285 of file history_sql.cxx.
Referenced by hs_get_tags(), and hs_read().
01286 { 01287 if (fHaveXIndex) 01288 return HS_SUCCESS; 01289 01290 if (fDebug) 01291 printf("XReadIndex!\n"); 01292 01293 std::vector<std::string> tables; 01294 01295 int status = fSql->ListTables(&tables); 01296 if (status != DB_SUCCESS) 01297 return status; 01298 01299 for (unsigned i=0; i<tables.size(); i++) { 01300 if (tables[i] == "_history_index") 01301 continue; 01302 01303 IndexEntry* ie = NULL; //FindEventName(tables[i].c_str()); 01304 01305 if (!ie) { 01306 ie = new IndexEntry; 01307 01308 ie->table_name = tables[i]; 01309 ie->event_name = ie->table_name; 01310 01311 gHistoryIndex.push_back(ie); 01312 } 01313 01314 std::vector<std::string> columns; 01315 01316 status = fSql->ListColumns(ie->table_name.c_str(), &columns); 01317 if (status != DB_SUCCESS) 01318 return status; 01319 01320 for (unsigned int j=0; j<columns.size(); j+=2) { 01321 if (columns[j] == "_t_time") 01322 continue; 01323 if (columns[j] == "_i_time") 01324 continue; 01325 01326 IndexEntryTag t; 01327 t.column_name = columns[j]; 01328 t.tag_name = t.column_name; 01329 t.timestamp = 0; 01330 01331 ie->tags.push_back(t); 01332 } 01333 } 01334 01335 fHaveXIndex = true; 01336 01337 //PrintIndex(); 01338 01339 return HS_SUCCESS; 01340 }
std::string SqlHistory::fConnectString |
Definition at line 1163 of file history_sql.cxx.
Referenced by hs_connect(), hs_write_event(), and Reconnect().
Definition at line 1162 of file history_sql.cxx.
std::vector<Event*> SqlHistory::fEvents |
Definition at line 1166 of file history_sql.cxx.
Referenced by hs_define_event(), and hs_write_event().
Definition at line 1168 of file history_sql.cxx.
Referenced by hs_connect(), hs_define_event(), and SqlHistory().
Definition at line 1169 of file history_sql.cxx.
Referenced by hs_clear_cache(), SqlHistory(), and XReadIndex().
std::vector<std::string> SqlHistory::fIndexEvents |
Definition at line 1167 of file history_sql.cxx.
Referenced by hs_clear_cache(), and hs_get_events().
Definition at line 1161 of file history_sql.cxx.
Referenced by hs_connect(), hs_define_event(), hs_disconnect(), hs_get_events(), hs_get_tags(), hs_read(), hs_read_old_style(), hs_set_debug(), hs_write_event(), Reconnect(), SqlHistory(), XReadIndex(), and ~SqlHistory().