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

Public Member Functions

 HsSqlSchema ()
 
 ~HsSqlSchema ()
 
void remove_inactive_columns ()
 
int find_column_index (const std::string &column_name)
 
void print (bool print_tags=true) const
 
int get_transaction_count ()
 
void reset_transaction_count ()
 
void increment_transaction_count ()
 
int close_transaction ()
 
int flush_buffers ()
 
int close ()
 
int write_event (const time_t t, const char *data, const size_t data_size)
 
int match_event_var (const char *event_name, const char *var_name, const int var_index)
 
int read_last_written (const time_t timestamp, const int debug, time_t *last_written)
 
int read_data (const time_t start_time, const time_t end_time, const int num_var, const std::vector< int > &var_schema_index, const int var_index[], const int debug, std::vector< time_t > &last_time, MidasHistoryBufferInterface *buffer[])
 
- Public Member Functions inherited from HsSchema
 HsSchema ()
 
virtual ~HsSchema ()
 

Public Attributes

SqlBasefSql = NULL
 
std::string fTableName
 
std::vector< std::string > fColumnNames
 
std::vector< std::string > fColumnTypes
 
std::vector< bool > fColumnInactive
 
std::unordered_map< std::string, size_t > fColumnIndexCache
 
- Public Attributes inherited from HsSchema
std::string fEventName
 
time_t fTimeFrom = 0
 
time_t fTimeTo = 0
 
std::vector< HsSchemaEntryfVariables
 
std::vector< int > fOffsets
 
size_t fNumBytes = 0
 
int fCountWriteUndersize = 0
 
int fCountWriteOversize = 0
 
size_t fWriteMaxSize = 0
 
size_t fWriteMinSize = 0
 
bool fDisabled = true
 

Private Attributes

int fTableTransactionCount = 0
 

Static Private Attributes

static std::map< SqlBase *, int > gfTransactionCount
 

Detailed Description

Definition at line 682 of file history_schema.cxx.

Constructor & Destructor Documentation

◆ HsSqlSchema()

HsSqlSchema::HsSqlSchema ( )
inline

Definition at line 698 of file history_schema.cxx.

699 {
700 // empty
701 }

◆ ~HsSqlSchema()

HsSqlSchema::~HsSqlSchema ( )
inline

Definition at line 703 of file history_schema.cxx.

704 {
705 assert(get_transaction_count() == 0);
706 }
int get_transaction_count()
Here is the call graph for this function:

Member Function Documentation

◆ close()

int HsSqlSchema::close ( )
inlinevirtual

Implements HsSchema.

Definition at line 716 of file history_schema.cxx.

716{ return close_transaction(); }
Here is the call graph for this function:

◆ close_transaction()

int HsSqlSchema::close_transaction ( )

Definition at line 4135 of file history_schema.cxx.

4136{
4137 if (!fSql->IsConnected()) {
4138 return HS_SUCCESS;
4139 }
4140
4141 int status = HS_SUCCESS;
4142 if (get_transaction_count() > 0) {
4145 }
4146 return status;
4147}
std::string fTableName
void reset_transaction_count()
virtual bool IsConnected()=0
virtual int CommitTransaction(const char *table_name)=0
#define HS_SUCCESS
Definition midas.h:728
DWORD status
Definition odbhist.cxx:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_column_index()

int HsSqlSchema::find_column_index ( const std::string &  column_name)

Definition at line 740 of file history_schema.cxx.

741{
742 // Rebuild the cache if it is out of sync with fColumnNames. Columns are only
743 // ever appended (read_column_names) or removed in bulk with a resize
744 // (remove_inactive_columns), so a size mismatch reliably detects staleness.
745 if (fColumnIndexCache.size() != fColumnNames.size()) {
746 fColumnIndexCache.clear();
747 for (size_t i=0; i<fColumnNames.size(); i++)
749 }
750
751 auto it = fColumnIndexCache.find(column_name);
752 if (it == fColumnIndexCache.end())
753 return -1;
754 return (int)it->second;
755}
std::vector< std::string > fColumnNames
std::unordered_map< std::string, size_t > fColumnIndexCache
INT i
Definition mdump.cxx:32
Here is the caller graph for this function:

◆ flush_buffers()

int HsSqlSchema::flush_buffers ( )
inlinevirtual

Implements HsSchema.

Definition at line 715 of file history_schema.cxx.

715{ return close_transaction(); }
Here is the call graph for this function:

◆ get_transaction_count()

int HsSqlSchema::get_transaction_count ( )

Definition at line 4589 of file history_schema.cxx.

