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 ()
 
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< boolfColumnInactive
 
- Public Attributes inherited from HsSchema
std::string fEventName
 
time_t fTimeFrom = 0
 
time_t fTimeTo = 0
 
std::vector< HsSchemaEntryfVariables
 
std::vector< intfOffsets
 
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 *, intgfTransactionCount
 

Detailed Description

Definition at line 681 of file history_schema.cxx.

Constructor & Destructor Documentation

◆ HsSqlSchema()

HsSqlSchema::HsSqlSchema ( )
inline

Definition at line 693 of file history_schema.cxx.

694 {
695 // empty
696 }

◆ ~HsSqlSchema()

HsSqlSchema::~HsSqlSchema ( )
inline

Definition at line 698 of file history_schema.cxx.

699 {
700 assert(get_transaction_count() == 0);
701 }
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 710 of file history_schema.cxx.

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

◆ close_transaction()

int HsSqlSchema::close_transaction ( )

Definition at line 4112 of file history_schema.cxx.

4113{
4114 if (!fSql->IsConnected()) {
4115 return HS_SUCCESS;
4116 }
4117
4118 int status = HS_SUCCESS;
4119 if (get_transaction_count() > 0) {
4122 }
4123 return status;
4124}
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:727
DWORD status
Definition odbhist.cxx:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ flush_buffers()

int HsSqlSchema::flush_buffers ( )
inlinevirtual

Implements HsSchema.

Definition at line 709 of file history_schema.cxx.

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

◆ get_transaction_count()

int HsSqlSchema::get_transaction_count ( )

Definition at line 4566 of file history_schema.cxx.

4566 {
4567 if (!fSql || fSql->fTransactionPerTable) {
4569 } else {
4570 return gfTransactionCount[fSql];
4571 }
4572}
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 4582 of file history_schema.cxx.

4582 {
4583 if (!fSql || fSql->fTransactionPerTable) {
4585 } else {
4587 }
4588}
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 4144 of file history_schema.cxx.

4145{
4146 if (event_name_cmp(this->fTableName, event_name)==0) {
4147 for (size_t j=0; j<this->fVariables.size(); j++) {
4148 if (var_name_cmp(this->fColumnNames[j], var_name)==0)
4149 return j;
4150 }
4151 }
4152
4153 return HsSchema::match_event_var(event_name, var_name, var_index);
4154}
std::vector< HsSchemaEntry > fVariables
virtual int match_event_var(const char *event_name, const char *var_name, const int var_index)
std::vector< std::string > fColumnNames
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 801 of file history_schema.cxx.

802{
803 size_t nv = this->fVariables.size();
804 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);
805 if (print_tags) {
806 for (size_t j=0; j<nv; j++) {
807 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);
808 printf(", sql_column [%s], sql_type [%s], offset %d", this->fColumnNames[j].c_str(), this->fColumnTypes[j].c_str(), this->fOffsets[j]);
809 printf(", inactive %d", (int)this->fColumnInactive[j]);
810 printf("\n");
811 }
812 }
813}
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:11786
static std::string TimeToString(time_t t)
INT type
Definition mana.cxx:269
#define name(x)
Definition midas_macro.h:24
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:

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

4483{
4484 bool bad_last_time = false;
4485
4486 if (debug)
4487 printf("SqlHistory::read_data: table [%s], start %s, end %s\n", fTableName.c_str(), TimeToString(start_time).c_str(), TimeToString(end_time).c_str());
4488
4489 std::string collist;
4490
4491 for (int i=0; i<num_var; i++) {
4492 int j = var_schema_index[i];
4493 if (j < 0)
4494 continue;
4495 if (collist.length() > 0)
4496 collist += ", ";
4498 }
4499
4500 std::string cmd;
4501 cmd += "SELECT _i_time, ";
4502 cmd += collist;
4503 cmd += " FROM ";
4504 cmd += fSql->QuoteId(fTableName.c_str());
4505 cmd += " WHERE _i_time>=";
4506 cmd += TimeToString(start_time);
4507 cmd += " and _i_time<=";
4508 cmd += TimeToString(end_time);
4509 cmd += " ORDER BY _i_time;";
4510
4511 int status = fSql->Prepare(fTableName.c_str(), cmd.c_str());
4512
4513 if (status != DB_SUCCESS)
4514 return HS_FILE_ERROR;
4515
4516 /* Loop through the rows in the result-set */
4517
4518 int count = 0;
4519
4520 while (1) {
4521 status = fSql->Step();
4522 if (status != DB_SUCCESS)
4523 break;
4524
4525 count++;
4526
4527 time_t t = fSql->GetTime(0);
4528
4529 if (t < start_time || t > end_time)
4530 continue;
4531
4532 int k = 0;
4533
4534 for (int i=0; i<num_var; i++) {
4535 int j = var_schema_index[i];
4536 if (j < 0)
4537 continue;
4538
4539 if (t < last_time[i]) { // protect against duplicate and non-monotonous data
4540 bad_last_time = true;
4541 } else {
4542 double v = fSql->GetDouble(1+k);
4543
4544 //printf("Column %d, index %d, Row %d, time %d, value %f\n", k, colindex[k], count, t, v);
4545
4546 buffer[i]->Add(t, v);
4547 last_time[i] = t;
4548 }
4549
4550 k++;
4551 }
4552 }
4553
4554 fSql->Finalize();
4555
4556 if (bad_last_time) {
4557 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());
4558 }
4559
4560 if (debug)
4561 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);
4562
4563 return HS_SUCCESS;
4564}
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:631
#define HS_FILE_ERROR
Definition midas.h:728
#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:929
DWORD last_time
Definition mana.cxx:3070
BOOL debug
debug printouts
Definition mana.cxx:254
double count
Definition mdump.cxx:33
INT i
Definition mdump.cxx:32
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 4430 of file history_schema.cxx.

