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 4653 of file history_schema.cxx.

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

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

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

7100{
7101 return new FileHistory();
7102}
Here is the caller graph for this function:

◆ MakeMidasHistoryMysql()

MidasHistoryInterface * MakeMidasHistoryMysql ( )

Definition at line 7079 of file history_schema.cxx.

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

◆ MakeMidasHistoryPgsql()

MidasHistoryInterface * MakeMidasHistoryPgsql ( )

Definition at line 7089 of file history_schema.cxx.

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

◆ MakeMidasHistorySqlite()

MidasHistoryInterface * MakeMidasHistorySqlite ( )

Definition at line 7069 of file history_schema.cxx.

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

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

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

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

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

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

◆ KiB

const double KiB = 1024

Definition at line 6350 of file history_schema.cxx.

◆ kMonth

const time_t kMonth = 30*kDay

Definition at line 6348 of file history_schema.cxx.

◆ MiB

Definition at line 6351 of file history_schema.cxx.