history_sql.cxx File Reference

Go to the source code of this file.

Data Structures

class  SqlBase
class  SqlDebug
struct  Tag
struct  Event
struct  IndexEntryTag
struct  IndexEntry
class  SqlHistory

Defines

#define STRLCPY(dst, src)   strlcpy((dst), (src), sizeof(dst))
#define FREE(x)   { if (x) free(x); (x) = NULL; }

Functions

static const char * midasTypeName (int tid)
static const char * midas2sqlType (int tid)
static int sql2midasType (const char *name)
static bool isCompatible (int tid, const char *sqlType)
static void PrintTags (int ntags, const TAG tags[])
int WriteEvent (SqlBase *sql, Event *e, time_t t, const char *buf, int size)
static std::string MidasNameToSqlName (const char *s)
static void PrintIndex ()
static IndexEntryFindIndexByTableName (const char *table_name)
static IndexEntryFindIndexByEventName (const char *event_name)
static IndexEntryTagFindIndexByTagName (IndexEntry *ie, const char *tag_name)
static IndexEntryTagFindIndexByColumnName (IndexEntry *ie, const char *column_name)
static int ReadIndex (SqlBase *sql, const char *event_name)
MidasHistoryInterfaceMakeMidasHistorySqlDebug ()

Variables

static const int tid_size []
static const char * tid_name []
static const char * sql_type_pgsql []
static const char * sql_type_mysql []
static const char ** sql_type = NULL
std::vector< IndexEntry * > gHistoryIndex
static int gHaveIndex = true
static int gHaveIndexAll = false
static int gTrace = 0


Define Documentation

#define FREE (  )     { if (x) free(x); (x) = NULL; }

Definition at line 34 of file history_sql.cxx.

#define STRLCPY ( dst,
src   )     strlcpy((dst), (src), sizeof(dst))

Definition at line 33 of file history_sql.cxx.


Function Documentation

static IndexEntryTag* FindIndexByColumnName ( IndexEntry ie,
const char *  column_name 
) [static]

Definition at line 995 of file history_sql.cxx.

Referenced by SqlHistory::hs_get_tags().

00996 {
00997    for (unsigned i=0; i<ie->tags.size(); i++)
00998       if (equal_ustring(ie->tags[i].column_name.c_str(), column_name)) {
00999          return &ie->tags[i];
01000       }
01001    return NULL;
01002 }

static IndexEntry* FindIndexByEventName ( const char *  event_name  )  [static]

Definition at line 977 of file history_sql.cxx.

Referenced by SqlHistory::hs_define_event(), SqlHistory::hs_get_tags(), SqlHistory::hs_read(), and ReadIndex().

00978 {
00979    for (unsigned i=0; i<gHistoryIndex.size(); i++)
00980       if (equal_ustring(gHistoryIndex[i]->event_name.c_str(), event_name)) {
00981          return gHistoryIndex[i];
00982       }
00983    return NULL;
00984 }

static IndexEntry* FindIndexByTableName ( const char *  table_name  )  [static]

Definition at line 968 of file history_sql.cxx.

Referenced by SqlHistory::hs_get_events().

00969 {
00970    for (unsigned i=0; i<gHistoryIndex.size(); i++)
00971       if (equal_ustring(gHistoryIndex[i]->table_name.c_str(), table_name)) {
00972          return gHistoryIndex[i];
00973       }
00974    return NULL;
00975 }

static IndexEntryTag* FindIndexByTagName ( IndexEntry ie,
const char *  tag_name 
) [static]

Definition at line 986 of file history_sql.cxx.

Referenced by SqlHistory::hs_define_event(), and SqlHistory::hs_read().

00987 {
00988    for (unsigned i=0; i<ie->tags.size(); i++)
00989       if (equal_ustring(ie->tags[i].tag_name.c_str(), tag_name)) {
00990          return &ie->tags[i];
00991       }
00992    return NULL;
00993 }

static bool isCompatible ( int  tid,
const char *  sqlType 
) [static]

Definition at line 153 of file history_sql.cxx.

00154 {
00155    if (0)
00156       printf("compare types midas \'%s\'=\'%s\' and sql \'%s\'\n", midasTypeName(tid), midas2sqlType(tid), sqlType);
00157 
00158    if (sql2midasType(sqlType) == tid)
00159       return true;
00160 
00161    if (strcasecmp(midas2sqlType(tid), sqlType) == 0)
00162       return true;
00163 
00164    // permit writing FLOAT into DOUBLE
00165    if (tid==TID_FLOAT && strcmp(sqlType, "double")==0)
00166       return true;
00167 
00168    // T2K quirk!
00169    // permit writing BYTE into signed tinyint
00170    if (tid==TID_BYTE && strcmp(sqlType, "tinyint")==0)
00171       return true;
00172 
00173    // T2K quirk!
00174    // permit writing WORD into signed tinyint
00175    if (tid==TID_WORD && strcmp(sqlType, "tinyint")==0)
00176       return true;
00177 
00178    return false;
00179 }

