00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include <assert.h>
00016
00017 #include <map>
00018
00019 #include "midas.h"
00020 #include "msystem.h"
00021 #include "history.h"
00022
00023 #define STRLCPY(dst, src) strlcpy(dst, src, sizeof(dst))
00024
00025 static WORD get_variable_id(DWORD ltime, const char* evname, const char* tagname)
00026 {
00027 HNDLE hDB, hKeyRoot;
00028 int status, i;
00029
00030 cm_get_experiment_database(&hDB, NULL);
00031
00032 status = db_find_key(hDB, 0, "/History/Events", &hKeyRoot);
00033 if (status != DB_SUCCESS) {
00034 return 0;
00035 }
00036
00037 for (i = 0;; i++) {
00038 HNDLE hKey;
00039 KEY key;
00040 WORD evid;
00041 char buf[256];
00042 int size;
00043 char *s;
00044 int j;
00045 int ntags = 0;
00046 TAG* tags = NULL;
00047 char event_name[NAME_LENGTH];
00048
00049 status = db_enum_key(hDB, hKeyRoot, i, &hKey);
00050 if (status != DB_SUCCESS)
00051 break;
00052
00053 status = db_get_key(hDB, hKey, &key);
00054 assert(status == DB_SUCCESS);
00055
00056 if (!isdigit(key.name[0]))
00057 continue;
00058
00059 evid = atoi(key.name);
00060
00061 assert(key.item_size < (int)sizeof(buf));
00062
00063 size = sizeof(buf);
00064 status = db_get_data(hDB, hKey, buf, &size, TID_STRING);
00065 assert(status == DB_SUCCESS);
00066
00067 strlcpy(event_name, buf, sizeof(event_name));
00068
00069 s = strchr(buf,':');
00070 if (s)
00071 *s = 0;
00072
00073
00074
00075 if (!equal_ustring((char *)evname, buf))
00076 continue;
00077
00078 status = hs_get_tags(ltime, evid, event_name, &ntags, &tags);
00079
00080
00081
00082
00083
00084 for (j=0; j<ntags; j++) {
00085
00086
00087 if (equal_ustring((char *)tagname, tags[j].name)) {
00088 if (tags)
00089 free(tags);
00090 return evid;
00091 }
00092 }
00093
00094 if (tags)
00095 free(tags);
00096 tags = NULL;
00097 }
00098
00099 return 0;
00100 }
00101
00102 static WORD get_variable_id_tags(const char* evname, const char* tagname)
00103 {
00104 HNDLE hDB, hKeyRoot;
00105 int status, i;
00106
00107 cm_get_experiment_database(&hDB, NULL);
00108
00109 status = db_find_key(hDB, 0, "/History/Tags", &hKeyRoot);
00110 if (status != DB_SUCCESS) {
00111 return 0;
00112 }
00113
00114 for (i = 0;; i++) {
00115 HNDLE hKey;
00116 KEY key;
00117 WORD evid;
00118 char buf[256];
00119 int size;
00120 char *s;
00121 int j;
00122
00123 status = db_enum_key(hDB, hKeyRoot, i, &hKey);
00124 if (status != DB_SUCCESS)
00125 break;
00126
00127 status = db_get_key(hDB, hKey, &key);
00128 assert(status == DB_SUCCESS);
00129
00130 if (key.type != TID_STRING)
00131 continue;
00132
00133 if (!isdigit(key.name[0]))
00134 continue;
00135
00136 evid = atoi(key.name);
00137
00138 assert(key.item_size < (int)sizeof(buf));
00139
00140 size = sizeof(buf);
00141 status = db_get_data_index(hDB, hKey, buf, &size, 0, TID_STRING);
00142 assert(status == DB_SUCCESS);
00143
00144 s = strchr(buf,'/');
00145 if (s)
00146 *s = 0;
00147
00148
00149
00150 if (!equal_ustring((char *)evname, buf))
00151 continue;
00152
00153 for (j=1; j<key.num_values; j++) {
00154 size = sizeof(buf);
00155 status = db_get_data_index(hDB, hKey, buf, &size, j, TID_STRING);
00156 assert(status == DB_SUCCESS);
00157
00158 if (!isdigit(buf[0]))
00159 continue;
00160
00161 s = strchr(buf,' ');
00162 if (!s)
00163 continue;
00164
00165 s++;
00166
00167
00168
00169 if (equal_ustring((char *)tagname, s)) {
00170
00171 return evid;
00172 }
00173 }
00174 }
00175
00176 return 0;
00177 }
00178
00179 static int get_event_id(const char* event_name)
00180 {
00181 HNDLE hDB, hKeyRoot;
00182 int status, i;
00183 char name[256];
00184 STRLCPY(name, event_name);
00185 char *s = strchr(name, '/');
00186 if (s)
00187 *s = ':';
00188
00189
00190
00191 cm_get_experiment_database(&hDB, NULL);
00192
00193 status = db_find_key(hDB, 0, "/History/Events", &hKeyRoot);
00194 if (status == DB_SUCCESS) {
00195 for (i = 0;; i++) {
00196 HNDLE hKey;
00197 KEY key;
00198 WORD evid;
00199 int size;
00200 char tmp[NAME_LENGTH+NAME_LENGTH+2];
00201
00202 status = db_enum_key(hDB, hKeyRoot, i, &hKey);
00203 if (status != DB_SUCCESS)
00204 break;
00205
00206 status = db_get_key(hDB, hKey, &key);
00207 assert(status == DB_SUCCESS);
00208
00209
00210
00211 evid = (WORD) strtol(key.name, NULL, 0);
00212 if (evid == 0)
00213 continue;
00214
00215 size = sizeof(tmp);
00216 status = db_get_data(hDB, hKey, tmp, &size, TID_STRING);
00217
00218 assert(status == DB_SUCCESS);
00219
00220
00221
00222 if (equal_ustring(name, tmp))
00223 return evid;
00224 }
00225 }
00226
00227 int max_id = 100;
00228
00229
00230 if (strcmp(name, "Run transitions")==0) {
00231 status = db_set_value(hDB, 0, "/History/Events/0", name, strlen(name)+1, 1, TID_STRING);
00232 assert(status == DB_SUCCESS);
00233 return 0;
00234 }
00235
00236 while (1) {
00237 char tmp[NAME_LENGTH+NAME_LENGTH+2];
00238 HNDLE hKey;
00239 WORD evid = max_id + 1;
00240
00241 sprintf(tmp,"/History/Events/%d", evid);
00242
00243 status = db_find_key(hDB, 0, tmp, &hKey);
00244 if (status == DB_SUCCESS) {
00245 max_id = evid;
00246 assert(max_id < 65000);
00247 continue;
00248 }
00249
00250 status = db_set_value(hDB, 0, tmp, name, strlen(name)+1, 1, TID_STRING);
00251 assert(status == DB_SUCCESS);
00252
00253 return evid;
00254 }
00255
00256
00257 return -1;
00258 }
00259
00260 #if 0
00261 char* sort_names(char* names)
00262 {
00263 int i, p;
00264 int len = 0;
00265 int num = 0;
00266 char* arr_names;
00267 struct poor_mans_list sorted;
00268
00269 for (i=0, p=0; names[p]!=0; i++) {
00270 const char*pp = names+p;
00271 int pplen = strlen(pp);
00272
00273 if (pplen > len)
00274 len = pplen;
00275 p += strlen(names+p) + 1;
00276 }
00277
00278 num = i;
00279
00280 len+=1;
00281
00282 arr_names = (char*)malloc(len*num);
00283
00284 for (i=0, p=0; names[p]!=0; i++) {
00285 const char*pp = names+p;
00286 strlcpy(arr_names+i*len, pp, len);
00287 p += strlen(names+p) + 1;
00288 }
00289
00290 free(names);
00291
00292 qsort(arr_names, num, len, sort_tags);
00293
00294 list_init(&sorted);
00295
00296 for (i=0; i<num; i++)
00297 list_add(&sorted, arr_names+i*len);
00298
00299 return sorted.names;
00300 }
00301 #endif
00302
00303
00304
00305 class MidasHistory: public MidasHistoryInterface
00306 {
00307 public:
00308 int fDebug;
00309
00310 int fListSource;
00311
00312 std::vector<std::string> fEventsCache;
00313 std::map<std::string, std::vector<TAG> > fTagsCache;
00314 std::map<std::string, int > fEvidCache;
00315
00316 public:
00317 MidasHistory()
00318 {
00319 fDebug = 0;
00320 fListSource = 0;
00321 }
00322
00323 ~MidasHistory()
00324 {
00325
00326 }
00327
00328
00329
00330 int hs_connect(const char* unused_connect_string)
00331 {
00332 HNDLE hDB;
00333 int status;
00334 char str[1024];
00335
00336 cm_get_experiment_database(&hDB, NULL);
00337
00338
00339 int size = sizeof(str);
00340 memset(str, 0, size);
00341
00342 status = db_get_value(hDB, 0, "/Logger/History dir", str, &size, TID_STRING, FALSE);
00343 if (status != DB_SUCCESS)
00344 status = db_get_value(hDB, 0, "/Logger/Data dir", str, &size, TID_STRING, TRUE);
00345
00346 if (status == DB_SUCCESS)
00347 ::hs_set_path(str);
00348
00349
00350
00351 int oldListSource = fListSource;
00352
00353 fListSource = 0;
00354 size = sizeof(fListSource);
00355 status = db_get_value(hDB, 0, "/History/ListSource", &fListSource, &size, TID_INT, TRUE);
00356
00357
00358
00359 if (fListSource == 0) {
00360 HNDLE hKey;
00361 status = db_find_key(hDB, 0, "/History/Tags", &hKey);
00362 if (status == DB_SUCCESS)
00363 fListSource = 2;
00364 }
00365
00366
00367
00368 if (fListSource == 0) {
00369 HNDLE hKey;
00370 status = db_find_key(hDB, 0, "/History/Events", &hKey);
00371 if (status == DB_SUCCESS)
00372 fListSource = 3;
00373 }
00374
00375 if (fListSource != oldListSource)
00376 hs_clear_cache();
00377
00378 if (fDebug)
00379 printf("hs_connect: path [%s], list source %d\n", str, fListSource);
00380
00381 return HS_SUCCESS;
00382 }
00383
00384
00385
00386 int hs_disconnect()
00387 {
00388 hs_clear_cache();
00389 return HS_SUCCESS;
00390 }
00391
00392
00393
00394 int hs_set_debug(int debug)
00395 {
00396 return debug;
00397 }
00398
00399
00400
00401 int hs_clear_cache()
00402 {
00403 if (fDebug)
00404 printf("hs_clear_cache!\n");
00405
00406 fEventsCache.clear();
00407 fTagsCache.clear();
00408 fEvidCache.clear();
00409 return HS_SUCCESS;
00410 }
00411
00412
00413
00414 int hs_define_event(const char* event_name, int ntags, const TAG tags[])
00415 {
00416 int event_id = get_event_id(event_name);
00417 fEvidCache[event_name] = event_id;
00418 return ::hs_define_event(event_id, (char*)event_name, (TAG*)tags, ntags*sizeof(TAG));
00419 }
00420
00421 int hs_write_event(const char* event_name, time_t timestamp, int data_size, const char* data)
00422 {
00423 int event_id = fEvidCache[event_name];
00424
00425 return ::hs_write_event(event_id, (void*)data, data_size);
00426 }
00427
00428
00429
00430 int GetEventsFromEquipment(std::vector<std::string> *events)
00431 {
00432 HNDLE hDB, hKeyRoot;
00433 int i, status;
00434
00435 cm_get_experiment_database(&hDB, NULL);
00436
00437 status = db_find_key(hDB, 0, "/Equipment", &hKeyRoot);
00438 if (status != DB_SUCCESS) {
00439 return HS_FILE_ERROR;
00440 }
00441
00442
00443 for (i = 0;; i++) {
00444 HNDLE hKeyEq;
00445 int history;
00446 int size;
00447
00448 status = db_enum_key(hDB, hKeyRoot, i, &hKeyEq);
00449 if (status != DB_SUCCESS)
00450 break;
00451
00452
00453 size = sizeof(history);
00454 db_get_value(hDB, hKeyEq, "Common/Log history", &history, &size, TID_INT, TRUE);
00455
00456
00457 if (history > 0) {
00458 KEY key;
00459 char *evname;
00460
00461
00462 db_get_key(hDB, hKeyEq, &key);
00463
00464 evname = key.name;
00465
00466 events->push_back(evname);
00467
00468
00469 }
00470 }
00471
00472
00473 status = db_find_key(hDB, 0, "/History/Links", &hKeyRoot);
00474 if (status == DB_SUCCESS) {
00475 for (i = 0;; i++) {
00476 HNDLE hKey;
00477 KEY key;
00478 char* evname;
00479
00480 status = db_enum_link(hDB, hKeyRoot, i, &hKey);
00481 if (status == DB_NO_MORE_SUBKEYS)
00482 break;
00483
00484 db_get_key(hDB, hKey, &key);
00485
00486 evname = key.name;
00487
00488 events->push_back(evname);
00489
00490
00491 }
00492 }
00493
00494 return HS_SUCCESS;
00495 }
00496
00497 int GetEventsFromOdbEvents(std::vector<std::string> *events)
00498 {
00499 int i;
00500 HNDLE hDB, hKeyRoot;
00501 int status;
00502
00503 cm_get_experiment_database(&hDB, NULL);
00504
00505 status = db_find_key(hDB, 0, "/History/Events", &hKeyRoot);
00506 if (status != DB_SUCCESS) {
00507 return HS_FILE_ERROR;
00508 }
00509
00510
00511 for (i = 0;; i++) {
00512 HNDLE hKeyEq;
00513 char *s;
00514 char evname[1024+NAME_LENGTH];
00515 int size;
00516
00517 status = db_enum_key(hDB, hKeyRoot, i, &hKeyEq);
00518 if (status != DB_SUCCESS)
00519 break;
00520
00521 size = sizeof(evname);
00522 status = db_get_data(hDB, hKeyEq, evname, &size, TID_STRING);
00523 assert(status == DB_SUCCESS);
00524
00525 s = strchr(evname,':');
00526 if (s)
00527 *s = '/';
00528
00529
00530
00531 int found = 0;
00532 for (unsigned i=0; i<events->size(); i++) {
00533 if (equal_ustring(evname, (*events)[i].c_str())) {
00534 found = 1;
00535 break;
00536 }
00537 }
00538
00539 if (found)
00540 continue;
00541
00542 events->push_back(evname);
00543
00544
00545 }
00546
00547 return HS_SUCCESS;
00548 }
00549
00550 int GetEventsFromOdbTags(std::vector<std::string> *events)
00551 {
00552 HNDLE hDB;
00553 int i;
00554 HNDLE hKeyRoot;
00555 int status;
00556
00557 cm_get_experiment_database(&hDB, NULL);
00558
00559 status = db_find_key(hDB, 0, "/History/Tags", &hKeyRoot);
00560 if (status != DB_SUCCESS) {
00561 return HS_FILE_ERROR;
00562 }
00563
00564
00565 for (i = 0;; i++) {
00566 HNDLE hKeyEq;
00567 KEY key;
00568 char *s;
00569 WORD event_id;
00570 char evname[1024+NAME_LENGTH];
00571 int size;
00572
00573 status = db_enum_key(hDB, hKeyRoot, i, &hKeyEq);
00574 if (status != DB_SUCCESS)
00575 break;
00576
00577
00578 db_get_key(hDB, hKeyEq, &key);
00579
00580
00581
00582 if (key.type != TID_STRING)
00583 continue;
00584
00585
00586 s = key.name;
00587
00588 event_id = (WORD)strtoul(s,&s,0);
00589 if (event_id == 0)
00590 continue;
00591 if (s[0] != 0)
00592 continue;
00593
00594 size = sizeof(evname);
00595 status = db_get_data_index(hDB, hKeyEq, evname, &size, 0, TID_STRING);
00596 assert(status == DB_SUCCESS);
00597
00598
00599
00600 int found = 0;
00601 for (unsigned i=0; i<events->size(); i++) {
00602 if (equal_ustring(evname, (*events)[i].c_str())) {
00603 found = 1;
00604 break;
00605 }
00606 }
00607
00608 if (found)
00609 continue;
00610
00611 events->push_back(evname);
00612
00613
00614 }
00615
00616 return HS_SUCCESS;
00617 }
00618
00619 int hs_get_events(std::vector<std::string> *pevents)
00620 {
00621 assert(pevents);
00622 pevents->clear();
00623
00624 if (fEventsCache.size() == 0) {
00625 int status;
00626 HNDLE hDB;
00627 cm_get_experiment_database(&hDB, NULL);
00628
00629 if (fDebug)
00630 printf("hs_get_events: reading events list!\n");
00631
00632 switch (fListSource) {
00633 case 0:
00634 case 1:
00635 status = GetEventsFromEquipment(&fEventsCache);
00636 break;
00637 case 2:
00638 status = GetEventsFromOdbTags(&fEventsCache);
00639 break;
00640 case 3:
00641 status = GetEventsFromOdbEvents(&fEventsCache);
00642 break;
00643 default:
00644 return HS_FILE_ERROR;
00645 }
00646
00647 if (status != HS_SUCCESS)
00648 return status;
00649 }
00650
00651 for (unsigned i=0; i<fEventsCache.size(); i++)
00652 pevents->push_back(fEventsCache[i]);
00653
00654 return HS_SUCCESS;
00655 }
00656
00657 int xhs_event_id(time_t t, const char* event_name, const char* tag_name, int *pevid)
00658 {
00659 if (fDebug)
00660 printf("xhs_event_id for event [%s], tag [%s]\n", event_name, tag_name);
00661
00662 *pevid = 0;
00663
00664
00665 DWORD event_id = get_variable_id_tags(event_name, tag_name);
00666
00667
00668 if (event_id == 0)
00669 event_id = get_variable_id((DWORD)t, event_name, tag_name);
00670
00671
00672 if ((event_id == 0) && equal_ustring(event_name, "Run transitions")) {
00673 *pevid = 0;
00674 return HS_SUCCESS;
00675 }
00676
00677
00678 if (event_id == 0) {
00679 int status = hs_get_event_id(0, (char*)event_name, &event_id);
00680 if (status != HS_SUCCESS)
00681 return status;
00682 }
00683
00684 if (event_id == 0)
00685 return HS_UNDEFINED_VAR;
00686
00687 *pevid = event_id;
00688
00689 return HS_SUCCESS;
00690 }
00691
00692 int GetTagsFromEquipment(const char* event_name, std::vector<TAG> *ptags)
00693 {
00694 HNDLE hDB, hKeyRoot;
00695 HNDLE hKey, hKeyEq, hKeyVar;
00696 BOOL is_link = FALSE;
00697 int status;
00698 int i;
00699 char eq_name[NAME_LENGTH];
00700 char str[256];
00701
00702 cm_get_experiment_database(&hDB, NULL);
00703
00704 status = db_find_key(hDB, 0, "/Equipment", &hKeyRoot);
00705 if (status != DB_SUCCESS) {
00706 return HS_FILE_ERROR;
00707 }
00708
00709
00710
00711 STRLCPY(eq_name, event_name);
00712
00713 is_link = FALSE;
00714 db_find_key(hDB, hKeyRoot, eq_name, &hKeyEq);
00715 if (!hKeyEq) {
00716 sprintf(str, "/History/Links/%s", eq_name);
00717 status = db_find_link(hDB, 0, str, &hKeyVar);
00718 if (status != DB_SUCCESS) {
00719 return HS_FILE_ERROR;
00720 } else
00721 is_link = TRUE;
00722 }
00723
00724
00725 if (!is_link) {
00726 sprintf(str, "/Equipment/%s/Variables", eq_name);
00727 status = db_find_key(hDB, 0, str, &hKeyVar);
00728 if (status != DB_SUCCESS) {
00729 return HS_FILE_ERROR;
00730 }
00731 }
00732
00733 for (i = 0;; i++) {
00734 KEY varkey;
00735
00736 status = db_enum_link(hDB, hKeyVar, i, &hKey);
00737 if (status == DB_NO_MORE_SUBKEYS)
00738 break;
00739
00740 if (is_link) {
00741 db_get_key(hDB, hKey, &varkey);
00742 TAG t;
00743 STRLCPY(t.name, varkey.name);
00744 t.n_data = varkey.num_values;
00745 t.type = varkey.type;
00746 ptags->push_back(t);
00747 } else {
00748 int n_names;
00749 int single_names;
00750 HNDLE hKeyNames;
00751 char var_name[NAME_LENGTH];
00752
00753
00754 db_get_key(hDB, hKey, &varkey);
00755 n_names = 0;
00756
00757
00758 db_find_key(hDB, hKeyEq, "Settings/Names", &hKeyNames);
00759 single_names = (hKeyNames > 0);
00760 if (hKeyNames) {
00761 KEY key;
00762
00763 db_get_key(hDB, hKeyNames, &key);
00764 n_names = key.num_values;
00765 } else {
00766 KEY key;
00767 sprintf(str, "Settings/Names %s", varkey.name);
00768 db_find_key(hDB, hKeyEq, str, &hKeyNames);
00769 if (hKeyNames) {
00770
00771 db_get_key(hDB, hKeyNames, &key);
00772 n_names = key.num_values;
00773 }
00774 }
00775
00776 if (hKeyNames) {
00777 int j;
00778
00779
00780 for (j = 0; j < n_names; j++) {
00781 int size;
00782
00783 size = NAME_LENGTH;
00784 db_get_data_index(hDB, hKeyNames, var_name, &size, j, TID_STRING);
00785
00786
00787 if (single_names) {
00788 strlcat(var_name, " ", sizeof(var_name));
00789 strlcat(var_name, varkey.name, sizeof(var_name));
00790 }
00791
00792 TAG t;
00793 STRLCPY(t.name, var_name);
00794 t.type = varkey.type;
00795 t.n_data = 1;
00796
00797 ptags->push_back(t);
00798 }
00799 } else {
00800 TAG t;
00801 STRLCPY(t.name, varkey.name);
00802 t.n_data = varkey.num_values;
00803 t.type = varkey.type;
00804
00805 ptags->push_back(t);
00806 }
00807 }
00808 }
00809
00810 return HS_SUCCESS;
00811 }
00812
00813 int GetTagsFromHS(const char* event_name, std::vector<TAG> *ptags)
00814 {
00815 time_t now = time(NULL);
00816 int evid;
00817 int status = xhs_event_id(now, event_name, NULL, &evid);
00818 if (status != HS_SUCCESS)
00819 return status;
00820
00821 if (fDebug)
00822 printf("hs_get_tags: get tags for event [%s] %d\n", event_name, evid);
00823
00824 int ntags;
00825 TAG* tags;
00826 status = ::hs_get_tags((DWORD)now, evid, (char*)event_name, &ntags, &tags);
00827
00828 if (status != HS_SUCCESS)
00829 return status;
00830
00831 for (int i=0; i<ntags; i++)
00832 ptags->push_back(tags[i]);
00833
00834 if (tags)
00835 free(tags);
00836
00837 if (fDebug)
00838 printf("hs_get_tags: get tags for event [%s] %d, found %d tags\n", event_name, evid, ntags);
00839
00840 return HS_SUCCESS;
00841 }
00842
00843 int GetTagsFromOdb(const char* event_name, std::vector<TAG> *ptags)
00844 {
00845 HNDLE hDB, hKeyRoot;
00846 int i, j;
00847 int status;
00848
00849 cm_get_experiment_database(&hDB, NULL);
00850
00851 status = db_find_key(hDB, 0, "/History/Tags", &hKeyRoot);
00852 if (status != DB_SUCCESS) {
00853 return HS_FILE_ERROR;
00854 }
00855
00856
00857 for (i = 0;; i++) {
00858 HNDLE hKey;
00859 KEY key;
00860 WORD event_id;
00861 char buf[256];
00862 int size;
00863 char* s;
00864
00865 status = db_enum_key(hDB, hKeyRoot, i, &hKey);
00866 if (status != DB_SUCCESS)
00867 break;
00868
00869
00870 status = db_get_key(hDB, hKey, &key);
00871 assert(status == DB_SUCCESS);
00872
00873
00874 if (!isdigit(key.name[0]))
00875 continue;
00876
00877 event_id = atoi(key.name);
00878 if (event_id == 0)
00879 continue;
00880
00881 if (key.item_size >= (int)sizeof(buf))
00882 continue;
00883
00884 if (key.num_values == 1) {
00885
00886 HNDLE hKeyDir;
00887 sprintf(buf, "Tags %d", event_id);
00888 status = db_find_key(hDB, hKeyRoot, buf, &hKeyDir);
00889 if (status != DB_SUCCESS)
00890 continue;
00891
00892
00893 for (j=0; ; j++) {
00894 HNDLE hKey;
00895 WORD array;
00896 int size;
00897 char var_name[NAME_LENGTH];
00898
00899 status = db_enum_key(hDB, hKeyDir, j, &hKey);
00900 if (status != DB_SUCCESS)
00901 break;
00902
00903
00904 status = db_get_key(hDB, hKey, &key);
00905 assert(status == DB_SUCCESS);
00906
00907 array = 1;
00908 size = sizeof(array);
00909 status = db_get_data(hDB, hKey, &array, &size, TID_WORD);
00910 assert(status == DB_SUCCESS);
00911
00912 strlcpy(var_name, key.name, sizeof(var_name));
00913
00914
00915
00916 TAG t;
00917 STRLCPY(t.name, var_name);
00918 t.n_data = array;
00919 t.type = 0;
00920
00921 ptags->push_back(t);
00922 }
00923
00924 continue;
00925 }
00926
00927 if (key.type != TID_STRING)
00928 continue;
00929
00930 size = sizeof(buf);
00931 status = db_get_data_index(hDB, hKey, buf, &size, 0, TID_STRING);
00932 assert(status == DB_SUCCESS);
00933
00934 if (strchr(event_name, '/')==NULL) {
00935 char* s = strchr(buf, '/');
00936 if (s)
00937 *s = 0;
00938 }
00939
00940
00941
00942 if (!equal_ustring(buf, event_name))
00943 continue;
00944
00945
00946 for (j=1; j<key.num_values; j++) {
00947 int array;
00948 int size;
00949 char var_name[NAME_LENGTH];
00950 int ev_type;
00951
00952 size = sizeof(buf);
00953 status = db_get_data_index(hDB, hKey, buf, &size, j, TID_STRING);
00954 assert(status == DB_SUCCESS);
00955
00956
00957
00958 if (!isdigit(buf[0]))
00959 continue;
00960
00961 sscanf(buf, "%d[%d]", &ev_type, &array);
00962
00963 s = strchr(buf, ' ');
00964 if (!s)
00965 continue;
00966 s++;
00967
00968 STRLCPY(var_name, s);
00969
00970 TAG t;
00971 STRLCPY(t.name, var_name);
00972 t.n_data = array;
00973 t.type = ev_type;
00974
00975
00976
00977 ptags->push_back(t);
00978 }
00979 }
00980
00981 return HS_SUCCESS;
00982 }
00983
00984
00985
00986 int hs_get_tags(const char* event_name, std::vector<TAG> *ptags)
00987 {
00988 std::vector<TAG>& ttt = fTagsCache[event_name];
00989
00990 if (ttt.size() == 0) {
00991 int status = HS_FILE_ERROR;
00992
00993 if (fDebug)
00994 printf("hs_get_tags: reading tags for event [%s] using list source %d\n", event_name, fListSource);
00995
00996 switch (fListSource) {
00997 case 0:
00998 case 1:
00999 status = GetTagsFromEquipment(event_name, &ttt);
01000 break;
01001 case 2:
01002 status = GetTagsFromOdb(event_name, &ttt);
01003 break;
01004 case 3:
01005 status = GetTagsFromHS(event_name, &ttt);
01006 break;
01007 }
01008
01009 if (status != HS_SUCCESS)
01010 return status;
01011 }
01012
01013 for (unsigned i=0; i<ttt.size(); i++)
01014 ptags->push_back(ttt[i]);
01015
01016 return HS_SUCCESS;
01017 }
01018
01019
01020
01021 int hs_read(time_t start_time, time_t end_time, time_t interval,
01022 int num_var,
01023 const char* event_name[], const char* tag_name[], const int var_index[],
01024 int num_entries[],
01025 time_t* time_buffer[], double* data_buffer[],
01026 int st[])
01027 {
01028 DWORD* tbuffer = NULL;
01029 char* ybuffer = NULL;
01030 DWORD bsize, tsize;
01031 int hbuffer_size = 0;
01032
01033 if (hbuffer_size == 0) {
01034 hbuffer_size = 1000 * sizeof(DWORD);
01035 tbuffer = (DWORD*)malloc(hbuffer_size);
01036 ybuffer = (char*)malloc(hbuffer_size);
01037 }
01038
01039 for (int i=0; i<num_var; i++) {
01040 DWORD tid;
01041 int event_id;
01042
01043 if (event_name[i]==NULL) {
01044 st[i] = HS_UNDEFINED_EVENT;
01045 num_entries[i] = 0;
01046 continue;
01047 }
01048
01049 int status = xhs_event_id(start_time, event_name[i], tag_name[i], &event_id);
01050
01051 if (status != HS_SUCCESS) {
01052 st[i] = status;
01053 continue;
01054 }
01055
01056 DWORD n_point = 0;
01057
01058 do {
01059 bsize = tsize = hbuffer_size;
01060 memset(ybuffer, 0, bsize);
01061 status = ::hs_read(event_id, (DWORD)start_time, (DWORD)end_time, (DWORD)interval,
01062 (char*)tag_name[i], var_index[i],
01063 tbuffer, &tsize,
01064 ybuffer, &bsize,
01065 &tid, &n_point);
01066
01067 if (fDebug)
01068 printf("hs_read %d \'%s\' [%d] returned %d, %d entries\n", event_id, tag_name[i], var_index[i], status, n_point);
01069
01070 if (status == HS_TRUNCATED) {
01071 hbuffer_size *= 2;
01072 tbuffer = (DWORD*)realloc(tbuffer, hbuffer_size);
01073 assert(tbuffer);
01074 ybuffer = (char*)realloc(ybuffer, hbuffer_size);
01075 assert(ybuffer);
01076 }
01077
01078 } while (status == HS_TRUNCATED);
01079
01080 st[i] = status;
01081
01082 time_t* x = (time_t*)malloc(n_point*sizeof(time_t));
01083 assert(x);
01084 double* y = (double*)malloc(n_point*sizeof(double));
01085 assert(x);
01086
01087 time_buffer[i] = x;
01088 data_buffer[i] = y;
01089
01090 int n_vp = 0;
01091
01092 for (unsigned j = 0; j < n_point; j++) {
01093 x[n_vp] = tbuffer[j];
01094
01095
01096 switch (tid) {
01097 case TID_BYTE:
01098 y[n_vp] = *(((BYTE *) ybuffer) + j);
01099 break;
01100 case TID_SBYTE:
01101 y[n_vp] = *(((char *) ybuffer) + j);
01102 break;
01103 case TID_CHAR:
01104 y[n_vp] = *(((char *) ybuffer) + j);
01105 break;
01106 case TID_WORD:
01107 y[n_vp] = *(((WORD *) ybuffer) + j);
01108 break;
01109 case TID_SHORT:
01110 y[n_vp] = *(((short *) ybuffer) + j);
01111 break;
01112 case TID_DWORD:
01113 y[n_vp] = *(((DWORD *) ybuffer) + j);
01114 break;
01115 case TID_INT:
01116 y[n_vp] = *(((INT *) ybuffer) + j);
01117 break;
01118 case TID_BOOL:
01119 y[n_vp] = *(((BOOL *) ybuffer) + j);
01120 break;
01121 case TID_FLOAT:
01122 y[n_vp] = *(((float *) ybuffer) + j);
01123 break;
01124 case TID_DOUBLE:
01125 y[n_vp] = *(((double *) ybuffer) + j);
01126 break;
01127 }
01128
01129 n_vp++;
01130 }
01131
01132 num_entries[i] = n_vp;
01133 }
01134
01135 if (ybuffer)
01136 free(ybuffer);
01137 if (tbuffer)
01138 free(tbuffer);
01139
01140 return HS_SUCCESS;
01141 }
01142 };
01143
01144 MidasHistoryInterface* MakeMidasHistory()
01145 {
01146
01147 static MidasHistory* gh = NULL;
01148 if (!gh)
01149 gh = new MidasHistory;
01150 return gh;
01151 }
01152
01153