4589 {
4590 if (!fSql || fSql->fTransactionPerTable) {
4592 } else {
4593 return gfTransactionCount[fSql];
4594 }
4595}
static std::map< SqlBase *, int > gfTransactionCount
bool fTransactionPerTable
Here is the caller graph for this function:

◆ increment_transaction_count()

void HsSqlSchema::increment_transaction_count ( )

Definition at line 4605 of file history_schema.cxx.

4605 {
4606 if (!fSql || fSql->fTransactionPerTable) {
4608 } else {
4610 }
4611}
Here is the caller graph for this function:

◆ match_event_var()

int HsSqlSchema::match_event_var ( const char *  event_name,
const char *  var_name,
const int  var_index 
)
virtual

Reimplemented from HsSchema.

Definition at line 4167 of file history_schema.cxx.

4168{
4169 if (event_name_cmp(this->fTableName, event_name)==0) {
4170 for (size_t j=0; j<this->fVariables.size(); j++) {
4171 if (var_name_cmp(this->fColumnNames[j], var_name)==0)
4172 return j;
4173 }
4174 }
4175
4176 return HsSchema::match_event_var(event_name, var_name, var_index);
4177}
std::vector< HsSchemaEntry > fVariables
virtual int match_event_var(const char *event_name, const char *var_name, const int var_index)
static int var_name_cmp(const std::string &v1, const char *v2)
static int event_name_cmp(const std::string &e1, const char *e2)
INT j
Definition odbhist.cxx:40
char var_name[256]
Definition odbhist.cxx:41
Here is the call graph for this function:

◆ print()

void HsSqlSchema::print ( bool  print_tags = true) const
virtual

Reimplemented from HsSchema.

Definition at line 824 of file history_schema.cxx.

825{
826 size_t nv = this->fVariables.size();
827 printf("event [%s], sql_table [%s], time %s..%s, %zu variables, %zu bytes\n", this->fEventName.c_str(), this->fTableName.c_str(), TimeToString(this->fTimeFrom).c_str(), TimeToString(this->fTimeTo).c_str(), nv, fNumBytes);
828 if (print_tags) {
829 for (size_t j=0; j<nv; j++) {
830 printf(" %zu: name [%s], type [%s] tid %d, n_data %d, n_bytes %d", j, this->fVariables[j].name.c_str(), rpc_tid_name(this->fVariables[j].type), this->fVariables[j].type, this->fVariables[j].n_data, this->fVariables[j].n_bytes);
831 printf(", sql_column [%s], sql_type [%s], offset %d", this->fColumnNames[j].c_str(), this->fColumnTypes[j].c_str(), this->fOffsets[j]);
832 printf(", inactive %d", (int)this->fColumnInactive[j]);
833 printf("\n");
834 }
835 }
836}
std::vector< int > fOffsets
std::string fEventName
std::vector< std::string > fColumnTypes
std::vector< bool > fColumnInactive
const char * rpc_tid_name(INT id)
Definition midas.cxx:11895
static std::string TimeToString(time_t t)
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:

◆ read_data()

int HsSqlSchema::read_data ( const time_t  start_time,
const time_t  end_time,
const int  num_var,
const std::vector< int > &  var_schema_index,
const int  var_index[],
const int  debug,
std::vector< time_t > &  last_time,
MidasHistoryBufferInterface buffer[] 
)
virtual

Implements HsSchema.

Definition at line 4500 of file history_schema.cxx.

