MIDAS
Loading...
Searching...
No Matches
history_common.cxx
Go to the documentation of this file.
1/********************************************************************\
2
3 Name: history_common.cxx
4 Created by: Konstantin Olchanski
5
6 Contents: History functions common to all history implementations
7
8\********************************************************************/
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <assert.h>
14
15#include <map>
16
17#include "midas.h"
18#include "msystem.h"
19#include "history.h"
20#include "mstrlcpy.h"
21
22int hs_get_history(HNDLE hDB, HNDLE hKey, int flags, int debug_flag, MidasHistoryInterface **mh)
23{
24 int status, size;
25 std::string type;
26 int active;
27 int debug;
28 KEY key;
29
30 *mh = NULL;
31
32 if (!hKey || (flags&HS_GET_DEFAULT)) {
33 status = hs_find_reader_channel(hDB, &hKey, debug_flag);
34 if (status != HS_SUCCESS)
35 return status;
36 }
37
39 assert(status == DB_SUCCESS);
40
41 if (strcasecmp(key.name, "image") == 0) {
42 if (debug_flag)
43 cm_msg(MINFO, "hs_get_history", "History channel \'IMAGE\' handled by image facility");
44 return DB_NO_KEY;
45 }
46
47 active = 0;
48 size = sizeof(active);
49 status = db_get_value(hDB, hKey, "Active", &active, &size, TID_BOOL, TRUE);
50 assert(status == DB_SUCCESS);
51
52 status = db_get_value_string(hDB, hKey, "Type", 0, &type, TRUE);
53 assert(status == DB_SUCCESS);
54
55 debug = 0;
56 size = sizeof(debug);
57 status = db_get_value(hDB, hKey, "Debug", &debug, &size, TID_INT, TRUE);
58 assert(status == DB_SUCCESS);
59
60 if (debug_flag)
61 printf("hs_get_history: see channel hkey %d, name \'%s\', active %d, type [%s], debug %d\n", hKey, key.name, active, type.c_str(), debug);
62
63 if (strcasecmp(type.c_str(), "MIDAS")==0) {
64
65 std::string tmp;
66 // create ODB "History dir"
67 db_get_value_string(hDB, hKey, "History dir", 0, &tmp, TRUE);
68
69 std::string path = cm_get_history_path(key.name);
70
71 int i;
72
73 i = 1;
74 size = sizeof(i);
75 status = db_get_value(hDB, 0, "/Logger/WriteFileHistory", &i, &size, TID_BOOL, FALSE);
76 if (status==DB_SUCCESS) {
77 cm_msg(MERROR, "hs_get_history", "mlogger ODB setting /Logger/WriteFileHistory is obsolete, please delete it. Use /Logger/History/MIDAS/Active instead");
78 if (i==0)
79 active = 0;
80 }
81
82 if (active || (flags & HS_GET_INACTIVE)) {
84 assert(*mh);
85
86 (*mh)->hs_set_debug(debug);
87
88 status = (*mh)->hs_connect(path.c_str());
89 if (status != HS_SUCCESS) {
90 cm_msg(MERROR, "hs_get_history", "Cannot connect to MIDAS history, status %d", status);
91 return status;
92 }
93
94 if (debug_flag)
95 cm_msg(MINFO, "hs_get_history", "Connected history channel \'%s\' type MIDAS history in \"%s\"", key.name, path.c_str());
96 }
97
98 } else if (strcasecmp(type.c_str(), "ODBC")==0) {
99
100 if (1) {
101 int i;
102
103 i = 0;
104 size = sizeof(i);
105 status = db_get_value(hDB, 0, "/Logger/ODBC_Debug", &i, &size, TID_INT, FALSE);
106 if (status==DB_SUCCESS) {
107 cm_msg(MERROR, "hs_get_history", "mlogger ODB setting /Logger/ODBC_Debug is obsolete, please delete it. Use /Logger/History/ODBC/Debug instead");
108 }
109
110 status = db_get_value(hDB, 0, "/History/ODBC_Debug", &i, &size, TID_INT, FALSE);
111 if (status==DB_SUCCESS) {
112 cm_msg(MERROR, "hs_get_history", "mhttpd ODB setting /History/ODBC_Debug is obsolete, please delete it. Use /Logger/History/ODBC/Debug instead");
113 }
114
115 std::string dsn;
116
117 status = db_get_value_string(hDB, 0, "/Logger/ODBC_DSN", 0, &dsn, FALSE);
118 if (status==DB_SUCCESS) {
119 cm_msg(MERROR, "hs_get_history", "mlogger ODB setting /Logger/ODBC_DSN is obsolete, please delete it. Use /Logger/History/ODBC/Writer_ODBC_DSN instead");
120 }
121
122 status = db_get_value_string(hDB, 0, "/History/ODBC_DSN", 0, &dsn, FALSE);
123 if (status==DB_SUCCESS) {
124 cm_msg(MERROR, "hs_get_history", "mhttpd ODB setting /History/ODBC_DSN is obsolete, please delete it. Use /Logger/History/ODBC/Reader_ODBC_DSN instead");
125 }
126 }
127
128 std::string writer_dsn = "history_writer";
129 std::string reader_dsn = "history_reader";
130
131 status = db_get_value_string(hDB, hKey, "Writer_ODBC_DSN", 0, &writer_dsn, TRUE);
132 assert(status == DB_SUCCESS);
133
134 status = db_get_value_string(hDB, hKey, "Reader_ODBC_DSN", 0, &reader_dsn, TRUE);
135 assert(status == DB_SUCCESS);
136
137 std::string dsn;
138
139 if (flags & HS_GET_READER)
140 dsn = reader_dsn;
141 else if (flags & HS_GET_WRITER)
142 dsn = writer_dsn;
143
144 if (active || (flags & HS_GET_INACTIVE)) {
145 if (debug == 2) {
147 } else if (dsn.length() > 1) {
149 }
150
151 if (*mh == NULL)
152 return HS_FILE_ERROR;
153
154 (*mh)->hs_set_debug(debug);
155
156 status = (*mh)->hs_connect(dsn.c_str());
157 if (status != HS_SUCCESS) {
158 cm_msg(MERROR, "hs_get_history", "Cannot connect to ODBC SQL driver \'%s\', status %d. Check .odbc.ini and MIDAS documentation", dsn.c_str(), status);
159 return status;
160 }
161
162 if (debug_flag)
163 cm_msg(MINFO, "hs_get_history", "Connected history channel \'%s\' type ODBC (MySQL), DSN \'%s\'", key.name, dsn.c_str());
164 }
165 } else if (strcasecmp(type.c_str(), "SQLITE")==0) {
166
167 std::string tmp;
168 // create ODB "History dir"
169 db_get_value_string(hDB, hKey, "History dir", 0, &tmp, TRUE);
170
171 std::string path = cm_get_history_path(key.name);
172
173 if (active || (flags & HS_GET_INACTIVE)) {
175 if (*mh == NULL)
176 return HS_FILE_ERROR;
177
178 (*mh)->hs_set_debug(debug);
179
180 status = (*mh)->hs_connect(path.c_str());
181 if (status != HS_SUCCESS) {
182 cm_msg(MERROR, "hs_get_history", "Cannot connect to SQLITE history, status %d, see messages", status);
183 return status;
184 }
185
186 if (debug_flag)
187 cm_msg(MINFO, "hs_get_history", "Connected history channel \'%s\' type SQLITE in \'%s\'", key.name, path.c_str());
188 }
189 } else if (strcasecmp(type.c_str(), "FILE")==0) {
190
191 std::string tmp;
192 // create ODB "History dir"
193 db_get_value_string(hDB, hKey, "History dir", 0, &tmp, TRUE);
194
195 std::string path = cm_get_history_path(key.name);
196
197 //printf("FILE path [%s], expt_path [%s], local History Dir [%s]\n", path.c_str(), expt_path, dir);
198
199 if (active || (flags & HS_GET_INACTIVE)) {
201 if (*mh == NULL)
202 return HS_FILE_ERROR;
203
204 (*mh)->hs_set_debug(debug);
205
206 status = (*mh)->hs_connect(path.c_str());
207 if (status != HS_SUCCESS) {
208 cm_msg(MERROR, "hs_get_history", "Cannot connect to FILE history, status %d, see messages", status);
209 return status;
210 }
211
212 if (debug_flag)
213 cm_msg(MINFO, "hs_get_history", "Connected history channel \'%s\' type FILE in \'%s\'", key.name, path.c_str());
214 }
215 } else if (strcasecmp(type.c_str(), "MYSQL")==0) {
216
217 std::string writer_dsn = "mysql_writer.txt";
218 std::string reader_dsn = "mysql_reader.txt";
219
220 status = db_get_value_string(hDB, hKey, "MYSQL Writer", 0, &writer_dsn, TRUE);
221 assert(status == DB_SUCCESS);
222
223 status = db_get_value_string(hDB, hKey, "MYSQL Reader", 0, &reader_dsn, TRUE);
224 assert(status == DB_SUCCESS);
225
226 std::string dsn;
227
228 if (flags & HS_GET_READER)
229 dsn = reader_dsn;
230 else if (flags & HS_GET_WRITER)
231 dsn = writer_dsn;
232
233 std::string path;
234
235 if (dsn[0] == DIR_SEPARATOR)
236 path = dsn;
237 else {
238 std::string expt_path = cm_get_path();
239
240 path = expt_path;
241 // normally expt_path has the trailing '/', see midas.c::cm_set_path()
242 if (path[path.length() - 1] != DIR_SEPARATOR)
243 path += DIR_SEPARATOR_STR;
244 path += dsn;
245 }
246
247 if (active || (flags & HS_GET_INACTIVE)) {
249 if (*mh == NULL)
250 return HS_FILE_ERROR;
251
252 (*mh)->hs_set_debug(debug);
253
254 status = (*mh)->hs_connect(path.c_str());
255 if (status != HS_SUCCESS) {
256 cm_msg(MERROR, "hs_get_history", "Cannot connect to MYSQL history, status %d", status);
257 return status;
258 }
259
260 if (debug_flag)
261 cm_msg(MINFO, "hs_get_history", "Connected history channel \'%s\' type MYSQL at \'%s\'", key.name,
262 path.c_str());
263 }
264 } else if (strcasecmp(type.c_str(), "PGSQL")==0) {
265
266 std::string writer_dsn = "pgsql_writer.txt";
267 std::string reader_dsn = "pgsql_reader.txt";
268
269 status = db_get_value_string(hDB, hKey, "PGSQL Writer", 0, &writer_dsn, TRUE);
270 assert(status == DB_SUCCESS);
271
272 status = db_get_value_string(hDB, hKey, "PGSQL Reader", 0, &reader_dsn, TRUE);
273 assert(status == DB_SUCCESS);
274
275 std::string dsn;
276
277 if (flags & HS_GET_READER)
278 dsn = reader_dsn;
279 else if (flags & HS_GET_WRITER)
280 dsn = writer_dsn;
281
282 std::string path;
283
284 if (dsn[0] == DIR_SEPARATOR)
285 path = dsn;
286 else {
287 std::string expt_path = cm_get_path();
288
289 path = expt_path;
290 // normally expt_path has the trailing '/', see midas.c::cm_set_path()
291 if (path[path.length() - 1] != DIR_SEPARATOR)
292 path += DIR_SEPARATOR_STR;
293 path += dsn;
294 }
295
296 int downsample = 0;
297 size = sizeof(downsample);
298 status = db_get_value(hDB, hKey, "Enable downsampling queries", &downsample, &size, TID_BOOL, TRUE);
299 assert(status == DB_SUCCESS);
300
301 if (active || (flags & HS_GET_INACTIVE)) {
303 if (*mh == NULL)
304 return HS_FILE_ERROR;
305
306 (*mh)->hs_set_debug(debug);
307 //(*mh)->hs_set_downsample(downsample);
308
309 status = (*mh)->hs_connect(path.c_str());
310 if (status != HS_SUCCESS) {
311 cm_msg(MERROR, "hs_get_history", "Cannot connect to PGSQL history, status %d", status);
312 return status;
313 }
314
315 if (debug_flag)
316 cm_msg(MINFO, "hs_get_history", "Connected history channel \'%s\' type PGSQL at \'%s\'", key.name,
317 path.c_str());
318 }
319 } else if (strcasecmp(type.c_str(), "IMAGE")==0) {
320 if (debug_flag)
321 cm_msg(MINFO, "hs_get_history", "History channel \'IMAGE\' handled by image facility");
322 } else {
323 cm_msg(MERROR, "hs_get_history", "Logger history channel /Logger/History/%s/Type has invalid value \'%s\', valid values are MIDAS, ODBC, SQLITE, MYSQL, FILE and IMAGE", key.name, type.c_str());
324 return HS_FILE_ERROR;
325 }
326
327 if (*mh == NULL)
328 return HS_FILE_ERROR;
329
330 mstrlcpy((*mh)->name, key.name, sizeof((*mh)->name));
331 mstrlcpy((*mh)->type, type.c_str(), sizeof((*mh)->type));
332
333 return HS_SUCCESS;
334}
335
336// find history reader channel, returns ODB handle to the history channel definition in /Logger/History/...
338{
339 int status;
340 int size;
342 HNDLE hKey;
343 std::string hschanname;
344
345 *hKeyOut = 0;
346
347 status = db_find_key(hDB, 0, "/Logger/History", &hKeyChan);
348 if (status != DB_SUCCESS) {
349 cm_msg(MERROR, "hs_find_reader_channel", "Cannot find /Logger/History, db_find_key() status %d", status);
350 return status;
351 }
352
353 // get history channel name selected by user in ODB
354
355 status = db_get_value_string(hDB, 0, "/History/LoggerHistoryChannel", 0, &hschanname, TRUE);
356 assert(status == DB_SUCCESS);
357
358 if (hschanname.length() > 0) {
360 if (status == DB_NO_KEY) {
361 cm_msg(MERROR, "hs_find_reader_channel", "Misconfigured history: history channel name in /History/LoggerHistoryChannel is \'%s\', not present in /Logger/History, db_find_key() status %d", hschanname.c_str(), status);
362 return HS_FILE_ERROR;
363 }
364 assert(status == DB_SUCCESS);
365 *hKeyOut = hKey;
366 return HS_SUCCESS;
367 }
368
369 // if selected channel name is blank, find first active channel
370
371 for (int ichan=0; ; ichan++) {
373 if (status != DB_SUCCESS)
374 break;
375
376 int active = 0;
377 size = sizeof(active);
378 status = db_get_value(hDB, hKey, "Active", &active, &size, TID_BOOL, FALSE);
379 if (status == DB_SUCCESS && active != 0) {
380 *hKeyOut = hKey;
381 return HS_SUCCESS;
382 }
383 }
384
385 cm_msg(MERROR, "hs_find_reader_channel", "Cannot find default history: /History/LoggerHistoryChannel is empty and there are no active history channels in /Logger/History");
386 return HS_FILE_ERROR;
387}
388
389static std::string hs_event_list_filename()
390{
391 std::string path = cm_get_path();
392 return path + ".LOGGER_HISTORY_EVENTS.TXT";
393}
394
395// save list of active events
396int hs_save_event_list(const std::vector<std::string> *pevents)
397{
398 std::string ss;
399 for (unsigned i=0; i<pevents->size(); i++)
400 ss += (*pevents)[i] + "\n";
401
402 std::string fname = hs_event_list_filename();
403
404 FILE *fp = fopen(fname.c_str(), "w");
405 if (!fp) {
406 cm_msg(MERROR, "hs_save_event_list", "Cannot open file \'%s\', errno %d (%s)", fname.c_str(), errno, strerror(errno));
407 return HS_FILE_ERROR;
408 }
409
410 const char* s = ss.c_str();
411 int len = strlen(s);
412
413 int wr = write(fileno(fp), s, len);
414
415 if (wr != len) {
416 cm_msg(MERROR, "hs_save_event_list", "Cannot write to file \'%s\', errno %d (%s)", fname.c_str(), errno, strerror(errno));
417 fclose(fp);
418 return HS_FILE_ERROR;
419 }
420
421 fclose(fp);
422 return HS_SUCCESS;
423}
424
425// get list of active events
426int hs_read_event_list(std::vector<std::string> *pevents)
427{
428 std::string fname = hs_event_list_filename();
429
430 FILE *fp = fopen(fname.c_str(), "r");
431 if (!fp) {
432 cm_msg(MERROR, "hs_read_event_list", "Cannot open file \'%s\', errno %d (%s)", fname.c_str(), errno, strerror(errno));
433 return HS_FILE_ERROR;
434 }
435
436 while (1) {
437 char buf[256];
438 char *s = fgets(buf, sizeof(buf), fp);
439 if (!s) // EOF
440 break;
441 // kill trailing \n and \r
442 s = strchr(buf, '\n');
443 if (s)
444 *s = 0;
445 s = strchr(buf, '\r');
446 if (s)
447 *s = 0;
448 pevents->push_back(buf);
449 }
450
451 fclose(fp);
452 return HS_SUCCESS;
453}
454
455/* emacs
456 * Local Variables:
457 * tab-width: 8
458 * c-basic-offset: 3
459 * indent-tabs-mode: nil
460 * End:
461 */
#define FALSE
Definition cfortran.h:309
std::string cm_get_path()
Definition midas.cxx:1537
std::string cm_get_history_path(const char *history_channel)
Definition midas.cxx:5843
#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
MidasHistoryInterface * MakeMidasHistory()
Definition history.cxx:3583
#define TID_BOOL
Definition midas.h:340
#define MINFO
Definition midas.h:560
#define MERROR
Definition midas.h:559
#define TID_INT
Definition midas.h:338
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
Definition odb.cxx:5415
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6019
INT EXPRT db_get_value_string(HNDLE hdb, HNDLE hKeyRoot, const char *key_name, int index, std::string *s, BOOL create, int create_string_length)
Definition odb.cxx:13934
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4079
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5586
#define HS_GET_WRITER
Definition history.h:36
#define HS_GET_DEFAULT
Definition history.h:38
#define HS_GET_INACTIVE
Definition history.h:37
#define HS_GET_READER
Definition history.h:35
int hs_read_event_list(std::vector< std::string > *pevents)
int hs_save_event_list(const std::vector< std::string > *pevents)
int hs_find_reader_channel(HNDLE hDB, HNDLE *hKeyOut, int debug_flag)
int hs_get_history(HNDLE hDB, HNDLE hKey, int flags, int debug_flag, MidasHistoryInterface **mh)
static std::string hs_event_list_filename()
MidasHistoryInterface * MakeMidasHistoryODBC()
MidasHistoryInterface * MakeMidasHistorySqlDebug()
MidasHistoryInterface * MakeMidasHistorySqlite()
MidasHistoryInterface * MakeMidasHistoryMysql()
MidasHistoryInterface * MakeMidasHistoryPgsql()
MidasHistoryInterface * MakeMidasHistoryFile()
HNDLE hKey
BOOL debug
debug printouts
Definition mana.cxx:254
INT type
Definition mana.cxx:269
HNDLE hDB
main ODB handle
Definition mana.cxx:207
KEY key
Definition mdump.cxx:34
INT i
Definition mdump.cxx:32
#define DIR_SEPARATOR
Definition midas.h:193
INT HNDLE
Definition midas.h:132
#define DIR_SEPARATOR_STR
Definition midas.h:194
#define TRUE
Definition midas.h:182
MidasHistoryInterface * mh
#define write(n, a, f, d)
static FILE * fp
DWORD status
Definition odbhist.cxx:39
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Definition midas.h:1026
char name[NAME_LENGTH]
Definition midas.h:1029