MIDAS
Loading...
Searching...
No Matches
history_odbc.cxx File Reference
#include "midas.h"
#include "msystem.h"
#include <vector>
#include <string>
#include "history.h"
#include "mstrlcpy.h"
Include dependency graph for history_odbc.cxx:

Go to the source code of this file.

Classes

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

Macros

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

Functions

static const charmidasTypeName (int tid)
 
static const charmidas2sqlType (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 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)
 
MidasHistoryInterfaceMakeMidasHistoryODBC ()
 
MidasHistoryInterfaceMakeMidasHistorySqlDebug ()
 

Variables

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

Macro Definition Documentation

◆ FREE

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

Definition at line 28 of file history_odbc.cxx.

Function Documentation

◆ FindIndexByColumnName()

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

Definition at line 1006 of file history_odbc.cxx.

1007{
1008 for (unsigned i=0; i<ie->tags.size(); i++)
1009 if (equal_ustring(ie->tags[i].column_name.c_str(), column_name)) {
1010 return &ie->tags[i];
1011 }
1012 return NULL;
1013}
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3201
INT i
Definition mdump.cxx:32
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindIndexByEventName()

static IndexEntry * FindIndexByEventName ( const char event_name)
static

Definition at line 988 of file history_odbc.cxx.

989{
990 for (unsigned i=0; i<gHistoryIndex.size(); i++)
991 if (equal_ustring(gHistoryIndex[i]->event_name.c_str(), event_name)) {
992 return gHistoryIndex[i];
993 }
994 return NULL;
995}
static std::vector< IndexEntry * > gHistoryIndex
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindIndexByTableName()

static IndexEntry * FindIndexByTableName ( const char table_name)
static

Definition at line 979 of file history_odbc.cxx.

980{
981 for (unsigned i=0; i<gHistoryIndex.size(); i++)
982 if (equal_ustring(gHistoryIndex[i]->table_name.c_str(), table_name)) {
983 return gHistoryIndex[i];
984 }
985 return NULL;
986}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindIndexByTagName()

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

Definition at line 997 of file history_odbc.cxx.

998{
999 for (unsigned i=0; i<ie->tags.size(); i++)
1000 if (equal_ustring(ie->tags[i].tag_name.c_str(), tag_name)) {
1001 return &ie->tags[i];
1002 }
1003 return NULL;
1004}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ isCompatible()

static bool isCompatible ( int  tid,
const char sqlType 
)
static

Definition at line 153 of file history_odbc.cxx.

154{
155#if 0
156 printf("compare types midas \'%s\'=\'%s\' and sql \'%s\'\n", midasTypeName(tid), midas2sqlType(tid), sqlType);
157#endif
158
159 if (sql2midasType(sqlType) == tid)
160 return true;
161
162 if (strcasecmp(midas2sqlType(tid), sqlType) == 0)
163 return true;
164
165 // permit writing FLOAT into DOUBLE
166 if (tid==TID_FLOAT && strcmp(sqlType, "double")==0)
167 return true;
168
169 // T2K quirk!
170 // permit writing BYTE into signed tinyint
171 if (tid==TID_UINT8 && strcmp(sqlType, "tinyint")==0)
172 return true;
173
174 // T2K quirk!
175 // permit writing WORD into signed tinyint
176 if (tid==TID_UINT16 && strcmp(sqlType, "tinyint")==0)
177 return true;
178
179 return false;
180}
#define TID_UINT8
Definition midas.h:328
#define TID_UINT16
Definition midas.h:333
#define TID_FLOAT
Definition midas.h:341
static int sql2midasType(const char *name)
static const char * midasTypeName(int tid)
static const char * midas2sqlType(int tid)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeMidasHistoryODBC()

MidasHistoryInterface * MakeMidasHistoryODBC ( )

Definition at line 2150 of file history_odbc.cxx.

2151{
2152 return NULL;
2153}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeMidasHistorySqlDebug()

MidasHistoryInterface * MakeMidasHistorySqlDebug ( )

Definition at line 2156 of file history_odbc.cxx.

2157{
2158 return new SqlHistory(new SqlDebug());
2159}
Here is the caller graph for this function:

◆ midas2sqlType()

static const char * midas2sqlType ( int  tid)
static

Definition at line 137 of file history_odbc.cxx.

138{
139 assert(tid>=0);
140 assert(tid<15);
141 return sql_type[tid];
142}
static const char ** sql_type
Here is the caller graph for this function:

◆ MidasNameToSqlName()

static std::string MidasNameToSqlName ( const char s)
static

Definition at line 932 of file history_odbc.cxx.

933{
934 std::string out;
935
936 for (int i=0; s[i]!=0; i++) {
937 char c = s[i];
938 if (isalpha(c) || isdigit(c))
939 out += tolower(c);
940 else
941 out += '_';
942 }
943
944 return out;
945}
char c
Definition system.cxx:1310
Here is the call graph for this function:
Here is the caller graph for this function:

◆ midasTypeName()

static const char * midasTypeName ( int  tid)
static

Definition at line 130 of file history_odbc.cxx.

131{
132 assert(tid>=0);
133 assert(tid<15);
134 return tid_name[tid];
135}
static const char * tid_name[]
Here is the caller graph for this function:

◆ PrintTags()

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

Definition at line 824 of file history_odbc.cxx.

825{
826 for (int i=0; i<ntags; i++)
827 printf("tag %d: %s %s[%d]\n", i, midasTypeName(tags[i].type), tags[i].name, tags[i].n_data);
828}
INT type
Definition mana.cxx:269
#define name(x)
Definition midas_macro.h:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ReadIndex()

static int ReadIndex ( SqlBase sql,
const char event_name 
)
static

Definition at line 1020 of file history_odbc.cxx.

