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

Go to the source code of this file.

Classes

struct  HsSchemaEntry
 
struct  HsSchema
 
class  HsSchemaVector
 
class  SqlBase
 
struct  HsSqlSchema
 
struct  HsFileSchema
 
class  SchemaHistoryBase
 
class  SchemaHistoryBase::ReadBuffer
 
class  SqlHistoryBase
 
class  SqliteHistory
 
class  MysqlHistory
 
class  FileHistory
 

Macros

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

Functions

static charskip_spaces (char *s)
 
static std::string TimeToString (time_t t)
 
static std::string SmallIntToString (int i)
 
static bool MatchEventName (const char *event_name, const char *var_event_name)
 
static bool MatchTagName (const char *tag_name, int n_data, const char *var_tag_name, const int var_tag_index)
 
static void PrintTags (int ntags, const TAG tags[])
 
static std::string MidasNameToSqlName (const char *s)
 
static std::string MidasNameToFileName (const char *s)
 
static int event_name_cmp (const std::string &e1, const char *e2)
 
static int var_name_cmp (const std::string &v1, const char *v2)
 
void DoctorPgsqlColumnType (std::string *col_type, const char *index_type)
 
void DoctorSqlColumnType (std::string *col_type, const char *index_type)
 
static int ReadRecord (const char *file_name, int fd, int offset, int recsize, int irec, char *rec)
 
static int FindTime (const char *file_name, int fd, int offset, int recsize, int nrec, time_t timestamp, int *i1p, time_t *t1p, int *i2p, time_t *t2p, time_t *tstart, time_t *tend, int debug)
 
static HsSqlSchemaNewSqlSchema (HsSchemaVector *sv, const char *table_name, time_t t)
 
static int StartSqlTransaction (SqlBase *sql, const char *table_name, bool *have_transaction)
 
static int CreateSqlTable (SqlBase *sql, const char *table_name, bool *have_transaction, bool set_default_timestamp=false)
 
static int CreateSqlHyperTable (SqlBase *sql, const char *table_name, bool *have_transaction)
 
static int CreateSqlColumn (SqlBase *sql, const char *table_name, const char *column_name, const char *column_type, bool *have_transaction, int debug)
 
static int ReadSqliteTableNames (SqlBase *sql, HsSchemaVector *sv, const char *table_name, int debug)
 
static int ReadSqliteTableSchema (SqlBase *sql, HsSchemaVector *sv, const char *table_name, int debug)
 
static int ReadMysqlTableNames (SqlBase *sql, HsSchemaVector *sv, const char *table_name, int debug, const char *must_have_event_name, const char *must_have_table_name)
 
MidasHistoryInterfaceMakeMidasHistorySqlite ()
 
MidasHistoryInterfaceMakeMidasHistoryMysql ()
 
MidasHistoryInterfaceMakeMidasHistoryPgsql ()
 
MidasHistoryInterfaceMakeMidasHistoryFile ()
 

Variables

const time_t kDay = 24*60*60
 
const time_t kMonth = 30*kDay
 
const double KiB = 1024
 
const double MiB = KiB*KiB
 

Macro Definition Documentation

◆ FREE

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

Definition at line 53 of file history_schema.cxx.

Function Documentation

◆ CreateSqlColumn()

static int CreateSqlColumn ( SqlBase sql,
const char table_name,
const char column_name,
const char column_type,
bool have_transaction,
int  debug 
)
static

Definition at line 4587 of file history_schema.cxx.

4588{
4589 if (debug)
4590 printf("CreateSqlColumn: table [%s], column [%s], type [%s]\n", table_name, column_name, column_type);
4591
4592 int status = StartSqlTransaction(sql, table_name, have_transaction);
4593 if (status != HS_SUCCESS)
4594 return status;
4595
4596 std::string cmd;
4597 cmd = "ALTER TABLE ";
4598 cmd += sql->QuoteId(table_name);
4599 cmd += " ADD COLUMN ";
4600 cmd += sql->QuoteId(column_name);
4601 cmd += " ";
4602 cmd += column_type;
4603 cmd += ";";
4604
4605 status = sql->Exec(table_name, cmd.c_str());
4606
4607 cm_msg(MINFO, "CreateSqlColumn", "Adding column \"%s\" to SQL table \"%s\", status %d", column_name, table_name, status);
4609
4610 return status;
4611}
virtual std::string QuoteId(const char *s)=0
virtual int Exec(const char *sql)=0
#define HS_SUCCESS
Definition midas.h:727
#define MINFO
Definition midas.h:560
INT cm_msg_flush_buffer()
Definition midas.cxx:865
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
static int StartSqlTransaction(SqlBase *sql, const char *table_name, bool *have_transaction)
BOOL debug
debug printouts
Definition mana.cxx:254
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CreateSqlHyperTable()

