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
 
class  HsSchema
 
class  HsSchemaVector
 
class  SqlBase
 
class  HsSqlSchema
 
class  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 4657 of file history_schema.cxx.

4658{
4659 if (debug)
4660 printf("CreateSqlColumn: table [%s], column [%s], type [%s]\n", table_name, column_name, column_type);
4661
4662 int status = StartSqlTransaction(sql, table_name, have_transaction);
4663 if (status != HS_SUCCESS)
4664 return status;
4665
4666 std::string cmd;
4667 cmd = "ALTER TABLE ";
4668 cmd += sql->QuoteId(table_name);
4669 cmd += " ADD COLUMN ";
4670 cmd += sql->QuoteId(column_name);
4671 cmd += " ";
4672 cmd += column_type;
4673 cmd += ";";
4674
4675 status = sql->Exec(table_name, cmd.c_str());
4676
4677 cm_msg(MINFO, "CreateSqlColumn", "Adding column \"%s\" to SQL table \"%s\", status %d", column_name, table_name, status);
4679
4680 return status;
4681}
#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 4583 of file history_schema.cxx.

4583 {
4584 int status;
4585
4587 if (status != DB_SUCCESS)
4588 return HS_FILE_ERROR;
4589
4590 std::string cmd;
4591
4592 cmd = "CREATE TABLE ";
4593 cmd += sql->QuoteId(table_name);
4594 cmd += " (_t_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, _i_time INTEGER NOT NULL DEFAULT 0);";
4595
4596 status = sql->Exec(table_name, cmd.c_str());
4597
4598 if (status == DB_KEY_EXIST) {
4599 cm_msg(MINFO, "CreateSqlHyperTable", "Adding SQL table \"%s\", but it already exists", table_name);
4601 return status;
4602 }
4603
4604 if (status != DB_SUCCESS) {
4605 cm_msg(MINFO, "CreateSqlHyperTable", "Adding SQL table \"%s\", error status %d", table_name, status);
4607 return HS_FILE_ERROR;
4608 }
4609
4610 cm_msg(MINFO, "CreateSqlHyperTable", "Adding SQL table \"%s\"", table_name);
4612
4613 cmd = "SELECT create_hypertable(";
4614 cmd += sql->QuoteString(table_name);
4615 cmd += ", '_t_time');";
4616
4617 // convert regular table to hypertable
4618 status = sql->Exec(table_name, cmd.c_str());
4619
4620 if (status != DB_SUCCESS) {
4621 cm_msg(MINFO, "CreateSqlHyperTable", "Converting SQL table to hypertable \"%s\", error status %d", table_name, status);
4623 return HS_FILE_ERROR;
4624 }
4625
4626 std::string i_index_name;
4627 i_index_name = table_name;
4628 i_index_name += "_i_time_index";
4629
4630 std::string t_index_name;
4631 t_index_name = table_name;
4632 t_index_name += "_t_time_index";
4633
4634 cmd = "CREATE INDEX ";
4635 cmd += sql->QuoteId(i_index_name.c_str());
4636 cmd += " ON ";
4637 cmd += sql->QuoteId(table_name);
4638 cmd += " (_i_time ASC);";
4639
4640 status = sql->Exec(table_name, cmd.c_str());
4641 if (status != DB_SUCCESS)
4642 return HS_FILE_ERROR;
4643
4644 cmd = "CREATE INDEX ";
4645 cmd += sql->QuoteId(t_index_name.c_str());
4646 cmd += " ON ";
4647 cmd += sql->QuoteId(table_name);
4648 cmd += " (_t_time);";
4649
4650 status = sql->Exec(table_name, cmd.c_str());
4651 if (status != DB_SUCCESS)
4652 return HS_FILE_ERROR;
4653
4654 return status;
4655}
#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 4516 of file history_schema.cxx.