1021{
1022 if (gTrace)
1023 printf("ReadIndex [%s]\n", event_name);
1024
1025 if (!gHaveIndex)
1026 return HS_FILE_ERROR;
1027
1028 if (gHaveIndexAll)
1029 return HS_SUCCESS;
1030
1031 if (gTrace)
1032 printf("ReadIndex: reading index for event [%s]\n", event_name);
1033
1034 //event_name = NULL;
1035
1036 char cmd[256];
1037
1038 if (event_name)
1039 sprintf(cmd, "SELECT event_name, table_name, tag_name, column_name, itimestamp FROM _history_index where event_name=\'%s\';", event_name);
1040 else
1041 sprintf(cmd, "SELECT event_name, table_name, tag_name, column_name, itimestamp FROM _history_index;");
1042
1043 int status = sql->Exec(cmd);
1044
1045 if (status == DB_NO_KEY) {
1046 gHaveIndex = false;
1047 return HS_FILE_ERROR;
1048 }
1049
1050 if (gTrace) {
1051 printf("ReadIndex: event %s, Read status %d, nrows: %d\n",
1052 event_name,
1053 status,
1054 sql->GetNumRows());
1055 }
1056
1057 if (status != SUCCESS)
1058 return HS_FILE_ERROR;
1059
1060 if (sql->GetNumRows() == 0) {
1061 sql->Done();
1062 return HS_FILE_ERROR;
1063 }
1064
1065 int nrows = sql->GetNumRows();
1066 int ncols = sql->GetNumColumns();
1067
1068 if (nrows == 0)
1069 return HS_SUCCESS;
1070
1071 if (gTrace)
1072 printf("ReadIndex: event %s, nrows: %d, ncols: %d\n",
1073 event_name,
1074 nrows, ncols);
1075
1076 if (nrows < 0)
1077 return HS_FILE_ERROR;
1078
1079 if (ncols < 1)
1080 return HS_FILE_ERROR;
1081
1082 /* Loop through the rows in the result-set */
1083 while (1) {
1084 status = sql->Fetch();
1085 if (status != DB_SUCCESS)
1086 break;
1087
1088 std::string xevent_name = sql->GetColumn(1);
1089
1090 const char* p = sql->GetColumn(2);
1091 if (p) { // table declaration
1092 std::string xtable_name = p;
1093 std::string xtimestamp = sql->GetColumn(5);
1094 int timestamp = atoi(xtimestamp.c_str());
1095
1097 if (!ie) {
1098 ie = new IndexEntry;
1099 gHistoryIndex.push_back(ie);
1100 ie->timestamp = timestamp - 1; // make sure we update this entry
1101 }
1102
1103 if (timestamp > ie->timestamp) {
1104 ie->event_name = xevent_name;
1105 ie->table_name = xtable_name;
1106 ie->timestamp = timestamp;
1107 }
1108
1109 //printf("%s %s %s %s %s [%s]\n", xevent_name.c_str(), xtable_name.c_str(), "???", "???", xtimestamp.c_str(), p);
1110 continue;
1111 }
1112
1113 p = sql->GetColumn(3);
1114 if (p) { // tag declaration
1115 std::string xtag_name = p;
1116 std::string xcolumn_name = sql->GetColumn(4);
1117 std::string xtimestamp = sql->GetColumn(5);
1118 int timestamp = atoi(xtimestamp.c_str());
1119
1121 if (!ie) {
1122 ie = new IndexEntry;
1123 gHistoryIndex.push_back(ie);
1124 ie->timestamp = 0;
1125 ie->event_name = xevent_name;
1126 }
1127
1128 bool found = false;
1129 for (unsigned j=0; j<ie->tags.size(); j++)
1130 if (ie->tags[j].tag_name == xtag_name) {
1131 if (timestamp > ie->tags[j].timestamp) {
1132 ie->tags[j].timestamp = timestamp;
1133 ie->tags[j].column_name = xcolumn_name;
1134 }
1135 found = true;
1136 break;
1137 }
1138
1139 if (!found) {
1142 it.column_name = xcolumn_name;
1143 it.timestamp = timestamp;
1144 ie->tags.push_back(it);
1145 }
1146
1147 //printf("%s %s %s %s %s\n", xevent_name.c_str(), "???", xtag_name.c_str(), xcolumn_name.c_str(), xtimestamp.c_str());
1148 continue;
1149 }
1150
1151 }
1152
1153 sql->Done();
1154
1155 gHaveIndex = true;
1156
1157 if (event_name == NULL)
1158 gHaveIndexAll = true;
1159
1160 //PrintIndex();
1161
1162 return HS_SUCCESS;
1163}
virtual int Fetch()=0
virtual const char * GetColumn(int icol)=0
virtual int Done()=0
virtual int Exec(const char *sql)=0
virtual int GetNumColumns()=0
virtual int GetNumRows()=0
#define DB_SUCCESS
Definition midas.h:631
#define DB_NO_KEY
Definition midas.h:642
#define HS_SUCCESS
Definition midas.h:727
#define HS_FILE_ERROR
Definition midas.h:728
#define SUCCESS
Definition mcstd.h:54
static int gHaveIndexAll
static int gTrace
static IndexEntry * FindIndexByEventName(const char *event_name)
static int gHaveIndex
INT j
Definition odbhist.cxx:40
DWORD status
Definition odbhist.cxx:39
int timestamp
std::string tag_name
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sql2midasType()

static int sql2midasType ( const char name)
static

Definition at line 144 of file history_odbc.cxx.

145{
146 for (int tid=0; tid<15; tid++)
147 if (strcasecmp(name, sql_type[tid])==0)
148 return tid;
149 printf("sql2midasType: Cannot convert SQL data type \'%s\' to a MIDAS data type!\n", name);
150 return 0;
151}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteEvent()

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