static int CreateSqlHyperTable ( SqlBase sql,
const char table_name,
bool have_transaction 
)
static

Definition at line 4513 of file history_schema.cxx.

4513 {
4514 int status;
4515
4516 status = StartSqlTransaction(sql, table_name, have_transaction);
4517 if (status != DB_SUCCESS)
4518 return HS_FILE_ERROR;
4519
4520 std::string cmd;
4521
4522 cmd = "CREATE TABLE ";
4523 cmd += sql->QuoteId(table_name);
4524 cmd += " (_t_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, _i_time INTEGER NOT NULL DEFAULT 0);";
4525
4526 status = sql->Exec(table_name, cmd.c_str());
4527
4528 if (status == DB_KEY_EXIST) {
4529 cm_msg(MINFO, "CreateSqlHyperTable", "Adding SQL table \"%s\", but it already exists", table_name);
4531 return status;
4532 }
4533
4534 if (status != DB_SUCCESS) {
4535 cm_msg(MINFO, "CreateSqlHyperTable", "Adding SQL table \"%s\", error status %d", table_name, status);
4537 return HS_FILE_ERROR;
4538 }
4539
4540 cm_msg(MINFO, "CreateSqlHyperTable", "Adding SQL table \"%s\"", table_name);
4542
4543 cmd = "SELECT create_hypertable(";
4544 cmd += sql->QuoteString(table_name);
4545 cmd += ", '_t_time');";
4546
4547 // convert regular table to hypertable
4548 status = sql->Exec(table_name, cmd.c_str());
4549
4550 if (status != DB_SUCCESS) {
4551 cm_msg(MINFO, "CreateSqlHyperTable", "Converting SQL table to hypertable \"%s\", error status %d", table_name, status);
4553 return HS_FILE_ERROR;
4554 }
4555
4556 std::string i_index_name;
4557 i_index_name = table_name;
4558 i_index_name += "_i_time_index";
4559
4560 std::string t_index_name;
4561 t_index_name = table_name;
4562 t_index_name += "_t_time_index";
4563
4564 cmd = "CREATE INDEX ";
4565 cmd += sql->QuoteId(i_index_name.c_str());
4566 cmd += " ON ";
4567 cmd += sql->QuoteId(table_name);
4568 cmd += " (_i_time ASC);";
4569
4570 status = sql->Exec(table_name, cmd.c_str());
4571 if (status != DB_SUCCESS)
4572 return HS_FILE_ERROR;
4573
4574 cmd = "CREATE INDEX ";
4575 cmd += sql->QuoteId(t_index_name.c_str());
4576 cmd += " ON ";
4577 cmd += sql->QuoteId(table_name);
4578 cmd += " (_t_time);";
4579
4580 status = sql->Exec(table_name, cmd.c_str());
4581 if (status != DB_SUCCESS)
4582 return HS_FILE_ERROR;
4583
4584 return status;
4585}
virtual std::string QuoteString(const char *s)=0
#define DB_KEY_EXIST
Definition midas.h:641
#define DB_SUCCESS
Definition midas.h:631
#define HS_FILE_ERROR
Definition midas.h:728
Here is the call graph for this function:

◆ CreateSqlTable()

static int CreateSqlTable ( SqlBase sql,
const char table_name,
bool have_transaction,
bool  set_default_timestamp = false 
)
static

Definition at line 4446 of file history_schema.cxx.