4433{
4434 if (debug)
4435 printf("SqlHistory::read_last_written: table [%s], timestamp %s\n", fTableName.c_str(), TimeToString(timestamp).c_str());
4436
4437 std::string cmd;
4438 cmd += "SELECT _i_time FROM ";
4439 cmd += fSql->QuoteId(fTableName.c_str());
4440 cmd += " WHERE _i_time < ";
4441 cmd += TimeToString(timestamp);
4442 cmd += " ORDER BY _i_time DESC LIMIT 2;";
4443
4444 int status = fSql->Prepare(fTableName.c_str(), cmd.c_str());
4445
4446 if (status != DB_SUCCESS)
4447 return status;
4448
4449 time_t lw = 0;
4450
4451 /* Loop through the rows in the result-set */
4452
4453 while (1) {
4454 status = fSql->Step();
4455 if (status != DB_SUCCESS)
4456 break;
4457
4458 time_t t = fSql->GetTime(0);
4459
4460 if (t >= timestamp)
4461 continue;
4462
4463 if (t > lw)
4464 lw = t;
4465 }
4466
4467 fSql->Finalize();
4468
4469 *last_written = lw;
4470
4471 if (debug)
4472 printf("SqlHistory::read_last_written: table [%s], timestamp %s, last_written %s\n", fTableName.c_str(), TimeToString(timestamp).c_str(), TimeToString(lw).c_str());
4473
4474 return HS_SUCCESS;
4475}
Here is the call graph for this function:

◆ remove_inactive_columns()

void HsSqlSchema::remove_inactive_columns ( )
virtual

Implements HsSchema.

Definition at line 4231 of file history_schema.cxx.

4232{
4233 assert(fVariables.size() == fColumnInactive.size());
4234 assert(fVariables.size() == fColumnNames.size());
4235 assert(fVariables.size() == fColumnTypes.size());
4236 assert(fVariables.size() == fOffsets.size());
4237
4238 size_t count_active = 0;
4239 size_t count_inactive = 0;
4240
4241 for (size_t i=0; i<fColumnInactive.size(); i++) {
4242 if (fColumnInactive[i])
4243 count_inactive += 1;
4244 else
4245 count_active += 1;
4246 }
4247
4248 //printf("remove_inactive_columns: enter! count_active: %zu, count_inactive: %zu\n", count_active, count_inactive);
4249 //print();
4250
4251 if (count_inactive > 0) {
4252 size_t j=0;
4253
4254 for (size_t i=0; i<fColumnInactive.size(); i++) {
4255 if (fColumnInactive[i]) {
4256 // skip this entry
4257 } else {
4258 if (j != i) {
4263 fOffsets[j] = fOffsets[i];
4264 }
4265 j++;
4266 }
4267 }
4268
4269 //print();
4270 //printf("%zu %zu\n", j, count_active);
4271
4272 assert(j == count_active);
4273
4274 //print();
4275
4276 fVariables.resize(count_active);
4278 fColumnNames.resize(count_active);
4279 fColumnTypes.resize(count_active);
4280 fOffsets.resize(count_active);
4281
4282 assert(fVariables.size() == fColumnInactive.size());
4283 assert(fVariables.size() == fColumnNames.size());
4284 assert(fVariables.size() == fColumnTypes.size());
4285 assert(fVariables.size() == fOffsets.size());
4286
4287 //printf("remove_inactice_columns: exit!\n");
4288 //print();
4289 }
4290}
Here is the call graph for this function:

◆ reset_transaction_count()

void HsSqlSchema::reset_transaction_count ( )

Definition at line 4574 of file history_schema.cxx.

4574 {
4575 if (!fSql || fSql->fTransactionPerTable) {
4577 } else {
4579 }
4580}
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 4292 of file history_schema.cxx.