4517{
4518 int status;
4519
4521 if (status != DB_SUCCESS)
4522 return HS_FILE_ERROR;
4523
4524 std::string cmd;
4525
4526 cmd = "CREATE TABLE ";
4527 cmd += sql->QuoteId(table_name);
4529 cmd += " (_t_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, _i_time INTEGER NOT NULL DEFAULT 0);";
4530 } else {
4531 cmd += " (_t_time TIMESTAMP NOT NULL, _i_time INTEGER NOT NULL);";
4532 }
4533
4534 status = sql->Exec(table_name, cmd.c_str());
4535
4536
4537 if (status == DB_KEY_EXIST) {
4538 cm_msg(MINFO, "CreateSqlTable", "Adding SQL table \"%s\", but it already exists", table_name);
4540 return status;
4541 }
4542
4543 if (status != DB_SUCCESS) {
4544 cm_msg(MINFO, "CreateSqlTable", "Adding SQL table \"%s\", error status %d", table_name, status);
4546 return HS_FILE_ERROR;
4547 }
4548
4549 cm_msg(MINFO, "CreateSqlTable", "Adding SQL table \"%s\"", table_name);
4551
4552 std::string i_index_name;
4553 i_index_name = table_name;
4554 i_index_name += "_i_time_index";
4555
4556 std::string t_index_name;
4557 t_index_name = table_name;
4558 t_index_name += "_t_time_index";
4559
4560 cmd = "CREATE INDEX ";
4561 cmd += sql->QuoteId(i_index_name.c_str());
4562 cmd += " ON ";
4563 cmd += sql->QuoteId(table_name);
4564 cmd += " (_i_time ASC);";
4565
4566 status = sql->Exec(table_name, cmd.c_str());
4567 if (status != DB_SUCCESS)
4568 return HS_FILE_ERROR;
4569
4570 cmd = "CREATE INDEX ";
4571 cmd += sql->QuoteId(t_index_name.c_str());
4572 cmd += " ON ";
4573 cmd += sql->QuoteId(table_name);
4574 cmd += " (_t_time);";
4575
4576 status = sql->Exec(table_name, cmd.c_str());
4577 if (status != DB_SUCCESS)
4578 return HS_FILE_ERROR;
4579
4580 return status;
4581}
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 7103 of file history_schema.cxx.

7104{
7105 return new FileHistory();
7106}
Here is the caller graph for this function:

◆ MakeMidasHistoryMysql()

MidasHistoryInterface * MakeMidasHistoryMysql ( )

Definition at line 7083 of file history_schema.cxx.

7084{
7085#ifdef HAVE_MYSQL
7086 return new MysqlHistory();
7087#else
7088 cm_msg(MERROR, "MakeMidasHistoryMysql", "Error: Cannot initialize MySQL history - this MIDAS was built without MySQL support - HAVE_MYSQL is not defined");
7089 return NULL;
7090#endif
7091}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeMidasHistoryPgsql()

MidasHistoryInterface * MakeMidasHistoryPgsql ( )

Definition at line 7093 of file history_schema.cxx.

7094{
7095#ifdef HAVE_PGSQL
7096 return new PgsqlHistory();
7097#else
7098 cm_msg(MERROR, "MakeMidasHistoryPgsql", "Error: Cannot initialize PgSQL history - this MIDAS was built without PostgreSQL support - HAVE_PGSQL is not defined");
7099 return NULL;
7100#endif
7101}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeMidasHistorySqlite()

MidasHistoryInterface * MakeMidasHistorySqlite ( )

Definition at line 7073 of file history_schema.cxx.

7074{
7075#ifdef HAVE_SQLITE
7076 return new SqliteHistory();
7077#else
7078 cm_msg(MERROR, "MakeMidasHistorySqlite", "Error: Cannot initialize SQLITE history - this MIDAS was built without SQLITE support - HAVE_SQLITE is not defined");
7079 return NULL;
7080#endif
7081}
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 4066 of file history_schema.cxx.

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