4447{
4448 int status;
4449
4450 status = StartSqlTransaction(sql, table_name, have_transaction);
4451 if (status != DB_SUCCESS)
4452 return HS_FILE_ERROR;
4453
4454 std::string cmd;
4455
4456 cmd = "CREATE TABLE ";
4457 cmd += sql->QuoteId(table_name);
4459 cmd += " (_t_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, _i_time INTEGER NOT NULL DEFAULT 0);";
4460 } else {
4461 cmd += " (_t_time TIMESTAMP NOT NULL, _i_time INTEGER NOT NULL);";
4462 }
4463
4464 status = sql->Exec(table_name, cmd.c_str());
4465
4466
4467 if (status == DB_KEY_EXIST) {
4468 cm_msg(MINFO, "CreateSqlTable", "Adding SQL table \"%s\", but it already exists", table_name);
4470 return status;
4471 }
4472
4473 if (status != DB_SUCCESS) {
4474 cm_msg(MINFO, "CreateSqlTable", "Adding SQL table \"%s\", error status %d", table_name, status);
4476 return HS_FILE_ERROR;
4477 }
4478
4479 cm_msg(MINFO, "CreateSqlTable", "Adding SQL table \"%s\"", table_name);
4481
4482 std::string i_index_name;
4483 i_index_name = table_name;
4484 i_index_name += "_i_time_index";
4485
4486 std::string t_index_name;
4487 t_index_name = table_name;
4488 t_index_name += "_t_time_index";
4489
4490 cmd = "CREATE INDEX ";
4491 cmd += sql->QuoteId(i_index_name.c_str());
4492 cmd += " ON ";
4493 cmd += sql->QuoteId(table_name);
4494 cmd += " (_i_time ASC);";
4495
4496 status = sql->Exec(table_name, cmd.c_str());
4497 if (status != DB_SUCCESS)
4498 return HS_FILE_ERROR;
4499
4500 cmd = "CREATE INDEX ";
4501 cmd += sql->QuoteId(t_index_name.c_str());
4502 cmd += " ON ";
4503 cmd += sql->QuoteId(table_name);
4504 cmd += " (_t_time);";
4505
4506 status = sql->Exec(table_name, cmd.c_str());
4507 if (status != DB_SUCCESS)
4508 return HS_FILE_ERROR;
4509
4510 return status;
4511}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DoctorPgsqlColumnType()

void DoctorPgsqlColumnType ( std::string *  col_type,
const char index_type 
)

Definition at line 300 of file history_schema.cxx.

301{
302 if (*col_type == index_type)
303 return;
304
305 if (*col_type == "bigint" && strcmp(index_type, "int8")==0) {
307 return;
308 }
309
310 if (*col_type == "integer" && strcmp(index_type, "int4")==0) {
312 return;
313 }
314
315 if (*col_type == "smallint" && strcmp(index_type, "int2")==0) {
317 return;
318 }
319
320 cm_msg(MERROR, "SqlHistory", "Cannot use this SQL database, incompatible column names: created column type [%s] is reported with column type [%s]", index_type, col_type->c_str());
322 abort();
323}
#define MERROR
Definition midas.h:559
Here is the call graph for this function:

◆ DoctorSqlColumnType()

void DoctorSqlColumnType ( std::string *  col_type,
const char index_type 
)

Definition at line 325 of file history_schema.cxx.

326{
327 if (*col_type == index_type)
328 return;
329
330 if (*col_type == "int(10) unsigned" && strcmp(index_type, "integer unsigned")==0) {
332 return;
333 }
334
335 if (*col_type == "int(11)" && strcmp(index_type, "integer")==0) {
337 return;
338 }
339
340 if (*col_type == "integer" && strcmp(index_type, "int(11)")==0) {
342 return;
343 }
344
345 // MYSQL 8.0.23
346
347 if (*col_type == "int" && strcmp(index_type, "integer")==0) {
349 return;
350 }
351
352 if (*col_type == "int unsigned" && strcmp(index_type, "integer unsigned")==0) {
354 return;
355 }
356
357 cm_msg(MERROR, "SqlHistory", "Cannot use this SQL database, incompatible column names: created column type [%s] is reported with column type [%s]", index_type, col_type->c_str());
359 abort();
360}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ event_name_cmp()

static int event_name_cmp ( const std::string &  e1,
const char e2 
)
static

Definition at line 218 of file history_schema.cxx.

219{
220 return strcasecmp(e1.c_str(), e2);
221}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindTime()

static int FindTime ( const char file_name,
int  fd,
int  offset,
int  recsize,
int  nrec,
time_t  timestamp,
int i1p,
time_t t1p,
int i2p,
time_t t2p,
time_t tstart,
time_t tend,
int  debug 
)
static

Definition at line 2586 of file history_schema.cxx.

