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 int 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
 
int fNumBytes = 0
 
int fCountWriteUndersize = 0
 
int fCountWriteOversize = 0
 
int fWriteMaxSize = 0
 
int fWriteMinSize = 0
 
bool fDisabled = true
 

Private Attributes

int fTableTransactionCount = 0
 

Static Private Attributes

static std::map< SqlBase *, intgfTransactionCount
 

Detailed Description

Definition at line 680 of file history_schema.cxx.

Constructor & Destructor Documentation

◆ HsSqlSchema()

HsSqlSchema::HsSqlSchema ( )
inline

Definition at line 692 of file history_schema.cxx.

693 {
694 // empty
695 }

◆ ~HsSqlSchema()

HsSqlSchema::~HsSqlSchema ( )
inline

Definition at line 697 of file history_schema.cxx.

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

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

◆ close_transaction()

int HsSqlSchema::close_transaction ( )

Definition at line 4022 of file history_schema.cxx.

4023{
4024 if (!fSql->IsConnected()) {
4025 return HS_SUCCESS;
4026 }
4027
4028 int status = HS_SUCCESS;
4029 if (get_transaction_count() > 0) {
4032 }
4033 return status;
4034}
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 708 of file history_schema.cxx.

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

◆ get_transaction_count()

int HsSqlSchema::get_transaction_count ( )

Definition at line 4475 of file history_schema.cxx.

4475 {
4476 if (!fSql || fSql->fTransactionPerTable) {
4478 } else {
4479 return gfTransactionCount[fSql];
4480 }
4481}
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 4491 of file history_schema.cxx.

4491 {
4492 if (!fSql || fSql->fTransactionPerTable) {
4494 } else {
4496 }
4497}
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 4054 of file history_schema.cxx.

4055{
4056 if (event_name_cmp(this->fTableName, event_name)==0) {
4057 for (unsigned j=0; j<this->fVariables.size(); j++) {
4058 if (var_name_cmp(this->fColumnNames[j], var_name)==0)
4059 return j;
4060 }
4061 }
4062
4063 return HsSchema::match_event_var(event_name, var_name, var_index);
4064}
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 795 of file history_schema.cxx.

796{
797 unsigned nv = this->fVariables.size();
798 printf("event [%s], sql_table [%s], time %s..%s, %d variables, %d bytes\n", this->fEventName.c_str(), this->fTableName.c_str(), TimeToString(this->fTimeFrom).c_str(), TimeToString(this->fTimeTo).c_str(), nv, fNumBytes);
799 if (print_tags) {
800 for (unsigned j=0; j<nv; j++) {
801 printf(" %d: 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);
802 printf(", sql_column [%s], sql_type [%s], offset %d", this->fColumnNames[j].c_str(), this->fColumnTypes[j].c_str(), this->fOffsets[j]);
803 printf(", inactive %d", (int)this->fColumnInactive[j]);
804 printf("\n");
805 }
806 }
807}
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:11772
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 4386 of file history_schema.cxx.

4392{
4393 bool bad_last_time = false;
4394
4395 if (debug)
4396 printf("SqlHistory::read_data: table [%s], start %s, end %s\n", fTableName.c_str(), TimeToString(start_time).c_str(), TimeToString(end_time).c_str());
4397
4398 std::string collist;
4399
4400 for (int i=0; i<num_var; i++) {
4401 int j = var_schema_index[i];
4402 if (j < 0)
4403 continue;
4404 if (collist.length() > 0)
4405 collist += ", ";
4407 }
4408
4409 std::string cmd;
4410 cmd += "SELECT _i_time, ";
4411 cmd += collist;
4412 cmd += " FROM ";
4413 cmd += fSql->QuoteId(fTableName.c_str());
4414 cmd += " WHERE _i_time>=";
4415 cmd += TimeToString(start_time);
4416 cmd += " and _i_time<=";
4417 cmd += TimeToString(end_time);
4418 cmd += " ORDER BY _i_time;";
4419
4420 int status = fSql->Prepare(fTableName.c_str(), cmd.c_str());
4421
4422 if (status != DB_SUCCESS)
4423 return HS_FILE_ERROR;
4424
4425 /* Loop through the rows in the result-set */
4426
4427 int count = 0;
4428
4429 while (1) {
4430 status = fSql->Step();
4431 if (status != DB_SUCCESS)
4432 break;
4433
4434 count++;
4435
4436 time_t t = fSql->GetTime(0);
4437
4438 if (t < start_time || t > end_time)
4439 continue;
4440
4441 int k = 0;
4442
4443 for (int i=0; i<num_var; i++) {
4444 int j = var_schema_index[i];
4445 if (j < 0)
4446 continue;
4447
4448 if (t < last_time[i]) { // protect against duplicate and non-monotonous data
4449 bad_last_time = true;
4450 } else {
4451 double v = fSql->GetDouble(1+k);
4452
4453 //printf("Column %d, index %d, Row %d, time %d, value %f\n", k, colindex[k], count, t, v);
4454
4455 buffer[i]->Add(t, v);
4456 last_time[i] = t;
4457 }
4458
4459 k++;
4460 }
4461 }
4462
4463 fSql->Finalize();
4464
4465 if (bad_last_time) {
4466 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());
4467 }
4468
4469 if (debug)
4470 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);
4471
4472 return HS_SUCCESS;
4473}
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:915
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 4339 of file history_schema.cxx.

