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, off64_t offset, size_t recsize, off64_t irec, char *rec)
 
static int FindTime (const char *file_name, int fd, off64_t offset, size_t recsize, off64_t nrec, time_t timestamp, off64_t *i1p, time_t *t1p, off64_t *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 4746 of file history_schema.cxx.

4747{
4748 if (debug)
4749 printf("CreateSqlColumn: table [%s], column [%s], type [%s]\n", table_name, column_name, column_type);
4750
4751 int status = StartSqlTransaction(sql, table_name, have_transaction);
4752 if (status != HS_SUCCESS)
4753 return status;
4754
4755 std::string cmd;
4756 cmd = "ALTER TABLE ";
4757 cmd += sql->QuoteId(table_name);
4758 cmd += " ADD COLUMN ";
4759 cmd += sql->QuoteId(column_name);
4760 cmd += " ";
4761 cmd += column_type;
4762 cmd += ";";
4763
4764 status = sql->Exec(table_name, cmd.c_str());
4765
4766 cm_msg(MINFO, "CreateSqlColumn", "Adding column \"%s\" to SQL table \"%s\", status %d", column_name, table_name, status);
4768
4769 return status;
4770}
#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 4672 of file history_schema.cxx.

4672 {
4673 int status;
4674
4676 if (status != DB_SUCCESS)
4677 return HS_FILE_ERROR;
4678
4679 std::string cmd;
4680
4681 cmd = "CREATE TABLE ";
4682 cmd += sql->QuoteId(table_name);
4683 cmd += " (_t_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, _i_time INTEGER NOT NULL DEFAULT 0);";
4684
4685 status = sql->Exec(table_name, cmd.c_str());
4686
4687 if (status == DB_KEY_EXIST) {
4688 cm_msg(MINFO, "CreateSqlHyperTable", "Adding SQL table \"%s\", but it already exists", table_name);
4690 return status;
4691 }
4692
4693 if (status != DB_SUCCESS) {
4694 cm_msg(MINFO, "CreateSqlHyperTable", "Adding SQL table \"%s\", error status %d", table_name, status);
4696 return HS_FILE_ERROR;
4697 }
4698
4699 cm_msg(MINFO, "CreateSqlHyperTable", "Adding SQL table \"%s\"", table_name);
4701
4702 cmd = "SELECT create_hypertable(";
4703 cmd += sql->QuoteString(table_name);
4704 cmd += ", '_t_time');";
4705
4706 // convert regular table to hypertable
4707 status = sql->Exec(table_name, cmd.c_str());
4708
4709 if (status != DB_SUCCESS) {
4710 cm_msg(MINFO, "CreateSqlHyperTable", "Converting SQL table to hypertable \"%s\", error status %d", table_name, status);
4712 return HS_FILE_ERROR;
4713 }
4714
4715 std::string i_index_name;
4716 i_index_name = table_name;
4717 i_index_name += "_i_time_index";
4718
4719 std::string t_index_name;
4720 t_index_name = table_name;
4721 t_index_name += "_t_time_index";
4722
4723 cmd = "CREATE INDEX ";
4724 cmd += sql->QuoteId(i_index_name.c_str());
4725 cmd += " ON ";
4726 cmd += sql->QuoteId(table_name);
4727 cmd += " (_i_time ASC);";
4728
4729 status = sql->Exec(table_name, cmd.c_str());
4730 if (status != DB_SUCCESS)
4731 return HS_FILE_ERROR;
4732
4733 cmd = "CREATE INDEX ";
4734 cmd += sql->QuoteId(t_index_name.c_str());
4735 cmd += " ON ";
4736 cmd += sql->QuoteId(table_name);
4737 cmd += " (_t_time);";
4738
4739 status = sql->Exec(table_name, cmd.c_str());
4740 if (status != DB_SUCCESS)
4741 return HS_FILE_ERROR;
4742
4743 return status;
4744}
#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 4605 of file history_schema.cxx.

4606{
4607 int status;
4608
4610 if (status != DB_SUCCESS)
4611 return HS_FILE_ERROR;
4612
4613 std::string cmd;
4614
4615 cmd = "CREATE TABLE ";
4616 cmd += sql->QuoteId(table_name);
4618 cmd += " (_t_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, _i_time INTEGER NOT NULL DEFAULT 0);";
4619 } else {
4620 cmd += " (_t_time TIMESTAMP NOT NULL, _i_time INTEGER NOT NULL);";
4621 }
4622
4623 status = sql->Exec(table_name, cmd.c_str());
4624
4625
4626 if (status == DB_KEY_EXIST) {
4627 cm_msg(MINFO, "CreateSqlTable", "Adding SQL table \"%s\", but it already exists", table_name);
4629 return status;
4630 }
4631
4632 if (status != DB_SUCCESS) {
4633 cm_msg(MINFO, "CreateSqlTable", "Adding SQL table \"%s\", error status %d", table_name, status);
4635 return HS_FILE_ERROR;
4636 }
4637
4638 cm_msg(MINFO, "CreateSqlTable", "Adding SQL table \"%s\"", table_name);
4640
4641 std::string i_index_name;
4642 i_index_name = table_name;
4643 i_index_name += "_i_time_index";
4644
4645 std::string t_index_name;
4646 t_index_name = table_name;
4647 t_index_name += "_t_time_index";
4648
4649 cmd = "CREATE INDEX ";
4650 cmd += sql->QuoteId(i_index_name.c_str());
4651 cmd += " ON ";
4652 cmd += sql->QuoteId(table_name);
4653 cmd += " (_i_time ASC);";
4654
4655 status = sql->Exec(table_name, cmd.c_str());
4656 if (status != DB_SUCCESS)
4657 return HS_FILE_ERROR;
4658
4659 cmd = "CREATE INDEX ";
4660 cmd += sql->QuoteId(t_index_name.c_str());
4661 cmd += " ON ";
4662 cmd += sql->QuoteId(table_name);
4663 cmd += " (_t_time);";
4664
4665 status = sql->Exec(table_name, cmd.c_str());
4666 if (status != DB_SUCCESS)
4667 return HS_FILE_ERROR;
4668
4669 return status;
4670}
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,
off64_t  offset,
size_t  recsize,
off64_t  nrec,
time_t  timestamp,
off64_t i1p,
time_t t1p,
off64_t i2p,
time_t t2p,
time_t tstart,
time_t tend,
int  debug 
)
static