2587{
2588 //
2589 // purpose: find location time timestamp inside given file.
2590 // uses binary search
2591 // returns:
2592 // tstart, tend - time of first and last data in a file
2593 // i1p,t1p - data just before timestamp, used as "last_written"
2594 // i2p,t2p - data at timestamp or after timestamp, used as starting point to read data from file
2595 // assertions:
2596 // tstart <= t1p < t2p <= tend
2597 // i1p+1==i2p
2598 // t1p < timestamp <= t2p
2599 //
2600 // special cases:
2601 // 1) timestamp <= tstart - all data is in the future, return i1p==-1, t1p==-1, i2p==0, t2p==tstart
2602 // 2) tend < timestamp - all the data is in the past, return i1p = nrec-1, t1p = tend, i2p = nrec, t2p = 0;
2603 // 3) nrec == 1 only one record in this file and it is older than the timestamp (tstart == tend < timestamp)
2604 //
2605
2606 int status;
2607 char* buf = new char[recsize];
2608
2609 assert(nrec > 0);
2610
2611 int rec1 = 0;
2612 int rec2 = nrec-1;
2613
2615 if (status != HS_SUCCESS) {
2616 delete[] buf;
2617 return HS_FILE_ERROR;
2618 }
2619
2620 time_t t1 = *(DWORD*)buf;
2621
2622 *tstart = t1;
2623
2624 // timestamp is older than any data in this file
2625 if (timestamp <= t1) {
2626 *i1p = -1;
2627 *t1p = 0;
2628 *i2p = 0;
2629 *t2p = t1;
2630 *tend = 0;
2631 delete[] buf;
2632 return HS_SUCCESS;
2633 }
2634
2635 assert(t1 < timestamp);
2636
2637 if (nrec == 1) {
2638 *i1p = 0;
2639 *t1p = t1;
2640 *i2p = nrec; // == 1
2641 *t2p = 0;
2642 *tend = t1;
2643 delete[] buf;
2644 return HS_SUCCESS;
2645 }
2646
2648 if (status != HS_SUCCESS) {
2649 delete[] buf;
2650 return HS_FILE_ERROR;
2651 }
2652
2653 time_t t2 = *(DWORD*)buf;
2654
2655 *tend = t2;
2656
2657 // all the data is in the past
2658 if (t2 < timestamp) {
2659 *i1p = rec2;
2660 *t1p = t2;
2661 *i2p = nrec;
2662 *t2p = 0;
2663 delete[] buf;
2664 return HS_SUCCESS;
2665 }
2666
2667 assert(t1 < timestamp);
2668 assert(timestamp <= t2);
2669
2670 if (debug)
2671 printf("FindTime: rec %d..(x)..%d, time %s..(%s)..%s\n", rec1, rec2, TimeToString(t1).c_str(), TimeToString(timestamp).c_str(), TimeToString(t2).c_str());
2672
2673 // implement binary search
2674
2675 do {
2676 int rec = (rec1+rec2)/2;
2677
2678 assert(rec >= 0);
2679 assert(rec < nrec);
2680
2682 if (status != HS_SUCCESS) {
2683 delete[] buf;
2684 return HS_FILE_ERROR;
2685 }
2686
2687 time_t t = *(DWORD*)buf;
2688
2689 if (timestamp <= t) {
2690 if (debug)
2691 printf("FindTime: rec %d..(x)..%d..%d, time %s..(%s)..%s..%s\n", rec1, rec, rec2, TimeToString(t1).c_str(), TimeToString(timestamp).c_str(), TimeToString(t).c_str(), TimeToString(t2).c_str());
2692
2693 rec2 = rec;
2694 t2 = t;
2695 } else {
2696 if (debug)
2697 printf("FindTime: rec %d..%d..(x)..%d, time %s..%s..(%s)..%s\n", rec1, rec, rec2, TimeToString(t1).c_str(), TimeToString(t).c_str(), TimeToString(timestamp).c_str(), TimeToString(t2).c_str());
2698
2699 rec1 = rec;
2700 t1 = t;
2701 }
2702 } while (rec2 - rec1 > 1);
2703
2704 assert(rec1+1 == rec2);
2705 assert(t1 < timestamp);
2706 assert(timestamp <= t2);
2707
2708 if (debug)
2709 printf("FindTime: rec %d..(x)..%d, time %s..(%s)..%s, this is the result.\n", rec1, rec2, TimeToString(t1).c_str(), TimeToString(timestamp).c_str(), TimeToString(t2).c_str());
2710
2711 *i1p = rec1;
2712 *t1p = t1;
2713
2714 *i2p = rec2;
2715 *t2p = t2;
2716
2717 delete[] buf;
2718 return HS_SUCCESS;
2719}
unsigned int DWORD
Definition mcstd.h:51
static int ReadRecord(const char *file_name, int fd, int offset, int recsize, int irec, char *rec)
static std::string TimeToString(time_t t)
static int offset
Definition mgd.cxx:1500
char file_name[256]
Definition odbhist.cxx:41
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeMidasHistoryFile()