4342{
4343 if (debug)
4344 printf("SqlHistory::read_last_written: table [%s], timestamp %s\n", fTableName.c_str(), TimeToString(timestamp).c_str());
4345
4346 std::string cmd;
4347 cmd += "SELECT _i_time FROM ";
4348 cmd += fSql->QuoteId(fTableName.c_str());
4349 cmd += " WHERE _i_time < ";
4350 cmd += TimeToString(timestamp);
4351 cmd += " ORDER BY _i_time DESC LIMIT 2;";
4352
4353 int status = fSql->Prepare(fTableName.c_str(), cmd.c_str());
4354
4355 if (status != DB_SUCCESS)
4356 return status;
4357
4358 time_t lw = 0;
4359
4360 /* Loop through the rows in the result-set */
4361
4362 while (1) {
4363 status = fSql->Step();
4364 if (status != DB_SUCCESS)
4365 break;
4366
4367 time_t t = fSql->GetTime(0);
4368
4369 if (t >= timestamp)
4370 continue;
4371
4372 if (t > lw)
4373 lw = t;
4374 }
4375
4376 fSql->Finalize();
4377
4378 *last_written = lw;
4379
4380 if (debug)
4381 printf("SqlHistory::read_last_written: table [%s], timestamp %s, last_written %s\n", fTableName.c_str(), TimeToString(timestamp).c_str(), TimeToString(lw).c_str());
4382
4383 return HS_SUCCESS;
4384}
Here is the call graph for this function:

◆ remove_inactive_columns()

void HsSqlSchema::remove_inactive_columns ( )
virtual

Implements HsSchema.

Definition at line 4141 of file history_schema.cxx.

4142{
4143 assert(fVariables.size() == fColumnInactive.size());
4144 assert(fVariables.size() == fColumnNames.size());
4145 assert(fVariables.size() == fColumnTypes.size());
4146 assert(fVariables.size() == fOffsets.size());
4147
4148 size_t count_active = 0;
4149 size_t count_inactive = 0;
4150
4151 for (size_t i=0; i<fColumnInactive.size(); i++) {
4152 if (fColumnInactive[i])
4153 count_inactive += 1;
4154 else
4155 count_active += 1;
4156 }
4157
4158 //printf("remove_inactive_columns: enter! count_active: %zu, count_inactive: %zu\n", count_active, count_inactive);
4159 //print();
4160
4161 if (count_inactive > 0) {
4162 size_t j=0;
4163
4164 for (size_t i=0; i<fColumnInactive.size(); i++) {
4165 if (fColumnInactive[i]) {
4166 // skip this entry
4167 } else {
4168 if (j != i) {
4173 fOffsets[j] = fOffsets[i];
4174 }
4175 j++;
4176 }
4177 }
4178
4179 //print();
4180 //printf("%zu %zu\n", j, count_active);
4181
4182 assert(j == count_active);
4183
4184 //print();
4185
4186 fVariables.resize(count_active);
4188 fColumnNames.resize(count_active);
4189 fColumnTypes.resize(count_active);
4190 fOffsets.resize(count_active);
4191
4192 assert(fVariables.size() == fColumnInactive.size());
4193 assert(fVariables.size() == fColumnNames.size());
4194 assert(fVariables.size() == fColumnTypes.size());
4195 assert(fVariables.size() == fOffsets.size());
4196
4197 //printf("remove_inactice_columns: exit!\n");
4198 //print();
4199 }
4200}
Here is the call graph for this function:

◆ reset_transaction_count()

void HsSqlSchema::reset_transaction_count ( )

Definition at line 4483 of file history_schema.cxx.

4483 {
4484 if (!fSql || fSql->fTransactionPerTable) {
4486 } else {
4488 }
4489}
Here is the caller graph for this function:

◆ write_event()

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

Implements HsSchema.

Definition at line 4202 of file history_schema.cxx.