Definition at line 2623 of file history_schema.cxx.

2624{
2625 //
2626 // purpose: find location time timestamp inside given file.
2627 // uses binary search
2628 // returns:
2629 // tstart, tend - time of first and last data in a file
2630 // i1p,t1p - data just before timestamp, used as "last_written"
2631 // i2p,t2p - data at timestamp or after timestamp, used as starting point to read data from file
2632 // assertions:
2633 // tstart <= t1p < t2p <= tend
2634 // i1p+1==i2p
2635 // t1p < timestamp <= t2p
2636 //
2637 // special cases:
2638 // 1) timestamp <= tstart - all data is in the future, return i1p==-1, t1p==-1, i2p==0, t2p==tstart
2639 // 2) tend < timestamp - all the data is in the past, return i1p = nrec-1, t1p = tend, i2p = nrec, t2p = 0;
2640 // 3) nrec == 1 only one record in this file and it is older than the timestamp (tstart == tend < timestamp)
2641 //
2642
2643 int status;
2644 char* buf = new char[recsize];
2645
2646 assert(nrec > 0);
2647
2648 off64_t rec1 = 0;
2649 off64_t rec2 = nrec-1;
2650
2652 if (status != HS_SUCCESS) {
2653 delete[] buf;
2654 return HS_FILE_ERROR;
2655 }
2656
2657 time_t t1 = *(DWORD*)buf;
2658
2659 *tstart = t1;
2660
2661 // timestamp is older than any data in this file
2662 if (timestamp <= t1) {
2663 *i1p = -1;
2664 *t1p = 0;
2665 *i2p = 0;
2666 *t2p = t1;
2667 *tend = 0;
2668 delete[] buf;
2669 return HS_SUCCESS;
2670 }
2671
2672 assert(t1 < timestamp);
2673
2674 if (nrec == 1) {
2675 *i1p = 0;
2676 *t1p = t1;
2677 *i2p = nrec; // == 1
2678 *t2p = 0;
2679 *tend = t1;
2680 delete[] buf;
2681 return HS_SUCCESS;
2682 }
2683
2685 if (status != HS_SUCCESS) {
2686 delete[] buf;
2687 return HS_FILE_ERROR;
2688 }
2689
2690 time_t t2 = *(DWORD*)buf;
2691
2692 *tend = t2;
2693
2694 // all the data is in the past
2695 if (t2 < timestamp) {
2696 *i1p = rec2;
2697 *t1p = t2;
2698 *i2p = nrec;
2699 *t2p = 0;
2700 delete[] buf;
2701 return HS_SUCCESS;
2702 }
2703
2704 assert(t1 < timestamp);
2705 assert(timestamp <= t2);
2706
2707 if (debug)
2708 printf("FindTime: rec %jd..(x)..%jd, time %s..(%s)..%s\n", (intmax_t)rec1, (intmax_t)rec2, TimeToString(t1).c_str(), TimeToString(timestamp).c_str(), TimeToString(t2).c_str());
2709
2710 // implement binary search
2711
2712 do {
2713 off64_t rec = (rec1+rec2)/2;
2714
2715 assert(rec >= 0);
2716 assert(rec < nrec);
2717
2719 if (status != HS_SUCCESS) {
2720 delete[] buf;
2721 return HS_FILE_ERROR;
2722 }
2723
2724 time_t t = *(DWORD*)buf;
2725
2726 if (timestamp <= t) {
2727 if (debug)
2728 printf("FindTime: rec %jd..(x)..%jd..%jd, time %s..(%s)..%s..%s\n", (intmax_t)rec1, (intmax_t)rec, (intmax_t)rec2, TimeToString(t1).c_str(), TimeToString(timestamp).c_str(), TimeToString(t).c_str(), TimeToString(t2).c_str());
2729
2730 rec2 = rec;
2731 t2 = t;
2732 } else {
2733 if (debug)
2734 printf("FindTime: rec %jd..%jd..(x)..%jd, time %s..%s..(%s)..%s\n", (intmax_t)rec1, (intmax_t)rec, (intmax_t)rec2, TimeToString(t1).c_str(), TimeToString(t).c_str(), TimeToString(timestamp).c_str(), TimeToString(t2).c_str());
2735
2736 rec1 = rec;
2737 t1 = t;
2738 }
2739 } while (rec2 - rec1 > 1);
2740
2741 assert(rec1+1 == rec2);
2742 assert(t1 < timestamp);
2743 assert(timestamp <= t2);
2744
2745 if (debug)
2746 printf("FindTime: rec %jd..(x)..%jd, time %s..(%s)..%s, this is the result.\n", (intmax_t)rec1, (intmax_t)rec2, TimeToString(t1).c_str(), TimeToString(timestamp).c_str(), TimeToString(t2).c_str());
2747
2748 *i1p = rec1;
2749 *t1p = t1;
2750
2751 *i2p = rec2;
2752 *t2p = t2;
2753
2754 delete[] buf;
2755 return HS_SUCCESS;
2756}
unsigned int DWORD
Definition mcstd.h:51
static int ReadRecord(const char *file_name, int fd, off64_t offset, size_t recsize, off64_t 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 7278 of file history_schema.cxx.

7279{
7280 return new FileHistory();
7281}
Here is the caller graph for this function:

◆ MakeMidasHistoryMysql()

MidasHistoryInterface * MakeMidasHistoryMysql ( )

Definition at line 7258 of file history_schema.cxx.

7259{
7260#ifdef HAVE_MYSQL
7261 return new MysqlHistory();
7262#else
7263 cm_msg(MERROR, "MakeMidasHistoryMysql", "Error: Cannot initialize MySQL history - this MIDAS was built without MySQL support - HAVE_MYSQL is not defined");
7264 return NULL;
7265#endif
7266}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeMidasHistoryPgsql()

MidasHistoryInterface * MakeMidasHistoryPgsql ( )

Definition at line 7268 of file history_schema.cxx.

7269{
7270#ifdef HAVE_PGSQL
7271 return new PgsqlHistory();
7272#else
7273 cm_msg(MERROR, "MakeMidasHistoryPgsql", "Error: Cannot initialize PgSQL history - this MIDAS was built without PostgreSQL support - HAVE_PGSQL is not defined");
7274 return NULL;
7275#endif
7276}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MakeMidasHistorySqlite()

MidasHistoryInterface * MakeMidasHistorySqlite ( )

Definition at line 7248 of file history_schema.cxx.

7249{
7250#ifdef HAVE_SQLITE
7251 return new SqliteHistory();
7252#else
7253 cm_msg(MERROR, "MakeMidasHistorySqlite", "Error: Cannot initialize SQLITE history - this MIDAS was built without SQLITE support - HAVE_SQLITE is not defined");
7254 return NULL;
7255#endif
7256}
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 4154 of file history_schema.cxx.

4155{
4156 time_t tt = 0;
4157 int j=-1;
4158 int jjx=-1; // remember oldest schema
4159 time_t ttx = 0;
4160 for (size_t i=0; i<sv->size(); i++) {
4161 HsSqlSchema* s = (HsSqlSchema*)(*sv)[i];
4162 if (s->fTableName != table_name)
4163 continue;
4164
4165 if (s->fTimeFrom == t) {
4166 return s;
4167 }
4168
4169 // remember the last schema before time t
4170 if (s->fTimeFrom < t) {
4171 if (s->fTimeFrom > tt) {
4172 tt = s->fTimeFrom;
4173 j = i;
4174 }
4175 }
4176
4177 if (jjx < 0) {
4178 jjx = i;
4179 ttx = s->fTimeFrom;
4180 }
4181
4182 if (s->fTimeFrom < ttx) {
4183 jjx = i;
4184 ttx = s->fTimeFrom;
4185 }
4186
4187 //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));
4188 }
4189
4190 //printf("NewSqlSchema: will copy schema j=%d, tt=%d at time %d\n", j, tt, t);
4191
4192 //printf("cloned schema at time %s: ", TimeToString(t).c_str());
4193 //(*sv)[j]->print(false);
4194
4195 //printf("schema before:\n");
4196 //sv->print(false);
4197
4198 if (j >= 0) {
4199 HsSqlSchema* s = new HsSqlSchema;
4200 *s = *(HsSqlSchema*)(*sv)[j]; // make a copy
4201 s->fTimeFrom = t;
4202 sv->add(s);
4203
4204 //printf("schema after:\n");
4205 //sv->print(false);
4206
4207 return s;
4208 }
4209
4210 if (jjx >= 0) {
4211 cm_msg(MERROR, "NewSqlSchema", "Error: Unexpected ordering of schema for table \'%s\', good luck!", table_name);
4212
4213 HsSqlSchema* s = new HsSqlSchema;
4214 *s = *(HsSqlSchema*)(*sv)[jjx]; // make a copy
4215 s->fTimeFrom = t;
4216 s->fTimeTo = ttx;
4217 sv->add(s);
4218
4219 //printf("schema after:\n");
4220 //sv->print(false);
4221
4222 return s;
4223 }
4224
4225 cm_msg(MERROR, "NewSqlSchema", "Error: Cannot clone schema for table \'%s\', good luck!", table_name);
4226 return NULL;
4227}
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 5586 of file history_schema.cxx.

5587{
5588 if (debug)
5589 printf("ReadMysqlTableNames: table [%s], must have event [%s] table [%s]\n", table_name, must_have_event_name, must_have_table_name);
5590
5591 int status;
5592 std::string cmd;
5593
5594 if (table_name) {
5595 cmd = "SELECT event_name, table_name, itimestamp FROM _history_index WHERE table_name='";
5596 cmd += table_name;
5597 cmd += "';";
5598 } else {
5599 cmd = "SELECT event_name, table_name, itimestamp FROM _history_index WHERE table_name!='';";
5600 table_name = "_history_index";
5601 }
5602
5603 status = sql->Prepare(table_name, cmd.c_str());
5604
5605 if (status != DB_SUCCESS)
5606 return status;
5607
5608 bool found_must_have_table = false;
5609 int count = 0;
5610
5611 while (1) {
5612 status = sql->Step();
5613
5614 if (status != DB_SUCCESS)
5615 break;
5616
5617 const char* xevent_name = sql->GetText(0);
5618 const char* xtable_name = sql->GetText(1);
5619 time_t xevent_time = sql->GetTime(2);
5620
5621 if (debug == 999) {
5622 printf("entry %d event name [%s] table name [%s] time %s\n", count, xevent_name, xtable_name, TimeToString(xevent_time).c_str());
5623 }
5624
5626 assert(must_have_event_name != NULL);
5628 found_must_have_table = true;
5629 //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());
5630 } else {
5631 //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());
5632 }
5633 }
5634
5635 HsSqlSchema* s = new HsSqlSchema;
5636 s->fSql = sql;
5639 s->fTimeTo = 0;
5641 sv->add(s);
5642 count++;
5643 }
5644
5645 status = sql->Finalize();
5646
5648 cm_msg(MERROR, "ReadMysqlTableNames", "Error: Table [%s] for event [%s] missing from the history index\n", must_have_table_name, must_have_event_name);
5649 if (debug == 999)
5650 return HS_FILE_ERROR;
5651 // NB: recursion is broken by setting debug to 999.
5653 cm_msg(MERROR, "ReadMysqlTableNames", "Error: Cannot continue, nothing will work after this error\n");
5655 abort();
5656 return HS_FILE_ERROR;
5657 }
5658
5659 if (0) {
5660 // print accumulated schema
5661 printf("ReadMysqlTableNames: table_name [%s] event_name [%s] table_name [%s]\n", table_name, must_have_event_name, must_have_table_name);
5662 sv->print(false);
5663 }
5664
5665 return HS_SUCCESS;
5666}
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,
off64_t  offset,
size_t  recsize,
off64_t  irec,
char rec 
)
static