MidasHistoryInterface * MakeMidasHistoryFile ( )

Definition at line 7030 of file history_schema.cxx.

7031{
7032 return new FileHistory();
7033}
Here is the caller graph for this function:

◆ MakeMidasHistoryMysql()

MidasHistoryInterface * MakeMidasHistoryMysql ( )

Definition at line 7010 of file history_schema.cxx.

7011{
7012#ifdef HAVE_MYSQL
7013 return new MysqlHistory();
7014#else
7015 cm_msg(MERROR, "MakeMidasHistoryMysql", "Error: Cannot initialize MySQL history - this MIDAS was built without MySQL support - HAVE_MYSQL is not defined");
7016 return NULL;
7017#endif
7018}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeMidasHistoryPgsql()

MidasHistoryInterface * MakeMidasHistoryPgsql ( )

Definition at line 7020 of file history_schema.cxx.

7021{
7022#ifdef HAVE_PGSQL
7023 return new PgsqlHistory();
7024#else
7025 cm_msg(MERROR, "MakeMidasHistoryPgsql", "Error: Cannot initialize PgSQL history - this MIDAS was built without PostgreSQL support - HAVE_PGSQL is not defined");
7026 return NULL;
7027#endif
7028}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeMidasHistorySqlite()

MidasHistoryInterface * MakeMidasHistorySqlite ( )

Definition at line 7000 of file history_schema.cxx.

7001{
7002#ifdef HAVE_SQLITE
7003 return new SqliteHistory();
7004#else
7005 cm_msg(MERROR, "MakeMidasHistorySqlite", "Error: Cannot initialize SQLITE history - this MIDAS was built without SQLITE support - HAVE_SQLITE is not defined");
7006 return NULL;
7007#endif
7008}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MatchEventName()

static bool MatchEventName ( const char event_name,
const char var_event_name 
)
static

Definition at line 116 of file history_schema.cxx.

117{
118 // new-style event name: "equipment_name/variable_name:tag_name"
119 // old-style event name: "equipment_name:tag_name" ("variable_name" is missing)
121
122 //printf("looking for event_name [%s], try table [%s] event name [%s], new style [%d]\n", var_event_name, table_name, event_name, newStyleEventName);
123
124 if (strcasecmp(event_name, var_event_name) == 0) {
125 return true;
126 } else if (newStyleEventName) {
127 return false;
128 } else { // for old style names, need more parsing
129 bool match = false;
130
131 const char* s = event_name;
132 for (int j=0; s[j]; j++) {
133
134 if ((var_event_name[j]==0) && (s[j]=='/')) {
135 match = true;
136 break;
137 }
138
139 if ((var_event_name[j]==0) && (s[j]=='_')) {
140 match = true;
141 break;
142 }
143
144 if (var_event_name[j]==0) {
145 match = false;
146 break;
147 }
148
149 if (tolower(var_event_name[j]) != tolower(s[j])) { // does not work for UTF-8 Unicode
150 match = false;
151 break;
152 }
153 }
154
155 return match;
156 }
157}
BOOL match(char *pat, char *str)
Definition odbedit.cxx:190
INT j
Definition odbhist.cxx:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MatchTagName()

static bool MatchTagName ( const char tag_name,
int  n_data,
const char var_tag_name,
const int  var_tag_index 
)
static

Definition at line 159 of file history_schema.cxx.

160{
161 char alt_tag_name[1024]; // maybe this is an array without "Names"?
163
164 //printf(" looking for tag [%s] alt [%s], try column name [%s]\n", var_tag_name, alt_tag_name, tag_name);
165
166 if (strcasecmp(tag_name, var_tag_name) == 0)
167 if (var_tag_index >= 0 && var_tag_index < n_data)
168 return true;
169
170 if (strcasecmp(tag_name, alt_tag_name) == 0)
171 return true;
172
173 return false;
174}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MidasNameToFileName()

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

Definition at line 201 of file history_schema.cxx.

202{
203 std::string out;
204
205 for (int i=0; s[i]!=0; i++) {
206 char c = s[i];
207 if (isalpha(c) || isdigit(c))
208 out += tolower(c); // does not work for UTF-8 Unicode
209 else
210 out += '_';
211 }
212
213 return out;
214}
INT i
Definition mdump.cxx:32
char c
Definition system.cxx:1310
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MidasNameToSqlName()

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

Definition at line 184 of file history_schema.cxx.