4506{
4507 bool bad_last_time = false;
4508
4509 if (debug)
4510 printf("SqlHistory::read_data: table [%s], start %s, end %s\n", fTableName.c_str(), TimeToString(start_time).c_str(), TimeToString(end_time).c_str());
4511
4512 std::string collist;
4513
4514 for (int i=0; i<num_var; i++) {
4515 int j = var_schema_index[i];
4516 if (j < 0)
4517 continue;
4518 if (collist.length() > 0)
4519 collist += ", ";
4520 collist += fSql->QuoteId(fColumnNames[j].c_str());
4521 }
4522
4523 std::string cmd;
4524 cmd += "SELECT _i_time, ";
4525 cmd += collist;
4526 cmd += " FROM ";
4527 cmd += fSql->QuoteId(fTableName.c_str());
4528 cmd += " WHERE _i_time>=";
4529 cmd += TimeToString(start_time);
4530 cmd += " and _i_time<=";
4531 cmd += TimeToString(end_time);
4532 cmd += " ORDER BY _i_time;";
4533
4534 int status = fSql->Prepare(fTableName.c_str(), cmd.c_str());
4535
4536 if (status != DB_SUCCESS)
4537 return HS_FILE_ERROR;
4538
4539 /* Loop through the rows in the result-set */
4540
4541 int count = 0;
4542
4543 while (1) {
4544 status = fSql->Step();
4545 if (status != DB_SUCCESS)
4546 break;
4547
4548 count++;
4549
4550 time_t t = fSql->GetTime(0);
4551
4552 if (t < start_time || t > end_time)
4553 continue;
4554
4555 int k = 0;
4556
4557 for (int i=0; i<num_var; i++) {
4558 int j = var_schema_index[i];
4559 if (j < 0)
4560 continue;
4561
4562 if (t < last_time[i]) { // protect against duplicate and non-monotonous data
4563 bad_last_time = true;
4564 } else {
4565 double v = fSql->GetDouble(1+k);
4566
4567 //printf("Column %d, index %d, Row %d, time %d, value %f\n", k, colindex[k], count, t, v);
4568
4569 buffer[i]->Add(t, v);
4570 last_time[i] = t;
4571 }
4572
4573 k++;
4574 }
4575 }
4576
4577 fSql->Finalize();
4578
4579 if (bad_last_time) {
4580 cm_msg(MERROR, "SqlHistory::read_data", "Detected duplicate or non-monotonous data in table \"%s\" for start time %s and end time %s", fTableName.c_str(), TimeToString(start_time).c_str(), TimeToString(end_time).c_str());
4581 }
4582
4583 if (debug)
4584 printf("SqlHistory::read_data: table [%s], start %s, end %s, read %d rows\n", fTableName.c_str(), TimeToString(start_time).c_str(), TimeToString(end_time).c_str(), count);
4585
4586 return HS_SUCCESS;
4587}
virtual void Add(time_t time, double value)=0
virtual int Finalize()=0
virtual double GetDouble(int column)=0
virtual std::string QuoteId(const char *s)=0
virtual int Prepare(const char *table_name, const char *sql)=0
virtual time_t GetTime(int column)=0
virtual int Step()=0
#define DB_SUCCESS
Definition midas.h:632
#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
DWORD last_time
Definition mana.cxx:3070
BOOL debug
debug printouts
Definition mana.cxx:254
double count
Definition mdump.cxx:33
INT k
Definition odbhist.cxx:40
Here is the call graph for this function:

◆ read_last_written()

int HsSqlSchema::read_last_written ( const time_t  timestamp,
const int  debug,
time_t *  last_written 
)
virtual

Implements HsSchema.

Definition at line 4453 of file history_schema.cxx.

4456{
4457 if (debug)
4458 printf("SqlHistory::read_last_written: table [%s], timestamp %s\n", fTableName.c_str(), TimeToString(timestamp).c_str());
4459
4460 std::string cmd;
4461 cmd += "SELECT _i_time FROM ";
4462 cmd += fSql->QuoteId(fTableName.c_str());
4463 cmd += " WHERE _i_time < ";
4464 cmd += TimeToString(timestamp);
4465 cmd += " ORDER BY _i_time DESC LIMIT 2;";
4466
4467 int status = fSql->Prepare(fTableName.c_str(), cmd.c_str());
4468
4469 if (status != DB_SUCCESS)
4470 return status;
4471
4472 time_t lw = 0;
4473
4474 /* Loop through the rows in the result-set */
4475
4476 while (1) {
4477 status = fSql->Step();
4478 if (status != DB_SUCCESS)
4479 break;
4480
4481 time_t t = fSql->GetTime(0);
4482
4483 if (t >= timestamp)
4484 continue;
4485
4486 if (t > lw)
4487 lw = t;
4488 }
4489
4490 fSql->Finalize();
4491
4492 *last_written = lw;
4493
4494 if (debug)
4495 printf("SqlHistory::read_last_written: table [%s], timestamp %s, last_written %s\n", fTableName.c_str(), TimeToString(timestamp).c_str(), TimeToString(lw).c_str());
4496
4497 return HS_SUCCESS;
4498}
Here is the call graph for this function:

◆ remove_inactive_columns()

void HsSqlSchema::remove_inactive_columns ( )
virtual

Implements HsSchema.

Definition at line 4254 of file history_schema.cxx.

4255{
4256 assert(fVariables.size() == fColumnInactive.size());
4257 assert(fVariables.size() == fColumnNames.size());
4258 assert(fVariables.size() == fColumnTypes.size());
4259 assert(fVariables.size() == fOffsets.size());
4260
4261 size_t count_active = 0;
4262 size_t count_inactive = 0;
4263
4264 for (size_t i=0; i<fColumnInactive.size(); i++) {
4265 if (fColumnInactive[i])
4266 count_inactive += 1;
4267 else
4268 count_active += 1;
4269 }
4270
4271 //printf("remove_inactive_columns: enter! count_active: %zu, count_inactive: %zu\n", count_active, count_inactive);
4272 //print();
4273
4274 if (count_inactive > 0) {
4275 size_t j=0;
4276
4277 for (size_t i=0; i<fColumnInactive.size(); i++) {
4278 if (fColumnInactive[i]) {
4279 // skip this entry
4280 } else {
4281 if (j != i) {
4286 fOffsets[j] = fOffsets[i];
4287 }
4288 j++;
4289 }
4290 }
4291
4292 //print();
4293 //printf("%zu %zu\n", j, count_active);
4294
4295 assert(j == count_active);
4296
4297 //print();
4298
4299 fVariables.resize(count_active);
4300 fColumnInactive.resize(count_active);
4301 fColumnNames.resize(count_active);
4302 fColumnTypes.resize(count_active);
4303 fOffsets.resize(count_active);
4304
4305 assert(fVariables.size() == fColumnInactive.size());
4306 assert(fVariables.size() == fColumnNames.size());
4307 assert(fVariables.size() == fColumnTypes.size());
4308 assert(fVariables.size() == fOffsets.size());
4309
4310 //printf("remove_inactice_columns: exit!\n");
4311 //print();
4312 }
4313}

◆ reset_transaction_count()

void HsSqlSchema::reset_transaction_count ( )

Definition at line 4597 of file history_schema.cxx.

4597 {
4598 if (!fSql || fSql->fTransactionPerTable) {
4600 } else {
4602 }
4603}
Here is the caller graph for this function:

◆ write_event()

int HsSqlSchema::write_event ( const time_t  t,
const char *  data,
const size_t  data_size 
)
virtual

Implements HsSchema.

Definition at line 4315 of file history_schema.cxx.