MidasHistoryInterface* MakeMidasHistorySqlDebug (  ) 

Definition at line 2075 of file history_sql.cxx.

Referenced by open_history().

02076 {
02077    return new SqlHistory(new SqlDebug());
02078 }

static const char* midas2sqlType ( int  tid  )  [static]

Definition at line 137 of file history_sql.cxx.

00138 {
00139    assert(tid>=0);
00140    assert(tid<15);
00141    return sql_type[tid];
00142 }

static std::string MidasNameToSqlName ( const char *  s  )  [static]

Definition at line 923 of file history_sql.cxx.

Referenced by SqlHistory::hs_define_event().

00924 {
00925    std::string out;
00926 
00927    for (int i=0; s[i]!=0; i++) {
00928       char c = s[i];
00929       if (isalpha(c) || isdigit(c))
00930          out += tolower(c);
00931       else
00932          out += '_';
00933    }
00934    
00935    return out;
00936 }

static const char* midasTypeName ( int  tid  )  [static]

Definition at line 130 of file history_sql.cxx.

00131 {
00132    assert(tid>=0);
00133    assert(tid<15);
00134    return tid_name[tid];
00135 }

static void PrintIndex (  )  [static]

Definition at line 956 of file history_sql.cxx.

00957 {
00958    for (unsigned i=0; i<gHistoryIndex.size(); i++) {
00959       IndexEntry *e = gHistoryIndex[i];
00960 
00961       printf("entry %d: [%s] [%s], time %d, tags\n", i, e->event_name.c_str(), e->table_name.c_str(), e->timestamp);
00962 
00963       for (unsigned j=0; j<e->tags.size(); j++)
00964          printf("  tag %d: [%s] [%s], time %d\n", j, e->tags[j].tag_name.c_str(), e->tags[j].column_name.c_str(), e->tags[j].timestamp);
00965    }
00966 }

static void PrintTags ( int  ntags,
const TAG  tags[] 
) [static]

Definition at line 817 of file history_sql.cxx.

00818 {
00819    for (int i=0; i<ntags; i++)
00820       printf("tag %d: %s %s[%d]\n", i, midasTypeName(tags[i].type), tags[i].name, tags[i].n_data);
00821 }

static int ReadIndex ( SqlBase sql,
const char *  event_name 
) [static]

Definition at line 1009 of file history_sql.cxx.

Referenced by SqlHistory::hs_define_event(), SqlHistory::hs_get_events(), SqlHistory::hs_get_tags(), SqlHistory::hs_read(), and SqlHistory::hs_read_old_style().

01010 {
01011    if (gTrace)
01012       printf("ReadIndex [%s]\n", event_name);
01013 
01014    if (!gHaveIndex)
01015       return HS_FILE_ERROR;
01016 
01017    if (gHaveIndexAll)
01018       return HS_SUCCESS;
01019 
01020    if (gTrace)
01021       printf("ReadIndex: reading index for event [%s]\n", event_name);
01022 
01023    //event_name = NULL;
01024 
01025    char cmd[256];
01026 
01027    if (event_name)
01028       sprintf(cmd, "SELECT event_name, table_name, tag_name, column_name, itimestamp FROM _history_index where event_name=\'%s\';", event_name);
01029    else
01030       sprintf(cmd, "SELECT event_name, table_name, tag_name, column_name, itimestamp FROM _history_index;");
01031    
01032    int status = sql->Exec(cmd);
01033 
01034    if (status == DB_NO_KEY) {
01035       gHaveIndex = false;
01036       return HS_FILE_ERROR;
01037    }
01038    
01039    if (gTrace) {
01040       printf("ReadIndex: event %s, Read status %d, nrows: %d\n",
01041              event_name,
01042              status,
01043              sql->GetNumRows());
01044    }
01045    
01046    if (status != SUCCESS)
01047       return HS_FILE_ERROR;
01048    
01049    if (sql->GetNumRows() == 0) {
01050       sql->Done();
01051       return HS_FILE_ERROR;
01052    }
01053    
01054    int nrows = sql->GetNumRows();
01055    int ncols = sql->GetNumColumns();
01056    
01057    if (nrows == 0)
01058       return HS_SUCCESS;
01059    
01060    if (gTrace)
01061       printf("ReadIndex: event %s, nrows: %d, ncols: %d\n",
01062              event_name,
01063              nrows, ncols);
01064    
01065    if (nrows < 0)
01066       return HS_FILE_ERROR;
01067    
01068    if (ncols < 1)
01069       return HS_FILE_ERROR;
01070    
01071    /* Loop through the rows in the result-set */
01072    while (1) {
01073       status = sql->Fetch();
01074       if (status != DB_SUCCESS)
01075          break;
01076 
01077       std::string xevent_name  = sql->GetColumn(1);
01078 
01079       const char* p = sql->GetColumn(2);
01080       if (p) { // table declaration
01081          std::string xtable_name  = p;
01082          std::string xtimestamp   = sql->GetColumn(5);
01083          int timestamp = atoi(xtimestamp.c_str());
01084 
01085          IndexEntry* ie = FindIndexByEventName(xevent_name.c_str());
01086          if (!ie) {
01087             ie = new IndexEntry;
01088             gHistoryIndex.push_back(ie);
01089             ie->timestamp = timestamp - 1; // make sure we update this entry
01090          }
01091 
01092          if (timestamp > ie->timestamp) {
01093             ie->event_name = xevent_name;
01094             ie->table_name = xtable_name;
01095             ie->timestamp  = timestamp;
01096          }
01097 
01098          //printf("%s %s %s %s %s [%s]\n", xevent_name.c_str(), xtable_name.c_str(), "???", "???", xtimestamp.c_str(), p);
01099          continue;
01100       }
01101          
01102       p = sql->GetColumn(3);
01103       if (p) { // tag declaration
01104          std::string xtag_name    = p;
01105          std::string xcolumn_name = sql->GetColumn(4);
01106          std::string xtimestamp   = sql->GetColumn(5);
01107          int timestamp = atoi(xtimestamp.c_str());
01108 
01109          IndexEntry* ie = FindIndexByEventName(xevent_name.c_str());
01110          if (!ie) {
01111             ie = new IndexEntry;
01112             gHistoryIndex.push_back(ie);
01113             ie->timestamp = 0;
01114             ie->event_name = xevent_name;
01115          }
01116 
01117          bool found = false;
01118          for (unsigned j=0; j<ie->tags.size(); j++)
01119             if (ie->tags[j].tag_name == xtag_name) {
01120                if (timestamp > ie->tags[j].timestamp) {
01121                   ie->tags[j].timestamp = timestamp;
01122                   ie->tags[j].column_name = xcolumn_name;
01123                }
01124                found = true;
01125                break;
01126             }
01127 
01128          if (!found) {
01129             IndexEntryTag it;
01130             it.tag_name = xtag_name;
01131             it.column_name = xcolumn_name;
01132             it.timestamp  = timestamp;
01133             ie->tags.push_back(it);
01134          }
01135 
01136          //printf("%s %s %s %s %s\n", xevent_name.c_str(), "???", xtag_name.c_str(), xcolumn_name.c_str(), xtimestamp.c_str());
01137          continue;
01138       }
01139 
01140    }
01141 
01142    sql->Done();
01143 
01144    gHaveIndex = true;
01145 
01146    if (event_name == NULL)
01147       gHaveIndexAll = true;
01148 
01149    //PrintIndex();
01150 
01151    return HS_SUCCESS;
01152 }

static int sql2midasType ( const char *  name  )  [static]

Definition at line 144 of file history_sql.cxx.

00145 {
00146    for (int tid=0; tid<15; tid++)
00147       if (strcasecmp(name, sql_type[tid])==0)
00148          return tid;
00149    printf("sql2midasType: Cannot convert SQL data type \'%s\' to a MIDAS data type!\n", name);
00150    return 0;
00151 }

int WriteEvent ( SqlBase sql,
Event e,
time_t  t,
const char *  buf,
int  size 
)

Definition at line 823 of file history_sql.cxx.