185{
186 std::string out;
187
188 for (int i=0; s[i]!=0; i++) {
189 char c = s[i];
190 if (isalpha(c) || isdigit(c))
191 out += tolower(c); // does not work for UTF-8 Unicode
192 else
193 out += '_';
194 }
195
196 return out;
197}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ NewSqlSchema()

static HsSqlSchema * NewSqlSchema ( HsSchemaVector sv,
const char table_name,
time_t  t 
)
static

Definition at line 4071 of file history_schema.cxx.

4072{
4073 time_t tt = 0;
4074 int j=-1;
4075 int jjx=-1; // remember oldest schema
4076 time_t ttx = 0;
4077 for (unsigned i=0; i<sv->size(); i++) {
4078 HsSqlSchema* s = (HsSqlSchema*)(*sv)[i];
4079 if (s->table_name != table_name)
4080 continue;
4081
4082 if (s->time_from == t)
4083 return s;
4084
4085 // remember the last schema before time t
4086 if (s->time_from < t) {
4087 if (s->time_from > tt) {
4088 tt = s->time_from;
4089 j = i;
4090 }
4091 }
4092
4093 if (jjx < 0) {
4094 jjx = i;
4095 ttx = s->time_from;
4096 }
4097
4098 if (s->time_from < ttx) {
4099 jjx = i;
4100 ttx = s->time_from;
4101 }
4102
4103 //printf("table_name [%s], t=%s, i=%d, j=%d %s, tt=%s, dt is %d\n", table_name, TimeToString(t).c_str(), i, j, TimeToString(s->time_from).c_str(), TimeToString(tt).c_str(), (int)(s->time_from-t));
4104 }
4105
4106 //printf("NewSqlSchema: will copy schema j=%d, tt=%d at time %d\n", j, tt, t);
4107
4108 //printf("cloned schema at time %s: ", TimeToString(t).c_str());
4109 //(*sv)[j]->print(false);
4110
4111 //printf("schema before:\n");
4112 //sv->print(false);
4113
4114 if (j >= 0) {
4115 HsSqlSchema* s = new HsSqlSchema;
4116 *s = *(HsSqlSchema*)(*sv)[j]; // make a copy
4117 s->time_from = t;
4118 sv->add(s);
4119
4120 //printf("schema after:\n");
4121 //sv->print(false);
4122
4123 return s;
4124 }
4125
4126 if (jjx >= 0) {
4127 cm_msg(MERROR, "NewSqlSchema", "Error: Unexpected ordering of schema for table \'%s\', good luck!", table_name);
4128
4129 HsSqlSchema* s = new HsSqlSchema;
4130 *s = *(HsSqlSchema*)(*sv)[jjx]; // make a copy
4131 s->time_from = t;
4132 s->time_to = ttx;
4133 sv->add(s);
4134
4135 //printf("schema after:\n");
4136 //sv->print(false);
4137
4138 return s;
4139 }
4140
4141 cm_msg(MERROR, "NewSqlSchema", "Error: Cannot clone schema for table \'%s\', good luck!", table_name);
4142 return NULL;
4143}
std::string table_name
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PrintTags()

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

Definition at line 176 of file history_schema.cxx.

177{
178 for (int i=0; i<ntags; i++)
179 printf("tag %d: %s %s[%d]\n", i, rpc_tid_name(tags[i].type), tags[i].name, tags[i].n_data);
180}
const char * rpc_tid_name(INT id)
Definition midas.cxx:11764
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:

◆ ReadMysqlTableNames()

static int ReadMysqlTableNames ( SqlBase sql,
HsSchemaVector sv,
const char table_name,
int  debug,
const char must_have_event_name,
const char must_have_table_name 
)
static

Definition at line 5424 of file history_schema.cxx.