4316{
4317 HsSqlSchema* s = this;
4318
4319 assert(s->fVariables.size() == s->fColumnInactive.size());
4320 assert(s->fVariables.size() == s->fColumnNames.size());
4321 assert(s->fVariables.size() == s->fColumnTypes.size());
4322 assert(s->fVariables.size() == s->fOffsets.size());
4323
4324 std::string tags;
4325 std::string values;
4326
4327 for (size_t i=0; i<s->fVariables.size(); i++) {
4328 // NB: inactive columns should have been removed from the schema. K.O.
4329
4330 if (s->fColumnInactive[i]) {
4331 cm_msg(MERROR, "HsSqlSchema::write_event", "Internal error, unexpected inactive column %zu", i);
4333 return HS_FILE_ERROR;
4334 }
4335
4336 int type = s->fVariables[i].type;
4337 int n_data = s->fVariables[i].n_data;
4338 int offset = s->fOffsets[i];
4339 const char* column_name = s->fColumnNames[i].c_str();
4340
4341 if (offset < 0) {
4342 cm_msg(MERROR, "HsSqlSchema::write_event", "Internal error, unexpected negative offset %d for column %zu", offset, i);
4344 return HS_FILE_ERROR;
4345 }
4346
4347 assert(n_data == 1);
4348 assert(strlen(column_name) > 0);
4349 assert(offset >= 0);
4350 assert((size_t)offset < data_size);
4351
4352 void* ptr = (void*)(data+offset);
4353
4354 tags += ", ";
4355 tags += fSql->QuoteId(column_name);
4356
4357 values += ", ";
4358
4359 char buf[1024];
4360 int j=0;
4361
4362 switch (type) {
4363 default:
4364 sprintf(buf, "unknownType%d", type);
4365 break;
4366 case TID_BYTE:
4367 sprintf(buf, "%u",((unsigned char *)ptr)[j]);
4368 break;
4369 case TID_SBYTE:
4370 sprintf(buf, "%d",((signed char*)ptr)[j]);
4371 break;
4372 case TID_CHAR:
4373 // FIXME: quotes
4374 sprintf(buf, "\'%c\'",((char*)ptr)[j]);
4375 break;
4376 case TID_WORD:
4377 sprintf(buf, "%u",((unsigned short *)ptr)[j]);
4378 break;
4379 case TID_SHORT:
4380 sprintf(buf, "%d",((short *)ptr)[j]);
4381 break;
4382 case TID_DWORD:
4383 sprintf(buf, "%u",((unsigned int *)ptr)[j]);
4384 break;
4385 case TID_INT:
4386 sprintf(buf, "%d",((int *)ptr)[j]);
4387 break;
4388 case TID_BOOL:
4389 sprintf(buf, "%u",((unsigned int *)ptr)[j]);
4390 break;
4391 case TID_FLOAT:
4392 // FIXME: quotes
4393 sprintf(buf, "\'%.8g\'",((float*)ptr)[j]);
4394 break;
4395 case TID_DOUBLE:
4396 // FIXME: quotes
4397 sprintf(buf, "\'%.16g\'",((double*)ptr)[j]);
4398 break;
4399 }
4400
4401 values += buf;
4402 }
4403
4404 // 2001-02-16 20:38:40.1
4405 struct tm tms;
4406 localtime_r(&t, &tms); // somebody must call tzset() before this.
4407 char buf[1024];
4408 strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S.0", &tms);
4409
4410 std::string cmd;
4411 cmd = "INSERT INTO ";
4412 cmd += fSql->QuoteId(s->fTableName.c_str());
4413 cmd += " (_t_time, _i_time";
4414 cmd += tags;
4415 cmd += ") VALUES (";
4416 cmd += fSql->QuoteString(buf);
4417 cmd += ", ";
4418 cmd += fSql->QuoteString(TimeToString(t).c_str());
4419 cmd += "";
4420 cmd += values;
4421 cmd += ");";
4422
4423 if (fSql->IsConnected()) {
4424 if (s->get_transaction_count() == 0)
4425 fSql->OpenTransaction(s->fTableName.c_str());
4426
4428
4429 int status = fSql->Exec(s->fTableName.c_str(), cmd.c_str());
4430
4431 // mh2sql who does not call hs_flush_buffers()
4432 // so we should flush the transaction by hand
4433 // some SQL engines have limited transaction buffers... K.O.
4434 if (s->get_transaction_count() > 100000) {
4435 //printf("flush table %s\n", table_name);
4436 fSql->CommitTransaction(s->fTableName.c_str());
4438 }
4439
4440 if (status != DB_SUCCESS) {
4441 return status;
4442 }
4443 } else {
4444 int status = fSql->ExecDisconnected(s->fTableName.c_str(), cmd.c_str());
4445 if (status != DB_SUCCESS) {
4446 return status;
4447 }
4448 }
4449
4450 return HS_SUCCESS;
4451}
void increment_transaction_count()
virtual int Exec(const char *sql)=0
virtual std::string QuoteString(const char *s)=0
virtual int ExecDisconnected(const char *table_name, const char *sql)=0
virtual int OpenTransaction(const char *table_name)=0
#define TID_DOUBLE
Definition midas.h:343
#define TID_SBYTE
Definition midas.h:329
#define TID_BOOL
Definition midas.h:340
#define TID_SHORT
Definition midas.h:334
#define TID_WORD
Definition midas.h:332
#define TID_BYTE
Definition midas.h:327
#define TID_CHAR
Definition midas.h:331
#define TID_INT
Definition midas.h:338
#define TID_FLOAT
Definition midas.h:341
#define TID_DWORD
Definition midas.h:336
INT cm_msg_flush_buffer()
Definition midas.cxx:881
void * data
Definition mana.cxx:268
static int offset
Definition mgd.cxx:1500
MUTEX_T * tm
Definition odbedit.cxx:39
Here is the call graph for this function:

Member Data Documentation

◆ fColumnInactive

std::vector<bool> HsSqlSchema::fColumnInactive

Definition at line 690 of file history_schema.cxx.

◆ fColumnIndexCache

std::unordered_map<std::string, size_t> HsSqlSchema::fColumnIndexCache

Definition at line 694 of file history_schema.cxx.

◆ fColumnNames

std::vector<std::string> HsSqlSchema::fColumnNames

Definition at line 688 of file history_schema.cxx.

◆ fColumnTypes

std::vector<std::string> HsSqlSchema::fColumnTypes

Definition at line 689 of file history_schema.cxx.

◆ fSql

SqlBase* HsSqlSchema::fSql = NULL

Definition at line 686 of file history_schema.cxx.

◆ fTableName

std::string HsSqlSchema::fTableName

Definition at line 687 of file history_schema.cxx.

◆ fTableTransactionCount

int HsSqlSchema::fTableTransactionCount = 0
private

Definition at line 734 of file history_schema.cxx.

◆ gfTransactionCount

std::map< SqlBase *, int > HsSqlSchema::gfTransactionCount
staticprivate

Definition at line 735 of file history_schema.cxx.


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