Definition at line 830 of file history_odbc.cxx.

831{
832 //printf("event %d, time %s", rec.event_id, ctime(&t));
833
834 int n = e->tags.size();
835
836 std::string tags;
837 std::string values;
838
839 //if (n>0)
840 // printf(" %s", ctime(&t));
841
842 for (int i=0; i<n; i++) {
843 const Tag*t = &e->tags[i];
844
845 if (t) {
846 int offset = t->offset;
847 void* ptr = (void*)(buf+offset);
848
849 int arraySize = t->tag.n_data;
850
851 for (int j=0; j<arraySize; j++) {
852 tags += ", ";
853 values += ", ";
854
855 if (arraySize <= 1)
856 tags += t->column_name;
857 else {
858 tags += t->column_name;
859 char s[256];
860 sprintf(s,"_%d", j);
861 tags += s;
862 }
863
864 char s[1024];
865
866 switch (t->tag.type) {
867 default:
868 sprintf(s, "unknownType%d", t->tag.type);
869 break;
870 case 1: /* BYTE */
871 sprintf(s, "%u",((unsigned char*)ptr)[j]);
872 break;
873 case 2: /* SBYTE */
874 sprintf(s, "%d",((signed char*)ptr)[j]);
875 break;
876 case 3: /* CHAR */
877 sprintf(s, "\'%c\'",((char*)ptr)[j]);
878 break;
879 case 4: /* WORD */
880 sprintf(s, "%u",((unsigned short*)ptr)[j]);
881 break;
882 case 5: /* SHORT */
883 sprintf(s, "%d",((signed short*)ptr)[j]);
884 break;
885 case 6: /* DWORD */
886 sprintf(s, "%u",((unsigned int*)ptr)[j]);
887 break;
888 case 7: /* INT */
889 sprintf(s, "%d",((int*)ptr)[j]);
890 break;
891 case 8: /* BOOL */
892 sprintf(s, "%u",((unsigned int*)ptr)[j]);
893 break;
894 case 9: /* FLOAT */
895 sprintf(s, "\'%.8g\'",((float*)ptr)[j]);
896 break;
897 case 10: /* DOUBLE */
898 sprintf(s, "\'%.16g\'",((double*)ptr)[j]);
899 break;
900 }
901
902 values += s;
903 }
904 }
905 }
906
907 // 2001-02-16 20:38:40.1
908 struct tm tms;
909 localtime_r(&t, &tms); // somebody must call tzset() before this
910 char s[1024];
911 strftime(s,sizeof(s)-1,"%Y-%m-%d %H:%M:%S.0",&tms);
912
913 char sss[102400];
914 sprintf(sss, "INSERT INTO %s (_t_time, _i_time%s) VALUES (\'%s\', \'%d\'%s);",
915 e->table_name.c_str(),
916 tags.c_str(),
917 s,
918 (int)t,
919 values.c_str());
920
921 int status = sql->Exec(sss);
922
923 if (status != DB_SUCCESS) {
924 return status;
925 }
926
927 return HS_SUCCESS;
928}
DWORD n[4]
Definition mana.cxx:247
static int offset
Definition mgd.cxx:1500
MUTEX_T * tm
Definition odbedit.cxx:39
DWORD type
Definition midas.h:1236
DWORD n_data
Definition midas.h:1237
int offset
std::string column_name
static double e(void)
Definition tinyexpr.c:136
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ gHaveIndex

int gHaveIndex = true
static

Definition at line 1015 of file history_odbc.cxx.

◆ gHaveIndexAll

int gHaveIndexAll = false
static

Definition at line 1016 of file history_odbc.cxx.

◆ gHistoryIndex

std::vector<IndexEntry*> gHistoryIndex
static

Definition at line 963 of file history_odbc.cxx.

◆ gTrace

int gTrace = 0
static

Definition at line 1018 of file history_odbc.cxx.

◆ sql_type

const char** sql_type = NULL
static

Definition at line 128 of file history_odbc.cxx.

◆ sql_type_mysql

const char* sql_type_mysql[]
static
Initial value:
= {
"xxxINVALIDxxxNULL",
"tinyint unsigned",
"tinyint",
"char",
"smallint unsigned",
"smallint",
"integer unsigned",
"integer",
"tinyint",
"float",
"double",
"integer unsigned",
"VARCHAR",
"xxxINVALIDxxxARRAY",
"xxxINVALIDxxxSTRUCT",
"xxxINVALIDxxxKEY",
"xxxINVALIDxxxLINK"
}

Definition at line 104 of file history_odbc.cxx.

104 {
105 "xxxINVALIDxxxNULL", // TID_NULL
106 "tinyint unsigned", // TID_UINT8
107 "tinyint", // TID_INT8
108 "char", // TID_CHAR
109 "smallint unsigned", // TID_UINT16
110 "smallint", // TID_INT16
111 "integer unsigned", // TID_UINT32
112 "integer", // TID_INT32
113 "tinyint", // TID_BOOL
114 "float", // TID_FLOAT
115 "double", // TID_DOUBLE
116 "integer unsigned", // TID_BITFIELD
117 "VARCHAR", // TID_STRING
118 "xxxINVALIDxxxARRAY",
119 "xxxINVALIDxxxSTRUCT",
120 "xxxINVALIDxxxKEY",
121 "xxxINVALIDxxxLINK"
122};

◆ tid_name

const char* tid_name[]
static
Initial value:
= {
"NULL",
"UINT8",
"INT8",
"CHAR",
"UINT16",
"INT16",
"UINT32",
"INT32",
"BOOL",
"FLOAT",
"DOUBLE",
"BITFIELD",
"STRING",
"ARRAY",
"STRUCT",
"KEY",
"LINK",
"INT64",
"UINT64"
}

Definition at line 59 of file history_odbc.cxx.

59 {
60 "NULL",
61 "UINT8",
62 "INT8",
63 "CHAR",
64 "UINT16",
65 "INT16",
66 "UINT32",
67 "INT32",
68 "BOOL",
69 "FLOAT",
70 "DOUBLE",
71 "BITFIELD",
72 "STRING",
73 "ARRAY",
74 "STRUCT",
75 "KEY",
76 "LINK",
77 "INT64",
78 "UINT64"
79};

◆ tid_size

const int tid_size[]
static
Initial value:
= {
0,
1,
1,
1,
2,
2,
4,
4,
4,
4,
8,
4,
0,
0,
0,
0,
0,
8,
8
}

Definition at line 36 of file history_odbc.cxx.

36 {
37 0, /* tid == 0 not defined */
38 1, /* TID_UINT8 unsigned byte 0 255 */
39 1, /* TID_INT8 signed byte -128 127 */
40 1, /* TID_CHAR single character 0 255 */
41 2, /* TID_UINT16 two bytes 0 65535 */
42 2, /* TID_INT16 signed word -32768 32767 */
43 4, /* TID_UINT32 four bytes 0 2^32-1 */
44 4, /* TID_INT32 signed dword -2^31 2^31-1 */
45 4, /* TID_BOOL four bytes bool 0 1 */
46 4, /* TID_FLOAT 4 Byte float format */
47 8, /* TID_DOUBLE 8 Byte float format */
48 4, /* TID_BITFIELD 32 Bits Bitfield 00000... 11111... */
49 0, /* TID_STRING zero terminated string */
50 0, /* TID_ARRAY variable length array of unkown type */
51 0, /* TID_STRUCT C structure */
52 0, /* TID_KEY key in online database */
53 0, /* TID_LINK link in online database */
54 8, /* TID_INT64 8 bytes int -2^63 2^63-1 */
55 8 /* TID_UINT64 8 bytes unsigned int 0 2^64-1 */
56};