Definition at line 2592 of file history_schema.cxx.

2593{
2595
2597
2598 if (status64 < 0) {
2599 cm_msg(MERROR, "FileHistory::ReadRecord", "Cannot read \'%s\', lseek64(%jd) errno %d (%s)", file_name, (intmax_t)fpos, errno, strerror(errno));
2600 return -1;
2601 }
2602
2603 ssize_t rd = ::read(fd, rec, recsize);
2604
2605 if (rd < 0) {
2606 cm_msg(MERROR, "FileHistory::ReadRecord", "Cannot read \'%s\', read() errno %d (%s)", file_name, errno, strerror(errno));
2607 return -1;
2608 }
2609
2610 if (rd == 0) {
2611 cm_msg(MERROR, "FileHistory::ReadRecord", "Cannot read \'%s\', unexpected end of file on read()", file_name);
2612 return -1;
2613 }
2614
2615 if ((size_t)rd != recsize) {
2616 cm_msg(MERROR, "FileHistory::ReadRecord", "Cannot read \'%s\', short read() returned %zd instead of %zu bytes", file_name, rd, recsize);
2617 return -1;
2618 }
2619
2620 return HS_SUCCESS;
2621}
#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 5236 of file history_schema.cxx.

5237{
5238 if (debug)
5239 printf("ReadSqliteTableNames: table [%s]\n", table_name);
5240
5241 int status;
5242 std::string cmd;
5243
5244 // FIXME: quotes
5245 cmd = "SELECT event_name, _i_time FROM \'_event_name_";
5246 cmd += table_name;
5247 cmd += "\' WHERE table_name='";
5248 cmd += table_name;
5249 cmd += "';";
5250
5251 status = sql->Prepare(table_name, cmd.c_str());
5252
5253 if (status != DB_SUCCESS)
5254 return status;
5255
5256 while (1) {
5257 status = sql->Step();
5258
5259 if (status != DB_SUCCESS)
5260 break;
5261
5262 std::string xevent_name = sql->GetText(0);
5263 time_t xevent_time = sql->GetTime(1);
5264
5265 //printf("read event name [%s] time %s\n", xevent_name.c_str(), TimeToString(xevent_time).c_str());
5266
5267 HsSqlSchema* s = new HsSqlSchema;
5268 s->fSql = sql;
5271 s->fTimeTo = 0;
5272 s->fTableName = table_name;
5273 sv->add(s);
5274 }
5275
5276 status = sql->Finalize();
5277
5278 return HS_SUCCESS;
5279}
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 5281 of file history_schema.cxx.