4203{
4204 HsSqlSchema* s = this;
4205
4206 assert(s->fVariables.size() == s->fColumnInactive.size());
4207 assert(s->fVariables.size() == s->fColumnNames.size());
4208 assert(s->fVariables.size() == s->fColumnTypes.size());
4209 assert(s->fVariables.size() == s->fOffsets.size());
4210
4211 std::string tags;
4212 std::string values;
4213
4214 for (unsigned i=0; i<s->fVariables.size(); i++) {
4215 // NB: inactive columns should have been removed from the schema. K.O.
4216
4217 if (s->fColumnInactive[i]) {
4218 cm_msg(MERROR, "HsSqlSchema::write_event", "Internal error, unexpected inactive column %d", i);
4220 return HS_FILE_ERROR;
4221 }
4222
4223 int type = s->fVariables[i].type;
4224 int n_data = s->fVariables[i].n_data;
4225 int offset = s->fOffsets[i];
4226 const char* column_name = s->fColumnNames[i].c_str();
4227
4228 if (offset < 0) {
4229 cm_msg(MERROR, "HsSqlSchema::write_event", "Internal error, unexpected negative offset %d for column %d", offset, i);
4231 return HS_FILE_ERROR;
4232 }
4233
4234 assert(n_data == 1);
4235 assert(strlen(column_name) > 0);
4236 assert(offset < data_size);
4237
4238 void* ptr = (void*)(data+offset);
4239
4240 tags += ", ";
4241 tags += fSql->QuoteId(column_name);
4242
4243 values += ", ";
4244
4245 char buf[1024];
4246 int j=0;
4247
4248 switch (type) {
4249 default:
4250 sprintf(buf, "unknownType%d", type);
4251 break;
4252 case TID_BYTE:
4253 sprintf(buf, "%u",((unsigned char *)ptr)[j]);
4254 break;
4255 case TID_SBYTE:
4256 sprintf(buf, "%d",((signed char*)ptr)[j]);
4257 break;
4258 case TID_CHAR:
4259 // FIXME: quotes
4260 sprintf(buf, "\'%c\'",((char*)ptr)[j]);
4261 break;
4262 case TID_WORD:
4263 sprintf(buf, "%u",((unsigned short *)ptr)[j]);
4264 break;
4265 case TID_SHORT:
4266 sprintf(buf, "%d",((short *)ptr)[j]);
4267 break;
4268 case TID_DWORD:
4269 sprintf(buf, "%u",((unsigned int *)ptr)[j]);
4270 break;
4271 case TID_INT:
4272 sprintf(buf, "%d",((int *)ptr)[j]);
4273 break;
4274 case TID_BOOL:
4275 sprintf(buf, "%u",((unsigned int *)ptr)[j]);
4276 break;
4277 case TID_FLOAT:
4278 // FIXME: quotes
4279 sprintf(buf, "\'%.8g\'",((float*)ptr)[j]);
4280 break;
4281 case TID_DOUBLE:
4282 // FIXME: quotes
4283 sprintf(buf, "\'%.16g\'",((double*)ptr)[j]);
4284 break;
4285 }
4286
4287 values += buf;
4288 }
4289
4290 // 2001-02-16 20:38:40.1
4291 struct tm tms;
4292 localtime_r(&t, &tms); // somebody must call tzset() before this.
4293 char buf[1024];
4294 strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S.0", &tms);
4295
4296 std::string cmd;
4297 cmd = "INSERT INTO ";
4298 cmd += fSql->QuoteId(s->fTableName.c_str());
4299 cmd += " (_t_time, _i_time";
4300 cmd += tags;
4301 cmd += ") VALUES (";
4302 cmd += fSql->QuoteString(buf);
4303 cmd += ", ";
4304 cmd += fSql->QuoteString(TimeToString(t).c_str());
4305 cmd += "";
4306 cmd += values;
4307 cmd += ");";
4308
4309 if (fSql->IsConnected()) {
4310 if (s->get_transaction_count() == 0)
4311 fSql->OpenTransaction(s->fTableName.c_str());
4312
4314
4315 int status = fSql->Exec(s->fTableName.c_str(), cmd.c_str());
4316
4317 // mh2sql who does not call hs_flush_buffers()
4318 // so we should flush the transaction by hand
4319 // some SQL engines have limited transaction buffers... K.O.
4320 if (s->get_transaction_count() > 100000) {
4321 //printf("flush table %s\n", table_name);
4322 fSql->CommitTransaction(s->fTableName.c_str());
4324 }
4325
4326 if (status != DB_SUCCESS) {
4327 return status;
4328 }
4329 } else {
4330 int status = fSql->ExecDisconnected(s->fTableName.c_str(), cmd.c_str());
4331 if (status != DB_SUCCESS) {
4332 return status;
4333 }
4334 }
4335
4336 return HS_SUCCESS;
4337}
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:865
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 688 of file history_schema.cxx.

◆ fColumnNames

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

Definition at line 686 of file history_schema.cxx.

◆ fColumnTypes

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

Definition at line 687 of file history_schema.cxx.

◆ fSql

SqlBase* HsSqlSchema::fSql = NULL

Definition at line 684 of file history_schema.cxx.

◆ fTableName

std::string HsSqlSchema::fTableName

Definition at line 685 of file history_schema.cxx.

◆ fTableTransactionCount

int HsSqlSchema::fTableTransactionCount = 0
private

Definition at line 727 of file history_schema.cxx.

◆ gfTransactionCount

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

Definition at line 728 of file history_schema.cxx.


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