5496{
5497 if (debug)
5498 printf("ReadMysqlTableNames: table [%s], must have event [%s] table [%s]\n", table_name, must_have_event_name, must_have_table_name);
5499
5500 int status;
5501 std::string cmd;
5502
5503 if (table_name) {
5504 cmd = "SELECT event_name, table_name, itimestamp FROM _history_index WHERE table_name='";
5505 cmd += table_name;
5506 cmd += "';";
5507 } else {
5508 cmd = "SELECT event_name, table_name, itimestamp FROM _history_index WHERE table_name!='';";
5509 table_name = "_history_index";
5510 }
5511
5512 status = sql->Prepare(table_name, cmd.c_str());
5513
5514 if (status != DB_SUCCESS)
5515 return status;
5516
5517 bool found_must_have_table = false;
5518 int count = 0;
5519
5520 while (1) {
5521 status = sql->Step();
5522
5523 if (status != DB_SUCCESS)
5524 break;
5525
5526 const char* xevent_name = sql->GetText(0);
5527 const char* xtable_name = sql->GetText(1);
5528 time_t xevent_time = sql->GetTime(2);
5529
5530 if (debug == 999) {
5531 printf("entry %d event name [%s] table name [%s] time %s\n", count, xevent_name, xtable_name, TimeToString(xevent_time).c_str());
5532 }
5533
5535 assert(must_have_event_name != NULL);
5537 found_must_have_table = true;
5538 //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());
5539 } else {
5540 //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());
5541 }
5542 }
5543
5544 HsSqlSchema* s = new HsSqlSchema;
5545 s->fSql = sql;
5548 s->fTimeTo = 0;
5550 sv->add(s);
5551 count++;
5552 }
5553
5554 status = sql->Finalize();
5555
5557 cm_msg(MERROR, "ReadMysqlTableNames", "Error: Table [%s] for event [%s] missing from the history index\n", must_have_table_name, must_have_event_name);
5558 if (debug == 999)
5559 return HS_FILE_ERROR;
5560 // NB: recursion is broken by setting debug to 999.
5562 cm_msg(MERROR, "ReadMysqlTableNames", "Error: Cannot continue, nothing will work after this error\n");
5564 abort();
5565 return HS_FILE_ERROR;
5566 }
5567
5568 if (0) {
5569 // print accumulated schema
5570 printf("ReadMysqlTableNames: table_name [%s] event_name [%s] table_name [%s]\n", table_name, must_have_event_name, must_have_table_name);
5571 sv->print(false);
5572 }
5573
5574 return HS_SUCCESS;
5575}
std::string fEventName
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
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 5145 of file history_schema.cxx.

5146{
5147 if (debug)
5148 printf("ReadSqliteTableNames: table [%s]\n", table_name);
5149
5150 int status;
5151 std::string cmd;
5152
5153 // FIXME: quotes
5154 cmd = "SELECT event_name, _i_time FROM \'_event_name_";
5155 cmd += table_name;
5156 cmd += "\' WHERE table_name='";
5157 cmd += table_name;
5158 cmd += "';";
5159
5160 status = sql->Prepare(table_name, cmd.c_str());
5161
5162 if (status != DB_SUCCESS)
5163 return status;
5164
5165 while (1) {
5166 status = sql->Step();
5167
5168 if (status != DB_SUCCESS)
5169 break;
5170
5171 std::string xevent_name = sql->GetText(0);
5172 time_t xevent_time = sql->GetTime(1);
5173
5174 //printf("read event name [%s] time %s\n", xevent_name.c_str(), TimeToString(xevent_time).c_str());
5175
5176 HsSqlSchema* s = new HsSqlSchema;
5177 s->fSql = sql;
5180 s->fTimeTo = 0;
5181 s->fTableName = table_name;
5182 sv->add(s);
5183 }
5184
5185 status = sql->Finalize();
5186
5187 return HS_SUCCESS;
5188}
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 5190 of file history_schema.cxx.

5191{
5192 if (debug)
5193 printf("ReadSqliteTableSchema: table [%s]\n", table_name);
5194
5195 if (1) {
5196 // seed schema with table names
5197 HsSqlSchema* s = new HsSqlSchema;
5198 s->fSql = sql;
5199 s->fEventName = table_name;
5200 s->fTimeFrom = 0;
5201 s->fTimeTo = 0;
5202 s->fTableName = table_name;
5203 sv->add(s);
5204 }
5205
5206 return ReadSqliteTableNames(sql, sv, table_name, debug);
5207}
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 4503 of file history_schema.cxx.

4504{
4505 if (*have_transaction)
4506 return HS_SUCCESS;
4507
4508 int status = sql->OpenTransaction(table_name);
4509 if (status != DB_SUCCESS)
4510 return HS_FILE_ERROR;
4511
4512 *have_transaction = true;
4513 return HS_SUCCESS;
4514}
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 6351 of file history_schema.cxx.

◆ KiB

const double KiB = 1024

Definition at line 6354 of file history_schema.cxx.

◆ kMonth

const time_t kMonth = 30*kDay

Definition at line 6352 of file history_schema.cxx.

◆ MiB

Definition at line 6355 of file history_schema.cxx.