4293{
4294 HsSqlSchema* s = this;
4295
4296 assert(s->fVariables.size() == s->fColumnInactive.size());
4297 assert(s->fVariables.size() == s->fColumnNames.size());
4298 assert(s->fVariables.size() == s->fColumnTypes.size());
4299 assert(s->fVariables.size() == s->fOffsets.size());
4300
4301 std::string tags;
4302 std::string values;
4303
4304 for (size_t i=0; i<s->fVariables.size(); i++) {
4305 // NB: inactive columns should have been removed from the schema. K.O.
4306
4307 if (s->fColumnInactive[i]) {
4308 cm_msg(MERROR, "HsSqlSchema::write_event", "Internal error, unexpected inactive column %zu", i);
4310 return HS_FILE_ERROR;
4311 }
4312
4313 int type = s->fVariables[i].type;
4314 int n_data = s->fVariables[i].n_data;
4315 int offset = s->fOffsets[i];
4316 const char* column_name = s->fColumnNames[i].c_str();
4317
4318 if (offset < 0) {
4319 cm_msg(MERROR, "HsSqlSchema::write_event", "Internal error, unexpected negative offset %d for column %zu", offset, i);
4321 return HS_FILE_ERROR;
4322 }
4323
4324 assert(n_data == 1);
4325 assert(strlen(column_name) > 0);
4326 assert(offset >= 0);
4327 assert((size_t)offset < data_size);
4328
4329 void* ptr = (void*)(data+offset);
4330
4331 tags += ", ";
4332 tags += fSql->QuoteId(column_name);
4333
4334 values += ", ";
4335
4336 char buf[1024];
4337 int j=0;
4338
4339 switch (type) {
4340 default:
4341 sprintf(buf, "unknownType%d", type);
4342 break;
4343 case TID_BYTE:
4344 sprintf(buf, "%u",((unsigned char *)ptr)[j]);
4345 break;
4346 case TID_SBYTE:
4347 sprintf(buf, "%d",((signed char*)ptr)[j]);
4348 break;
4349 case TID_CHAR:
4350 // FIXME: quotes
4351 sprintf(buf, "\'%c\'",((char*)ptr)[j]);
4352 break;
4353 case TID_WORD:
4354 sprintf(buf, "%u",((unsigned short *)ptr)[j]);
4355 break;
4356 case TID_SHORT:
4357 sprintf(buf, "%d",((short *)ptr)[j]);
4358 break;
4359 case TID_DWORD:
4360 sprintf(buf, "%u",((unsigned int *)ptr)[j]);
4361 break;
4362 case TID_INT:
4363 sprintf(buf, "%d",((int *)ptr)[j]);
4364 break;
4365 case TID_BOOL:
4366 sprintf(buf, "%u",((unsigned int *)ptr)[j]);
4367 break;
4368 case TID_FLOAT:
4369 // FIXME: quotes
4370 sprintf(buf, "\'%.8g\'",((float*)ptr)[j]);
4371 break;
4372 case TID_DOUBLE:
4373 // FIXME: quotes
4374 sprintf(buf, "\'%.16g\'",((double*)ptr)[j]);
4375 break;
4376 }
4377
4378 values += buf;
4379 }
4380
4381 // 2001-02-16 20:38:40.1
4382 struct tm tms;
4383 localtime_r(&t, &tms); // somebody must call tzset() before this.
4384 char buf[1024];
4385 strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S.0", &tms);
4386
4387 std::string cmd;
4388 cmd = "INSERT INTO ";
4389 cmd += fSql->QuoteId(s->fTableName.c_str());
4390 cmd += " (_t_time, _i_time";
4391 cmd += tags;
4392 cmd += ") VALUES (";
4393 cmd += fSql->QuoteString(buf);
4394 cmd += ", ";
4395 cmd += fSql->QuoteString(TimeToString(t).c_str());
4396 cmd += "";
4397 cmd += values;
4398 cmd += ");";
4399
4400 if (fSql->IsConnected()) {
4401 if (s->get_transaction_count() == 0)
4402 fSql->OpenTransaction(s->fTableName.c_str());
4403
4405
4406 int status = fSql->Exec(s->fTableName.c_str(), cmd.c_str());
4407
4408 // mh2sql who does not call hs_flush_buffers()
4409 // so we should flush the transaction by hand
4410 // some SQL engines have limited transaction buffers... K.O.
4411 if (s->get_transaction_count() > 100000) {
4412 //printf("flush table %s\n", table_name);
4413 fSql->CommitTransaction(s->fTableName.c_str());
4415 }
4416
4417 if (status != DB_SUCCESS) {
4418 return status;
4419 }
4420 } else {
4421 int status = fSql->ExecDisconnected(s->fTableName.c_str(), cmd.c_str());
4422 if (status != DB_SUCCESS) {
4423 return status;
4424 }
4425 }
4426
4427 return HS_SUCCESS;
4428}
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:879
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 689 of file history_schema.cxx.

◆ fColumnNames

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

Definition at line 687 of file history_schema.cxx.

◆ fColumnTypes

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

Definition at line 688 of file history_schema.cxx.

◆ fSql

SqlBase* HsSqlSchema::fSql = NULL

Definition at line 685 of file history_schema.cxx.

◆ fTableName

std::string HsSqlSchema::fTableName

Definition at line 686 of file history_schema.cxx.

◆ fTableTransactionCount

int HsSqlSchema::fTableTransactionCount = 0
private

Definition at line 728 of file history_schema.cxx.

◆ gfTransactionCount

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

Definition at line 729 of file history_schema.cxx.


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