MIDAS
Loading...
Searching...
No Matches
MysqlHistory Class Reference
Inheritance diagram for MysqlHistory:
Collaboration diagram for MysqlHistory:

Public Member Functions

 MysqlHistory ()
 
int read_table_and_event_names (HsSchemaVector *sv)
 
int read_column_names (HsSchemaVector *sv, const char *table_name, const char *event_name)
 
int create_table (HsSchemaVector *sv, const char *event_name, time_t timestamp)
 
int update_column (const char *event_name, const char *table_name, const char *column_name, const char *column_type, const char *tag_name, const char *tag_type, const time_t timestamp, bool active, bool *have_transaction)
 
- Public Member Functions inherited from SqlHistoryBase
 SqlHistoryBase ()
 
virtual ~SqlHistoryBase ()
 
int hs_set_debug (int debug)
 set debug level, returns previous debug level
 
int hs_connect (const char *connect_string)
 returns HS_SUCCESS
 
int hs_disconnect ()
 disconnect from history, returns HS_SUCCESS
 
HsSchemanew_event (const char *event_name, time_t timestamp, int ntags, const TAG tags[])
 
int read_schema (HsSchemaVector *sv, const char *event_name, const time_t timestamp)
 
HsSchemamaybe_reopen (const char *event_name, time_t timestamp, HsSchema *s)
 
- Public Member Functions inherited from SchemaHistoryBase
 SchemaHistoryBase ()
 
virtual ~SchemaHistoryBase ()
 
int hs_define_event (const char *event_name, time_t timestamp, int ntags, const TAG tags[])
 see hs_define_event(), returns HS_SUCCESS or HS_FILE_ERROR
 
int hs_write_event (const char *event_name, time_t timestamp, int buffer_size, const char *buffer)
 see hs_write_event(), returns HS_SUCCESS or HS_FILE_ERROR
 
int hs_flush_buffers ()
 flush buffered data to storage where it is visible to mhttpd
 
int hs_clear_cache ()
 clear internal cache, returns HS_SUCCESS
 
int hs_get_events (time_t t, std::vector< std::string > *pevents)
 get list of events that exist(ed) at given time and later (value 0 means "return all events from beginning of time"), returns HS_SUCCESS
 
int hs_get_tags (const char *event_name, time_t t, std::vector< TAG > *ptags)
 get list of history variables for given event (use event names returned by hs_get_events()) that exist(ed) at given time and later (value 0 means "all variables for this event that ever existed"), also see hs_get_tags(), returns HS_SUCCESS
 
int hs_get_last_written (time_t timestamp, int num_var, const char *const event_name[], const char *const var_name[], const int var_index[], time_t last_written[])
 
int hs_read_buffer (time_t start_time, time_t end_time, int num_var, const char *const event_name[], const char *const var_name[], const int var_index[], MidasHistoryBufferInterface *buffer[], int hs_status[])
 returns HS_SUCCESS
 
int hs_read (time_t start_time, time_t end_time, time_t interval, int num_var, const char *const event_name[], const char *const var_name[], const int var_index[], int num_entries[], time_t *time_buffer[], double *data_buffer[], int st[])
 see hs_read(), returns HS_SUCCESS
 
int hs_read_binned (time_t start_time, time_t end_time, int num_bins, int num_var, const char *const event_name[], const char *const var_name[], const int var_index[], int num_entries[], int *count_bins[], double *mean_bins[], double *rms_bins[], double *min_bins[], double *max_bins[], time_t *bins_first_time[], double *bins_first_value[], time_t *bins_last_time[], double *bins_last_value[], time_t last_time[], double last_value[], int st[])
 returns HS_SUCCESS
 
- Public Member Functions inherited from MidasHistoryInterface
 MidasHistoryInterface ()
 history type: MIDAS, ODBC, SQLITE, etc
 
virtual ~MidasHistoryInterface ()
 

Additional Inherited Members

- Public Attributes inherited from SqlHistoryBase
SqlBasefSql
 
- Public Attributes inherited from MidasHistoryInterface
char name [NAME_LENGTH]
 
char type [NAME_LENGTH]
 history channel name
 