5425{
5426 if (debug)
5427 printf("ReadMysqlTableNames: table [%s], must have event [%s] table [%s]\n", table_name, must_have_event_name, must_have_table_name);
5428
5429 int status;
5430 std::string cmd;
5431
5432 if (table_name) {
5433 cmd = "SELECT event_name, table_name, itimestamp FROM _history_index WHERE table_name='";
5434 cmd += table_name;
5435 cmd += "';";
5436 } else {
5437 cmd = "SELECT event_name, table_name, itimestamp FROM _history_index WHERE table_name!='';";
5438 table_name = "_history_index";
5439 }
5440
5441 status = sql->Prepare(table_name, cmd.c_str());
5442
5443 if (status != DB_SUCCESS)
5444 return status;
5445
5446 bool found_must_have_table = false;
5447 int count = 0;
5448
5449 while (1) {
5450 status = sql->Step();
5451
5452 if (status != DB_SUCCESS)
5453 break;
5454
5455 const char* xevent_name = sql->GetText(0);
5456 const char* xtable_name = sql->GetText(1);
5457 time_t xevent_time = sql->GetTime(2);
5458
5459 if (debug == 999) {
5460 printf("entry %d event name [%s] table name [%s] time %s\n", count, xevent_name, xtable_name, TimeToString(xevent_time).c_str());
5461 }
5462
5464 assert(must_have_event_name != NULL);
5466 found_must_have_table = true;
5467 //printf("Found table [%s]: event name [%s] table name [%s] time %s\n", must_have_table_name, xevent_name, xtable_name, TimeToString(xevent_time).c_str());
5468 } else {
5469 //printf("Found correct table [%s] with wrong event name [%s] expected [%s] time %s\n", must_have_table_name, xevent_name, must_have_event_name, TimeToString(xevent_time).c_str());
5470 }
5471 }
5472
5473 HsSqlSchema* s = new HsSqlSchema;
5474 s->sql = sql;
5477 s->time_to = 0;
5479 sv->add(s);
5480 count++;
5481 }
5482
5483 status = sql->Finalize();
5484
5486 cm_msg(MERROR, "ReadMysqlTableNames", "Error: Table [%s] for event [%s] missing from the history index\n", must_have_table_name, must_have_event_name);
5487 if (debug == 999)
5488 return HS_FILE_ERROR;
5489 // NB: recursion is broken by setting debug to 999.
5491 cm_msg(MERROR, "ReadMysqlTableNames", "Error: Cannot continue, nothing will work after this error\n");
5493 abort();
5494 return HS_FILE_ERROR;
5495 }
5496
5497 if (0) {
5498 // print accumulated schema
5499 printf("ReadMysqlTableNames: table_name [%s] event_name [%s] table_name [%s]\n", table_name, must_have_event_name, must_have_table_name);
5500 sv->print(false);
5501 }
5502
5503 return HS_SUCCESS;
5504}
virtual int Finalize()=0
virtual int Prepare(const char *table_name, const char *sql)=0
virtual time_t GetTime(int column)=0
virtual int Step()=0
virtual const char * GetText(int column)=0
static int event_name_cmp(const std::string &e1, const char *e2)
static int ReadMysqlTableNames(SqlBase *sql, HsSchemaVector *sv, const char *table_name, int debug, const char *must_have_event_name, const char *must_have_table_name)
double count
Definition mdump.cxx:33
std::string event_name
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ReadRecord()

static int ReadRecord ( const char file_name,
int  fd,
int  offset,
int  recsize,
int  irec,
char rec 
)
static

Definition at line 2559 of file history_schema.cxx.

2560{
2561 int status;
2562 int fpos = offset + irec*recsize;
2563
2564 status = ::lseek(fd, fpos, SEEK_SET);
2565 if (status == -1) {
2566 cm_msg(MERROR, "FileHistory::ReadRecord", "Cannot read \'%s\', lseek(%d) errno %d (%s)", file_name, fpos, errno, strerror(errno));
2567 return -1;
2568 }
2569
2570 status = ::read(fd, rec, recsize);
2571 if (status == 0) {
2572 cm_msg(MERROR, "FileHistory::ReadRecord", "Cannot read \'%s\', unexpected end of file on read()", file_name);
2573 return -1;
2574 }
2575 if (status == -1) {
2576 cm_msg(MERROR, "FileHistory::ReadRecord", "Cannot read \'%s\', read() errno %d (%s)", file_name, errno, strerror(errno));
2577 return -1;
2578 }
2579 if (status != recsize) {
2580 cm_msg(MERROR, "FileHistory::ReadRecord", "Cannot read \'%s\', short read() returned %d instead of %d bytes", file_name, status, recsize);
2581 return -1;
2582 }
2583 return HS_SUCCESS;
2584}
#define read(n, a, f)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ReadSqliteTableNames()

static int ReadSqliteTableNames ( SqlBase sql,
HsSchemaVector sv,
const char table_name,
int  debug 
)
static

Definition at line 5075 of file history_schema.cxx.

