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

4019{
4020 if (!fSql->IsConnected()) {
4021 return HS_SUCCESS;
4022 }
4023
4024 int status = HS_SUCCESS;
4025 if (get_transaction_count() > 0) {
4028 }
4029 return status;
4030}
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 4471 of file history_schema.cxx.

4471 {
4472 if (!fSql || fSql->fTransactionPerTable) {
4474 } else {
4475 return gfTransactionCount[fSql];
4476 }
4477}
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 4487 of file history_schema.cxx.

4487 {
4488 if (!fSql || fSql->fTransactionPerTable) {
4490 } else {
4492 }
4493}
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 4050 of file history_schema.cxx.

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

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

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

◆ remove_inactive_columns()

void HsSqlSchema::remove_inactive_columns ( )
virtual

Implements HsSchema.

Definition at line 4137 of file history_schema.cxx.

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

◆ reset_transaction_count()

void HsSqlSchema::reset_transaction_count ( )

Definition at line 4479 of file history_schema.cxx.

4479 {
4480 if (!fSql || fSql->fTransactionPerTable) {
4482 } else {
4484 }
4485}
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 4198 of file history_schema.cxx.

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