00824 {
00825    //printf("event %d, time %s", rec.event_id, ctime(&t));
00826 
00827    int n  = e->tags.size();
00828    
00829    std::string tags;
00830    std::string values;
00831    
00832    //if (n>0)
00833    //  printf(" %s", ctime(&t));
00834    
00835    for (int i=0; i<n; i++) {
00836       const Tag*t = &e->tags[i];
00837       
00838       if (t) {
00839          int offset = t->offset;
00840          void* ptr = (void*)(buf+offset);
00841 
00842          int arraySize = t->tag.n_data;
00843          
00844          for (int j=0; j<arraySize; j++) {
00845             tags   += ", ";
00846             values += ", ";
00847             
00848             if (arraySize <= 1)
00849                tags += t->column_name;
00850             else {
00851                tags += t->column_name;
00852                char s[256];
00853                sprintf(s,"_%d", j);
00854                tags += s;
00855             }
00856                 
00857             char s[1024];
00858             
00859             switch (t->tag.type) {
00860             default:
00861                sprintf(s, "unknownType%d", t->tag.type);
00862                break;
00863             case 1: /* BYTE */
00864                sprintf(s, "%u",((uint8_t*)ptr)[j]);
00865                break;
00866             case 2: /* SBYTE */
00867                sprintf(s, "%d",((int8_t*)ptr)[j]);
00868                break;
00869             case 3: /* CHAR */
00870                sprintf(s, "\'%c\'",((char*)ptr)[j]);
00871                break;
00872             case 4: /* WORD */
00873                sprintf(s, "%u",((uint16_t*)ptr)[j]);
00874                break;
00875             case 5: /* SHORT */
00876                sprintf(s, "%d",((int16_t*)ptr)[j]);
00877                break;
00878             case 6: /* DWORD */
00879                sprintf(s, "%u",((uint32_t*)ptr)[j]);
00880                break;
00881             case 7: /* INT */
00882                sprintf(s, "%d",((int32_t*)ptr)[j]);
00883                break;
00884             case 8: /* BOOL */
00885                sprintf(s, "%u",((uint32_t*)ptr)[j]);
00886                break;
00887             case 9: /* FLOAT */
00888                sprintf(s, "\'%.8g\'",((float*)ptr)[j]);
00889                break;
00890             case 10: /* DOUBLE */
00891                sprintf(s, "\'%.16g\'",((double*)ptr)[j]);
00892                     break;
00893             }
00894             
00895             values += s;
00896          }
00897       }
00898    }
00899 
00900    // 2001-02-16 20:38:40.1
00901    char s[1024];
00902    strftime(s,sizeof(s)-1,"%Y-%m-%d %H:%M:%S.0",localtime(&t));
00903    
00904    char sss[102400];
00905    sprintf(sss, "INSERT INTO %s (_t_time, _i_time%s) VALUES (\'%s\', \'%d\'%s);",
00906            e->table_name.c_str(),
00907            tags.c_str(),
00908            s,
00909            (int)t,
00910            values.c_str());
00911 
00912    int status = sql->Exec(sss);
00913    
00914    if (status != DB_SUCCESS) {
00915       return status;
00916    }
00917 
00918    return HS_SUCCESS;
00919 }


Variable Documentation

int gHaveIndex = true [static]

Definition at line 1004 of file history_sql.cxx.

int gHaveIndexAll = false [static]

Definition at line 1005 of file history_sql.cxx.

std::vector<IndexEntry*> gHistoryIndex

Definition at line 954 of file history_sql.cxx.

int gTrace = 0 [static]

Definition at line 1007 of file history_sql.cxx.

const char** sql_type = NULL [static]

Definition at line 128 of file history_sql.cxx.

const char* sql_type_mysql[] [static]

Initial value:

 {
   "xxxINVALIDxxxNULL", 
   "tinyint unsigned",  
   "tinyint",           
   "char",              
   "smallint unsigned", 
   "smallint",          
   "integer unsigned",  
   "integer",           
   "tinyint",           
   "float",             
   "double",            
   "tinyint unsigned",  
   "VARCHAR",           
   "xxxINVALIDxxxARRAY",
   "xxxINVALIDxxxSTRUCT",
   "xxxINVALIDxxxKEY",
   "xxxINVALIDxxxLINK"
}

Definition at line 104 of file history_sql.cxx.

const char* sql_type_pgsql[] [static]

Initial value:

 {
   "xxxINVALIDxxxNULL", 
   "SMALLINT",  
   "SMALLINT",  
   "CHAR(1)",   
   "SMALLINT",  
   "SMALLINT",  
   "INTEGER",   
   "INTEGER",   
   "BOOL",      
   "FLOAT(53)", 
   "FLOAT(53)", 
   "SMALLINT",  
   "VARCHAR",   
   "xxxINVALIDxxxARRAY",
   "xxxINVALIDxxxSTRUCT",
   "xxxINVALIDxxxKEY",
   "xxxINVALIDxxxLINK"
}

Definition at line 84 of file history_sql.cxx.

const char* tid_name[] [static]

Initial value:

 {
   "NULL",
   "BYTE",
   "SBYTE",
   "CHAR",
   "WORD",
   "SHORT",
   "DWORD",
   "INT",
   "BOOL",
   "FLOAT",
   "DOUBLE",
   "BITFIELD",
   "STRING",
   "ARRAY",
   "STRUCT",
   "KEY",
   "LINK"
}

Definition at line 63 of file history_sql.cxx.

const int tid_size[] [static]

Initial value:

 {
   0,                           
   1,                           
   1,                           
   1,                           
   2,                           
   2,                           
   4,                           
   4,                           
   4,                           
   4,                           
   8,                           
   1,                           
   0,                           
   0,                           
   0,                           
   0,                           
   0                            
}

Definition at line 42 of file history_sql.cxx.


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