- Protected Member Functions inherited from SqlHistoryBase
int update_schema (HsSqlSchema *s, const time_t timestamp, const int ntags, const TAG tags[], bool write_enable)
 
int update_schema1 (HsSqlSchema *s, const time_t timestamp, const int ntags, const TAG tags[], bool write_enable, bool *have_transaction)
 
- Protected Attributes inherited from SchemaHistoryBase
int fDebug = 0
 
std::string fConnectString
 
HsSchemaVector fWriterSchema
 
std::vector< HsSchema * > fWriterEvents
 
HsSchemaVector fReaderSchema
 

Detailed Description

Definition at line 5589 of file history_schema.cxx.

Constructor & Destructor Documentation

◆ MysqlHistory()

MysqlHistory::MysqlHistory ( )
inline

Definition at line 5592 of file history_schema.cxx.

5592 { // ctor
5593#ifdef HAVE_MYSQL
5594 fSql = new Mysql();
5595#endif
5596 }

Member Function Documentation

◆ create_table()

int MysqlHistory::create_table ( HsSchemaVector sv,
const char *  event_name,
time_t  timestamp 
)
virtual

Implements SqlHistoryBase.

Definition at line 5889 of file history_schema.cxx.

5890{
5891 if (fDebug)
5892 printf("MysqlHistory::create_table: event [%s], timestamp %s\n", event_name, TimeToString(timestamp).c_str());
5893
5894 int status;
5895 std::string table_name = MidasNameToSqlName(event_name);
5896
5897 // MySQL table name length limit is 64 bytes
5898 if (table_name.length() > 40) {
5899 table_name.resize(40);
5900 table_name += "_T";
5901 }
5902
5903 time_t now = time(NULL);
5904
5905 int max_attempts = 10;
5906 for (int i=0; i<max_attempts; i++) {
5907 status = fSql->OpenTransaction(table_name.c_str());
5908 if (status != DB_SUCCESS) {
5909 return HS_FILE_ERROR;
5910 }
5911
5912 bool have_transaction = true;
5913
5914 std::string xtable_name = table_name;
5915
5916 if (i>0) {
5917 xtable_name += "_";
5918 xtable_name += TimeToString(now);
5919 if (i>1) {
5920 xtable_name += "_";
5921 char buf[256];
5922 sprintf(buf, "%d", i);
5923 xtable_name += buf;
5924 }
5925 }
5926
5927 status = CreateSqlTable(fSql, xtable_name.c_str(), &have_transaction);
5928
5929 //printf("event [%s] create table [%s] status %d\n", event_name, xtable_name.c_str(), status);
5930
5931 if (status == DB_KEY_EXIST) {
5932 // already exists, try with different name!
5933 fSql->RollbackTransaction(table_name.c_str());
5934 continue;
5935 }
5936
5937 if (status != HS_SUCCESS) {
5938 // MYSQL cannot roll back "create table", if we cannot create SQL tables, nothing will work. Give up now.
5939 cm_msg(MERROR, "MysqlHistory::create_table", "Could not create table [%s] for event [%s], timestamp %s, please fix the SQL database configuration and try again", table_name.c_str(), event_name, TimeToString(timestamp).c_str());
5940 abort();
5941
5942 // fatal error, give up!
5943 fSql->RollbackTransaction(table_name.c_str());
5944 break;
5945 }
5946
5947 for (int j=0; j<2; j++) {
5948 std::string cmd;
5949 cmd += "INSERT INTO _history_index (event_name, table_name, itimestamp, active) VALUES (";
5950 cmd += fSql->QuoteString(event_name);
5951 cmd += ", ";
5952 cmd += fSql->QuoteString(xtable_name.c_str());
5953 cmd += ", ";
5954 char buf[256];
5955 sprintf(buf, "%.0f", (double)timestamp);
5956 cmd += fSql->QuoteString(buf);
5957 cmd += ", ";
5958 cmd += fSql->QuoteString("1");
5959 cmd += ");";
5960
5961 int status = fSql->Exec(table_name.c_str(), cmd.c_str());
5962 if (status == DB_SUCCESS)
5963 break;
5964
5965 status = CreateSqlTable(fSql, "_history_index", &have_transaction);
5966 status = CreateSqlColumn(fSql, "_history_index", "event_name", "varchar(256) character set binary not null", &have_transaction, fDebug);
5967 status = CreateSqlColumn(fSql, "_history_index", "table_name", "varchar(256)", &have_transaction, fDebug);
5968 status = CreateSqlColumn(fSql, "_history_index", "tag_name", "varchar(256) character set binary", &have_transaction, fDebug);
5969 status = CreateSqlColumn(fSql, "_history_index", "tag_type", "varchar(256)", &have_transaction, fDebug);
5970 status = CreateSqlColumn(fSql, "_history_index", "column_name", "varchar(256)", &have_transaction, fDebug);
5971 status = CreateSqlColumn(fSql, "_history_index", "column_type", "varchar(256)", &have_transaction, fDebug);
5972 status = CreateSqlColumn(fSql, "_history_index", "itimestamp", "integer not null", &have_transaction, fDebug);
5973 status = CreateSqlColumn(fSql, "_history_index", "active", "boolean", &have_transaction, fDebug);
5974 }
5975
5976 status = fSql->CommitTransaction(table_name.c_str());
5977
5978 if (status != DB_SUCCESS) {
5979 return HS_FILE_ERROR;
5980 }
5981
5982 return ReadMysqlTableNames(fSql, sv, xtable_name.c_str(), fDebug, event_name, xtable_name.c_str());
5983 }
5984
5985 cm_msg(MERROR, "MysqlHistory::create_table", "Could not create table [%s] for event [%s], timestamp %s, after %d attempts", table_name.c_str(), event_name, TimeToString(timestamp).c_str(), max_attempts);
5986
5987 return HS_FILE_ERROR;
5988}
virtual int RollbackTransaction(const char *table_name)=0
virtual int CommitTransaction(const char *table_name)=0
virtual int Exec(const char *sql)=0
virtual std::string QuoteString(const char *s)=0
virtual int OpenTransaction(const char *table_name)=0
#define DB_KEY_EXIST
Definition midas.h:642
#define DB_SUCCESS
Definition midas.h:632
#define HS_SUCCESS
Definition midas.h:728
#define HS_FILE_ERROR
Definition midas.h:729
#define MERROR
Definition midas.h:559
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:931
static std::string MidasNameToSqlName(const char *s)
static int CreateSqlColumn(SqlBase *sql, const char *table_name, const char *column_name, const char *column_type, bool *have_transaction, int debug)
static std::string TimeToString(time_t t)
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 int CreateSqlTable(SqlBase *sql, const char *table_name, bool *have_transaction, bool set_default_timestamp=false)
INT i
Definition mdump.cxx:32
INT j
Definition odbhist.cxx:40
DWORD status
Definition odbhist.cxx:39
Here is the call graph for this function:

◆ read_column_names()

int MysqlHistory::read_column_names ( HsSchemaVector sv,
const char *  table_name,
const char *  event_name 
)
virtual

Implements SqlHistoryBase.

Definition at line 5691 of file history_schema.cxx.

5692{
5693 if (fDebug)
5694 printf("MysqlHistory::read_column_names: table [%s], event [%s]\n", table_name, event_name);
5695
5696 // for all schema for table_name, prepopulate is with column names
5697
5698 std::vector<std::string> columns;
5699 fSql->ListColumns(table_name, &columns);
5700
5701 // first, populate column names
5702
5703 for (size_t i=0; i<sv->size(); i++) {
5704 HsSqlSchema* s = (HsSqlSchema*)(*sv)[i];
5705
5706 if (s->fTableName != table_name)
5707 continue;
5708
5709 // schema should be empty at this point
5710 //assert(s->fVariables.size() == 0);
5711
5712 for (size_t j=0; j<columns.size(); j+=2) {
5713 const char* cn = columns[j+0].c_str();
5714 const char* ct = columns[j+1].c_str();
5715
5716 if (strcmp(cn, "_t_time") == 0)
5717 continue;
5718 if (strcmp(cn, "_i_time") == 0)
5719 continue;
5720
5721 bool found = (s->find_column_index(cn) >= 0);
5722
5723 //printf("column [%s] sql type [%s]\n", cn.c_str(), ct);
5724
5725 if (!found) {
5726 HsSchemaEntry se;
5727 se.tag_name = cn;
5728 se.tag_type = "";
5729 se.name = cn;
5730 se.type = 0;
5731 se.n_data = 1;
5732 se.n_bytes = 0;
5733 s->fColumnIndexCache[cn] = s->fColumnNames.size();
5734 s->fVariables.push_back(se);
5735 s->fColumnNames.push_back(cn);
5736 s->fColumnTypes.push_back(ct);
5737 s->fColumnInactive.push_back(false);
5738 s->fOffsets.push_back(-1);
5739 }
5740 }
5741 }
5742
5743 // then read column name information
5744
5745 std::string cmd;
5746 cmd = "SELECT column_name, column_type, tag_name, tag_type, itimestamp, active FROM _history_index WHERE event_name=";
5747 cmd += fSql->QuoteString(event_name);
5748 cmd += ";";
5749
5750 int status = fSql->Prepare(table_name, cmd.c_str());
5751
5752 if (status != DB_SUCCESS) {
5753 return status;
5754 }
5755
5756 while (1) {
5757 status = fSql->Step();
5758
5759 if (status != DB_SUCCESS)
5760 break;
5761
5762 const char* col_name = fSql->GetText(0);
5763 const char* col_type = fSql->GetText(1);
5764 const char* tag_name = fSql->GetText(2);
5765 const char* tag_type = fSql->GetText(3);
5766 time_t schema_time = fSql->GetTime(4);
5767 const char* active = fSql->GetText(5);
5768 int iactive = atoi(active);
5769
5770 //printf("read table [%s] column [%s] type [%s] tag name [%s] type [%s] time %s active [%s] %d\n", table_name, col_name, col_type, tag_name, tag_type, TimeToString(schema_time).c_str(), active, iactive);
5771
5772 if (!col_name)
5773 continue;
5774 if (!tag_name)
5775 continue;
5776 if (strlen(col_name) < 1)
5777 continue;
5778
5779 // make sure a schema exists at this time point
5780 NewSqlSchema(sv, table_name, schema_time);
5781
5782 // add this information to all schema
5783
5784 for (size_t i=0; i<sv->size(); i++) {
5785 HsSqlSchema* s = (HsSqlSchema*)(*sv)[i];
5786 if (s->fTableName != table_name)
5787 continue;
5788 if (s->fTimeFrom < schema_time)
5789 continue;
5790
5791 int tid = rpc_name_tid(tag_type);
5792 int tid_size = rpc_tid_size(tid);
5793
5794 int j = s->find_column_index(col_name);
5795 if (j < 0)
5796 continue;
5797
5798 s->fVariables[j].tag_name = tag_name;
5799 s->fVariables[j].tag_type = tag_type;
5800 if (!iactive) {
5801 s->fVariables[j].name = "";
5802 s->fColumnInactive[j] = true;
5803 } else {
5804 s->fVariables[j].name = tag_name;
5805 s->fColumnInactive[j] = false;
5806 }
5807 s->fVariables[j].type = tid;
5808 s->fVariables[j].n_data = 1;
5809 s->fVariables[j].n_bytes = tid_size;
5810
5811 // doctor column names in case MySQL returns different type
5812 // from the type used to create the column, but the types
5813 // are actually the same. K.O.
5814 DoctorSqlColumnType(&s->fColumnTypes[j], col_type);
5815 }
5816 }
5817
5818 status = fSql->Finalize();
5819
5820 return HS_SUCCESS;
5821}
std::vector< int > fOffsets
std::vector< HsSchemaEntry > fVariables
size_t size() const
std::vector< std::string > fColumnNames
std::vector< std::string > fColumnTypes
std::unordered_map< std::string, size_t > fColumnIndexCache
int find_column_index(const std::string &column_name)
std::vector< bool > fColumnInactive
std::string fTableName
virtual int Finalize()=0
virtual int ListColumns(const char *table, std::vector< std::string > *plist)=0
virtual int Prepare(const char *table_name, const char *sql)=0
virtual time_t GetTime(int column)=0
virtual int Step()=0
virtual const char * GetText(int column)=0
int rpc_name_tid(const char *name)
Definition midas.cxx:11909
INT rpc_tid_size(INT id)
Definition midas.cxx:11888
static const int tid_size[]
void DoctorSqlColumnType(std::string *col_type, const char *index_type)
static HsSqlSchema * NewSqlSchema(HsSchemaVector *sv, const char *table_name, time_t t)
std::string tag_name
int type
std::string tag_type
int n_data
std::string name
int n_bytes
Here is the call graph for this function:

◆ read_table_and_event_names()

int MysqlHistory::read_table_and_event_names ( HsSchemaVector sv)
virtual

Implements SqlHistoryBase.

Definition at line 5844 of file history_schema.cxx.

5845{
5846 int status;
5847
5848 if (fDebug)
5849 printf("MysqlHistory::read_table_and_event_names!\n");
5850
5851 // loop over all tables
5852
5853 std::vector<std::string> tables;
5854 status = fSql->ListTables(&tables);
5855 if (status != DB_SUCCESS)
5856 return status;
5857
5858 for (size_t i=0; i<tables.size(); i++) {
5859 const char* table_name = tables[i].c_str();
5860
5861 const char* s;
5862 s = strstr(table_name, "_history_index");
5863 if (s == table_name)
5864 continue;
5865
5866 if (1) {
5867 // seed schema with table names
5868 HsSqlSchema* s = new HsSqlSchema;
5869 s->fSql = fSql;
5870 s->fEventName = table_name;
5871 s->fTimeFrom = 0;
5872 s->fTimeTo = 0;
5873 s->fTableName = table_name;
5874 sv->add(s);
5875 }
5876 }
5877
5878 if (0) {
5879 // print accumulated schema
5880 printf("read_table_and_event_names:\n");
5881 sv->print(false);
5882 }
5883
5884 status = ReadMysqlTableNames(fSql, sv, NULL, fDebug, NULL, NULL);
5885
5886 return HS_SUCCESS;
5887}
std::string fEventName
void print(bool print_tags=true) const
void add(HsSchema *s)
virtual int ListTables(std::vector< std::string > *plist)=0
Here is the call graph for this function:

◆ update_column()

int MysqlHistory::update_column ( const char *  event_name,
const char *  table_name,
const char *  column_name,
const char *  column_type,
const char *  tag_name,
const char *  tag_type,
const time_t  timestamp,
bool  active,
bool *  have_transaction 
)
virtual

Implements SqlHistoryBase.

Definition at line 5990 of file history_schema.cxx.

5991{
5992 if (fDebug)
5993 printf("MysqlHistory::update_column: event [%s], table [%s], column [%s], type [%s] new name [%s], timestamp %s\n", event_name, table_name, column_name, column_type, tag_name, TimeToString(timestamp).c_str());
5994
5995 std::string cmd;
5996 cmd += "INSERT INTO _history_index (event_name, table_name, tag_name, tag_type, column_name, column_type, itimestamp, active) VALUES (";
5997 cmd += fSql->QuoteString(event_name);
5998 cmd += ", ";
5999 cmd += fSql->QuoteString(table_name);
6000 cmd += ", ";
6001 cmd += fSql->QuoteString(tag_name);
6002 cmd += ", ";
6003 cmd += fSql->QuoteString(tag_type);
6004 cmd += ", ";
6005 cmd += fSql->QuoteString(column_name);
6006 cmd += ", ";
6007 cmd += fSql->QuoteString(column_type);
6008 cmd += ", ";
6009 char buf[256];
6010 sprintf(buf, "%.0f", (double)timestamp);
6011 cmd += fSql->QuoteString(buf);
6012 cmd += ", ";
6013 if (active)
6014 cmd += fSql->QuoteString("1");
6015 else
6016 cmd += fSql->QuoteString("0");
6017 cmd += ");";
6018
6019 int status = fSql->Exec(table_name, cmd.c_str());
6020 if (status != DB_SUCCESS)
6021 return HS_FILE_ERROR;
6022
6023 return HS_SUCCESS;
6024}
Here is the call graph for this function:

The documentation for this class was generated from the following file: