history_midas.cxx

Go to the documentation of this file.
00001 /********************************************************************\
00002 
00003   Name:         history_midas.cxx
00004   Created by:   Konstantin Olchanski
00005 
00006   Contents:     Interface class for traditional MIDAS history
00007 
00008   $Id$
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       //printf("Found event %d, event [%s] name [%s], looking for [%s][%s]\n", evid, event_name, buf, evname, tagname);
00074 
00075       if (!equal_ustring((char *)evname, buf))
00076          continue;
00077 
00078       status = hs_get_tags(ltime, evid, event_name, &ntags, &tags);
00079 
00080       //printf("status %d, ntags %d\n", status, ntags);
00081 
00082       //status = hs_get_tags(ltime, evid, event_name, &ntags, &tags);
00083 
00084       for (j=0; j<ntags; j++) {
00085          //printf("at %d [%s] looking for [%s]\n", j, tags[j].name, tagname);
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       //printf("Found event %d, name [%s], looking for [%s][%s]\n", evid, buf, evname, tagname);
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          //printf("at %d [%s] [%s] compare to [%s]\n", j, buf, s, tagname);
00168 
00169          if (equal_ustring((char *)tagname, s)) {
00170             //printf("Found evid %d\n", evid);
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    //printf("Looking for event id for \'%s\'\n", name);
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          //printf("key \'%s\'\n", key.name);
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          //printf("status %d\n", status);
00218          assert(status == DB_SUCCESS);
00219 
00220          //printf("got %d \'%s\' looking for \'%s\'\n", evid, tmp, name);
00221 
00222          if (equal_ustring(name, tmp))
00223             return evid;
00224       }
00225    }
00226 
00227    int max_id = 100;
00228 
00229    // special event id for run transitions
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    /* not reached */
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       //printf("%d [%s] %d\n", i, pp, pplen);
00273       if (pplen > len)
00274          len = pplen;
00275       p += strlen(names+p) + 1;
00276    }
00277 
00278    num = i;
00279 
00280    len+=1; // space for string terminator '\0'
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() // ctor
00318    {
00319       fDebug = 0;
00320       fListSource = 0;
00321    }
00322 
00323    ~MidasHistory() // dtor
00324    {
00325       // empty
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       /* check dedicated history path */
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       /* select which list of events and variables to use */
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       /* by default "/History/ListSource" is set to zero, then use /History/Tags if available */
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       /* if "Tags" not present use "/History/Events" in conjunction with hs_get_tags() */
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       //printf("write event [%s] evid %d\n", event_name, event_id);
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       /* loop over equipment to display event name */
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          /* check history flag */
00453          size = sizeof(history);
00454          db_get_value(hDB, hKeyEq, "Common/Log history", &history, &size, TID_INT, TRUE);
00455     
00456          /* show event only if log history flag is on */
00457          if (history > 0) {
00458             KEY key;
00459             char *evname;
00460 
00461             /* get equipment name */
00462             db_get_key(hDB, hKeyEq, &key);
00463 
00464             evname = key.name;
00465 
00466             events->push_back(evname);
00467          
00468             //printf("event \'%s\'\n", evname);
00469          }
00470       }
00471    
00472       /* loop over history links to display event name */
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             //printf("event \'%s\'\n", evname);
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       /* loop over tags to display event names */
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          /* skip duplicated event names */
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          //printf("event \'%s\'\n", evname);
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       /* loop over tags to display event names */
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          /* get event name */
00578          db_get_key(hDB, hKeyEq, &key);
00579       
00580          //printf("key \'%s\'\n", key.name);
00581       
00582          if (key.type != TID_STRING)
00583             continue;
00584 
00585          /* parse event name in format: "event_id" or "event_id:var_name" */
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          /* skip duplicated event names */
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          //printf("event %d \'%s\'\n", event_id, evname);
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       /* use "/History/Tags" if available */
00665       DWORD event_id = get_variable_id_tags(event_name, tag_name);
00666       
00667       /* if no Tags, use "/History/Events" and hs_get_tags() to read definition from history files */
00668       if (event_id == 0)
00669          event_id = get_variable_id((DWORD)t, event_name, tag_name);
00670 
00671       /* special kludge because run transitions are not listed in /History/Events */
00672       if ((event_id == 0) && equal_ustring(event_name, "Run transitions")) {
00673          *pevid = 0;
00674          return HS_SUCCESS;
00675       }
00676       
00677       /* if nothing works, use hs_get_event_id() */
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       /* display variables for selected event */
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       /* go through variables for selected event */
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             /* get variable key */
00754             db_get_key(hDB, hKey, &varkey);
00755             n_names = 0;
00756          
00757             /* look for names */
00758             db_find_key(hDB, hKeyEq, "Settings/Names", &hKeyNames);
00759             single_names = (hKeyNames > 0);
00760             if (hKeyNames) {
00761                KEY key;
00762                /* get variables from names list */
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                   /* get variables from names list */
00771                   db_get_key(hDB, hKeyNames, &key);
00772                   n_names = key.num_values;
00773                }
00774             }
00775       
00776             if (hKeyNames) {
00777                int j;
00778 
00779                /* loop over array elements */
00780                for (j = 0; j < n_names; j++) {
00781                   int size;
00782                   /* get name #j */
00783                   size = NAME_LENGTH;
00784                   db_get_data_index(hDB, hKeyNames, var_name, &size, j, TID_STRING);
00785                
00786                   /* append variable key name for single name array */
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       /* loop over equipment to display event name */
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          /* get event name */
00870          status = db_get_key(hDB, hKey, &key);
00871          assert(status == DB_SUCCESS);
00872       
00873          /* parse event id */
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) { // old format of "/History/Tags"
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             /* loop over tags */
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                /* get event name */
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                //printf("Found %s, event %d (%s), tag (%s) array %d\n", key.name, event_id, event_name, var_name, array);
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          //printf("evid %d, name [%s]\n", event_id, buf);
00941 
00942          if (!equal_ustring(buf, event_name))
00943             continue;
00944 
00945          /* loop over tags */
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             //printf("index %d [%s]\n", j, buf);
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             //printf("Found %s, event %d, tag (%s) array %d, type %d\n", buf, event_id, var_name, array, ev_type);
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             /* convert data to float */
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 }; // end class
01143 
01144 MidasHistoryInterface* MakeMidasHistory()
01145 {
01146    // midas history is a singleton class
01147    static MidasHistory* gh = NULL;
01148    if (!gh)
01149       gh = new MidasHistory;
01150    return gh;
01151 }
01152 
01153 // end

Midas DOC Version 3.0.0 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Sergio Ballestrero - Suzannah Daviel - Doxygen - Peter Green - Qing Gu - Greg Hackman - Gertjan Hofman - Paul Knowles - Exaos Lee - Rudi Meier - Glenn Moloney - Dave Morris - John M O'Donnell - Konstantin Olchanski - Renee Poutissou - Tamsen Schurman - Andreas Suter - Jan M.Wouters - Piotr Adam Zolnierczuk