5076{
5077 if (debug)
5078 printf("ReadSqliteTableNames: table [%s]\n", table_name);
5079
5080 int status;
5081 std::string cmd;
5082
5083 // FIXME: quotes
5084 cmd = "SELECT event_name, _i_time FROM \'_event_name_";
5085 cmd += table_name;
5086 cmd += "\' WHERE table_name='";
5087 cmd += table_name;
5088 cmd += "';";
5089
5090 status = sql->Prepare(table_name, cmd.c_str());
5091
5092 if (status != DB_SUCCESS)
5093 return status;
5094
5095 while (1) {
5096 status = sql->Step();
5097
5098 if (status != DB_SUCCESS)
5099 break;
5100
5101 std::string xevent_name = sql->GetText(0);
5102 time_t xevent_time = sql->GetTime(1);
5103
5104 //printf("read event name [%s] time %s\n", xevent_name.c_str(), TimeToString(xevent_time).c_str());
5105
5106 HsSqlSchema* s = new HsSqlSchema;
5107 s->sql = sql;
5110 s->time_to = 0;
5111 s->table_name = table_name;
5112 sv->add(s);
5113 }
5114
5115 status = sql->Finalize();
5116
5117 return HS_SUCCESS;
5118}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ReadSqliteTableSchema()

static int ReadSqliteTableSchema ( SqlBase sql,
HsSchemaVector sv,
const char table_name,
int  debug 
)
static

Definition at line 5120 of file history_schema.cxx.

5121{
5122 if (debug)
5123 printf("ReadSqliteTableSchema: table [%s]\n", table_name);
5124
5125 if (1) {
5126 // seed schema with table names
5127 HsSqlSchema* s = new HsSqlSchema;
5128 s->sql = sql;
5129 s->event_name = table_name;
5130 s->time_from = 0;
5131 s->time_to = 0;
5132 s->table_name = table_name;
5133 sv->add(s);
5134 }
5135
5136 return ReadSqliteTableNames(sql, sv, table_name, debug);
5137}
static int ReadSqliteTableNames(SqlBase *sql, HsSchemaVector *sv, const char *table_name, int debug)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ skip_spaces()

static char * skip_spaces ( char s)
static

Definition at line 55 of file history_schema.cxx.

56{
57 while (*s) {
58 if (!isspace(*s))
59 break;
60 s++;
61 }
62 return s;
63}
Here is the call graph for this function:

◆ SmallIntToString()

static std::string SmallIntToString ( int  i)
static

Definition at line 95 of file history_schema.cxx.

96{
97 //int ii = i;
98
99 if (i == 0)
100 return "0";
101
102 assert(i > 0);
103
104 std::string v;
105 while (i) {
106 char c = '0' + i%10;
107 i /= 10;
108 v = c + v;
109 }
110
111 //printf("SmallIntToString: %d -> %s\n", ii, v.c_str());
112
113 return v;
114}
Here is the caller graph for this function:

◆ StartSqlTransaction()

static int StartSqlTransaction ( SqlBase sql,
const char table_name,
bool have_transaction 
)
static

Definition at line 4433 of file history_schema.cxx.

4434{
4435 if (*have_transaction)
4436 return HS_SUCCESS;
4437
4438 int status = sql->OpenTransaction(table_name);
4439 if (status != DB_SUCCESS)
4440 return HS_FILE_ERROR;
4441
4442 *have_transaction = true;
4443 return HS_SUCCESS;
4444}
virtual int OpenTransaction(const char *table_name)=0
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TimeToString()

static std::string TimeToString ( time_t  t)
static

Definition at line 65 of file history_schema.cxx.

66{
67 const char* sign = "";
68
69 if (t == 0)
70 return "0";
71
72 time_t tt = t;
73
74 if (t < 0) {
75 sign = "-";
76 tt = -t;
77 }
78
79 assert(tt > 0);
80
81 std::string v;
82 while (tt) {
83 char c = '0' + tt%10;
84 tt /= 10;
85 v = c + v;
86 }
87
88 v = sign + v;
89
90 //printf("time %.0f -> %s\n", (double)t, v.c_str());
91
92 return v;
93}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ var_name_cmp()

static int var_name_cmp ( const std::string &  v1,
const char v2 
)
static

Definition at line 225 of file history_schema.cxx.

226{
227 return strcasecmp(v1.c_str(), v2);
228}
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ kDay

const time_t kDay = 24*60*60

Definition at line 6278 of file history_schema.cxx.

◆ KiB

const double KiB = 1024

Definition at line 6281 of file history_schema.cxx.

◆ kMonth

const time_t kMonth = 30*kDay

Definition at line 6279 of file history_schema.cxx.

◆ MiB

Definition at line 6282 of file history_schema.cxx.