5282{
5283 if (debug)
5284 printf("ReadSqliteTableSchema: table [%s]\n", table_name);
5285
5286 if (1) {
5287 // seed schema with table names
5288 HsSqlSchema* s = new HsSqlSchema;
5289 s->fSql = sql;
5290 s->fEventName = table_name;
5291 s->fTimeFrom = 0;
5292 s->fTimeTo = 0;
5293 s->fTableName = table_name;
5294 sv->add(s);
5295 }
5296
5297 return ReadSqliteTableNames(sql, sv, table_name, debug);
5298}
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' + (char)(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 call graph for this function:
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 4592 of file history_schema.cxx.

4593{
4594 if (*have_transaction)
4595 return HS_SUCCESS;
4596
4597 int status = sql->OpenTransaction(table_name);
4598 if (status != DB_SUCCESS)
4599 return HS_FILE_ERROR;
4600
4601 *have_transaction = true;
4602 return HS_SUCCESS;
4603}
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' + (char)(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 6442 of file history_schema.cxx.

◆ KiB

const double KiB = 1024

Definition at line 6445 of file history_schema.cxx.

◆ kMonth

const time_t kMonth = 30*kDay

Definition at line 6443 of file history_schema.cxx.

◆ MiB

Definition at line 6446 of file history_schema.cxx.