history_odbc.cxx File Reference

Go to the source code of this file.

Data Structures

class  SqlBase
class  SqlStdout
class  SqlODBC
struct  Tag
struct  Event

Defines

#define DWORD   DWORD_xxx
#define BOOL   BOOL_xxx
#define STRLCPY(dst, src)   strlcpy(dst, src, sizeof(dst))
#define FREE(x)   { if (x) free(x); x = NULL; }

Functions

static const char * midasTypeName (int tid)
static const char * midas2sqlType (int tid)
static int sql2midasType (const char *name)
static bool isCompatible (int tid, const char *sqlType)
static void PrintTags (int ntags, const TAG tags[])
int CreateEvent (SqlBase *sql, Event *e)
int WriteEvent (SqlBase *sql, Event *e, time_t t, const char *buf, int size)
int hs_debug_odbc (int debug)
int hs_set_alarm_odbc (const char *alarm_name)
int hs_connect_odbc (const char *odbc_dsn)
int hs_disconnect_odbc ()
static std::string tagName2columnName (const char *s)
static std::string eventName2tableName (const char *s)
int hs_define_event_odbc (const char *event_name, const TAG tags[], int tags_size)
int hs_write_event_odbc (const char *event_name, time_t timestamp, const char *buffer, int buffer_size)
int hs_get_tags_odbc (const char *event_name, int *n_tags, TAG **tags)
int hs_read_odbc (time_t start_time, time_t end_time, time_t interval, const char *event_name, const char *tag_name, int var_index, int *num_entries, time_t **time_buffer, double **data_buffer)

Variables

static int gTrace = 0
static std::string gAlarmName
static std::string gOdbcDsn
static time_t gNextConnect = 0
static int gConnectRetry = 0
static int tid_size []
static char * tid_name []
static char * sql_type_pgsql []
static char * sql_type_mysql []
static char ** sql_type = NULL
static SqlBasegSql = NULL
static std::vector< Event * > gEvents


Define Documentation

#define BOOL   BOOL_xxx

Definition at line 27 of file history_odbc.cxx.

Referenced by al_check(), al_trigger_alarm(), ana_end_of_run(), analyze_run(), bk_swap(), bm_check_buffers(), bm_open_buffer(), bm_push_event(), bm_receive_event(), bm_update_read_pointer(), bm_wait_for_free_space(), bor(), close_channels(), cm_check_deferred_transition(), cm_cleanup(), cm_connect_experiment1(), cm_msg(), cm_msg1(), cm_set_client_info(), cm_transition1(), cm_yield(), cmd_dir(), cmd_edit(), command_loop(), db_check_record(), db_copy(), db_delete_key1(), db_open_database(), db_paste(), db_sprintf(), db_sprintff(), el_submit(), export_hist(), find_odb_tag(), ftp_command(), ftp_good(), generate_hist_graph(), getparam(), MidasHistory::GetTagsFromEquipment(), MidasHistory::hs_read(), initialize_equipment(), lazy_copy(), lazy_main(), lazy_maintain_free_space(), log_callback(), log_write(), logger_init(), main(), midas_bank_display(), midas_bank_display32(), odb_load(), open_history(), register_equipment(), rpc_send_event(), scheduler(), server_loop(), show_alarm_page(), show_elog_delete(), show_elog_new(), show_elog_page(), show_elog_query(), show_elog_submit_query(), show_hist_config_page(), show_hist_page(), show_messages_page(), show_programs_page(), show_status_page(), source_scan(), start_the_run(), stop_the_run(), tr_start(), tr_start_fal(), tr_stop(), write_event_ascii(), write_event_hbook(), and write_event_midas().

#define DWORD   DWORD_xxx

Definition at line 26 of file history_odbc.cxx.

Referenced by al_check(), ascii_write(), bm_check_buffers(), book_ntuples(), bor(), check_polled_events(), close_channels(), cm_cleanup(), cm_shutdown(), cm_transition1(), cm_yield(), cmd_edit(), cnaf_callback(), command_loop(), db_check_record(), db_open_database(), db_sprintf(), db_sprintff(), debug_print(), dump_write(), eb_user(), eb_yfragment_add(), export_hist(), ftp_get(), ftp_put(), generate_hist_graph(), MidasHistory::GetTagsFromHS(), MidasHistory::hs_read(), initialize_equipment(), lazy_copy(), lazy_main(), lazy_maintain_free_space(), log_callback(), log_write(), lrs1151_clear(), lrs1151_read(), lrs1190_count(), lrs1190_disable(), lrs1190_enable(), lrs1190_H2Read(), lrs1190_I4Read(), lrs1190_L2Read(), lrs1190_readh2(), lrs1190_readi4(), lrs1190_readl2(), lrs1190_readl2z(), lrs1190_reset(), main(), md_all_info_display(), md_bank_event_display(), md_log_write(), md_raw_bank_display(), md_raw_event_display(), midas_bank_display(), midas_bank_display32(), midas_event_get(), midas_event_skip(), mvme_read(), mvme_read_value(), mvme_write(), mvme_write_value(), open_history(), poll_event(), print_key(), process_event(), rd1151(), rd1190(), rd1190h(), rd1190l(), read_scaler_event(), readout_thread(), register_equipment(), rotate_wheel(), rpc_server_dispatch(), sc_thread(), scaler_accum(), scan_tree(), scheduler(), send_event(), show_start_page(), show_status_page(), sis3801_CSR_read(), sis3801_dwell_time(), sis3801_input_mode(), sis3801_int_clear(), sis3801_int_source_disable(), sis3801_int_source_enable(), sis3801_IRQ_REG_read(), sis3801_IRQ_REG_write(), sis3801_module_ID(), sis3801_next_logic(), sis3801_ref1(), sis3801_Status(), SIS3803_all_bcread(), SIS3803_all_bread(), sis3803_all_clear(), sis3803_all_disable(), sis3803_all_enable(), SIS3803_all_read(), sis3803_all_read(), SIS3803_all_read_clear(), sis3803_all_read_clear(), sis3803_channel_disable(), sis3803_channel_enable(), sis3803_counter_read(), SIS3803_CSR_read(), sis3803_CSR_read(), sis3803_CSR_write(), sis3803_grp1_clear(), sis3803_grp1_read(), sis3803_grp2_clear(), sis3803_grp2_read(), sis3803_input_mode(), sis3803_int_attach(), sis3803_int_clear(), sis3803_int_source(), sis3803_int_source_disable(), sis3803_int_source_enable(), sis3803_IRQ_REG_read(), sis3803_IRQ_REG_write(), sis3803_module_ID(), sis3803_module_reset(), sis3803_OVFL_grp1_read(), sis3803_OVFL_grp2_read(), sis3803_ref1(), sis3803_single_clear(), sis3803_single_OVFL_clear(), sis3803_test_disable(), sis3803_test_enable(), source_scan(), ss_millitime(), ss_thread_create(), ss_thread_kill(), ss_time(), test_write(), tr_start_fal(), tr_stop(), update_odb(), update_stats(), v1190_DataRead(), v1190_EventRead(), v1190_TdcIdList(), v792_EventRead(), v792_EvtCntRead(), vf48_EventRead(), vf48_EventRead64(), vmeio_Async_read(), vmeio_async_read(), vmeio_clear(), vmeio_int_clear(), vmeio_int_disable(), vmeio_int_enable(), vmeio_intsync_set(), vmeio_latch_write(), vmeio_pulse_set(), vmeio_pulse_write(), vmeio_Status_read(), vmeio_status_read(), vmeio_Sync_read(), vmeio_sync_read(), vmic_mmap(), vpc6_PortRegRBRead(), vpc6_PortRegRead(), VPPGPolmskRead(), VPPGPolzFlip(), VPPGPolzRead(), VPPGRegRead(), VPPGRegWrite(), vt48_EventRead(), vt48_RegPrint(), vt48_RegRead(), vt48_Status(), write_event_ascii(), write_event_hbook(), write_event_midas(), write_event_odb(), write_history(), MidasHistory::xhs_event_id(), ybk_close(), ybk_create(), ybk_find(), ybk_iterate(), ybk_list(), ybk_locate(), and ybk_size().

#define FREE (  )     { if (x) free(x); x = NULL; }

Definition at line 38 of file history_odbc.cxx.

#define STRLCPY ( dst,
src   )     strlcpy(dst, src, sizeof(dst))

Definition at line 37 of file history_odbc.cxx.


Function Documentation

int CreateEvent ( SqlBase sql,
Event e 
)

Definition at line 693 of file history_odbc.cxx.

Referenced by hs_define_event_odbc().

00694 {
00695    int status;
00696    
00697    if (e->create) {
00698       char buf[1024];
00699       sprintf(buf, "CREATE TABLE %s (_t_time TIMESTAMP NOT NULL, _i_time INTEGER NOT NULL, INDEX (_i_time), INDEX (_t_time));", e->table_name.c_str());
00700       status = sql->Exec(buf);
00701       if (status != 0) {
00702          e->active = false;
00703          return -1;
00704       }
00705    }
00706    
00707    for (size_t i=0; i<e->tags.size(); i++)
00708       if (e->tags[i].create) {
00709          char buf[1024];
00710 
00711          sprintf(buf, "ALTER TABLE %s ADD COLUMN %s %s;",
00712                  e->table_name.c_str(),
00713                  e->tags[i].column_name.c_str(),
00714                  midas2sqlType(e->tags[i].tag.type));
00715 
00716          status = sql->Exec(buf);
00717 
00718          if (status != 0) {
00719             e->active = false;
00720             return -1;
00721          }
00722       }
00723 
00724    return 0;
00725 }

static std::string eventName2tableName ( const char *  s  )  [static]

Definition at line 911 of file history_odbc.cxx.

Referenced by hs_define_event_odbc(), hs_get_tags_odbc(), and hs_read_odbc().

00912 {
00913    return tagName2columnName(s);
00914 }

int hs_connect_odbc ( const char *  odbc_dsn  ) 

connect to given ODBC DSN, defined in $HOME/.odbc.ini, returns HS_SUCCESS

Definition at line 848 of file history_odbc.cxx.

00849 {
00850    int status;
00851 
00852    if (gSql && gSql->IsConnected())
00853       if (strcmp(gOdbcDsn.c_str(), odbc_dsn) == 0)
00854          return HS_SUCCESS;
00855    
00856    if (gSql)
00857       hs_disconnect_odbc();
00858    
00859    assert(!gSql);
00860 
00861    gOdbcDsn = odbc_dsn;
00862    
00863    if (gTrace)
00864       printf("hs_connect_odbc: set DSN to \'%s\'\n", gOdbcDsn.c_str());
00865 
00866    if (gOdbcDsn[0] == '/')
00867       gSql = new SqlStdout();
00868    else
00869       gSql = new SqlODBC();
00870    
00871    status = gSql->Connect(gOdbcDsn.c_str());
00872    if (status != 0)
00873       return HS_FILE_ERROR;
00874    
00875    return HS_SUCCESS;
00876 }

int hs_debug_odbc ( int  debug  ) 

set debug level, returns previous debug level

Definition at line 832 of file history_odbc.cxx.

00833 {
00834    int old = gTrace;
00835    gTrace = debug;
00836    return old;
00837 }

int hs_define_event_odbc ( const char *  event_name,
const TAG  tags[],
int  tags_size 
)

see hs_define_event(), returns HS_SUCCESS or HS_FILE_ERROR

Definition at line 922 of file history_odbc.cxx.

00923 {
00924    assert(gSql);
00925 
00926    int ntags = tags_size/sizeof(TAG);
00927 
00928    if (gTrace) {
00929       printf("define event [%s] with %d tags:\n", event_name, ntags);
00930       PrintTags(ntags, tags);
00931    }
00932 
00933    // delete all events with the same name
00934    for (unsigned int i=0; i<gEvents.size(); i++)
00935       if (gEvents[i])
00936          if (gEvents[i]->event_name == event_name) {
00937             printf("deleting exising event %s\n", event_name);
00938             delete gEvents[i];
00939             gEvents[i] = NULL;
00940          }
00941 
00942    Event* e = new Event();
00943 
00944    e->event_name = event_name;
00945    e->table_name = eventName2tableName(event_name);
00946    e->active = true;
00947    e->create = false;
00948 
00949    int offset = 0;
00950    for (int i=0; i<ntags; i++) {
00951       for (unsigned int j=0; j<tags[i].n_data; j++) {
00952          Tag t;
00953          t.create = false;
00954          if (tags[i].n_data == 1)
00955             t.column_name = tagName2columnName(tags[i].name);
00956          else {
00957             char s[256];
00958             sprintf(s, "_%d", j);
00959             t.column_name = tagName2columnName(tags[i].name) + s;
00960          }
00961          t.offset = offset;
00962          t.tag = tags[i];
00963          t.tag.n_data = 1;
00964          e->tags.push_back(t);
00965          int size = tid_size[tags[i].type];
00966          offset += size;
00967       }
00968    }
00969 
00970    std::vector<std::string> columns = gSql->ListColumns(e->table_name.c_str());
00971 
00972    if (columns.size() <= 0)
00973       e->create = true;
00974 
00975    for (size_t i=0; i<e->tags.size(); i++) {
00976       // check for duplicate column names
00977       for (size_t j=i+1; j<e->tags.size(); j++)
00978          if (e->tags[i].column_name == e->tags[j].column_name) {
00979             cm_msg(MERROR, "hs_define_event_odbc", "Error: History event \'%s\': Duplicated column name \'%s\' from tags %d \'%s\' and %d \'%s\'", event_name, e->tags[i].column_name.c_str(), i, e->tags[i].tag.name, j, e->tags[j].tag.name);
00980             e->active = false;
00981             break;
00982          }
00983 
00984       // check if new column needs to be created
00985       bool found = false;
00986       for (size_t j=0; j<columns.size(); j+=2) {
00987          if (e->tags[i].column_name == columns[j]) {
00988             // column exists, check data type
00989             //printf("column \'%s\', data type %s\n", e->tags[i].column_name.c_str(), columns[j+1].c_str());
00990 
00991             if (!isCompatible(e->tags[i].tag.type, columns[j+1].c_str())) {
00992                cm_msg(MERROR, "hs_define_event_odbc", "Error: History event \'%s\': Incompatible data type for tag \'%s\' type \'%s\', SQL column \'%s\' type \'%s\'", event_name, e->tags[i].tag.name, midasTypeName(e->tags[i].tag.type), columns[j].c_str(), columns[j+1].c_str());
00993                e->active = false;
00994             }
00995 
00996             found = true;
00997             break;
00998          }
00999       }
01000 
01001       if (!found) {
01002          // create it
01003          //printf("column \'%s\', data type %s  --- create!\n", e->tags[i].column_name.c_str(), midasTypeName(e->tags[i].tag.type));
01004          e->tags[i].create = true;
01005       }
01006    }
01007 
01008    int status = CreateEvent(gSql, e);
01009 
01010    if (status != 0) {
01011       // if cannot create event in SQL database, disable this event and carry on.
01012 
01013       e->active = false;
01014 
01015       if (gAlarmName.length() > 0) {
01016          char buf[256];
01017          sprintf(buf, "%s cannot define history event \'%s\', see messages", gAlarmName.c_str(), e->event_name.c_str());
01018          al_trigger_alarm(gAlarmName.c_str(), buf, "Alarm", "", AT_INTERNAL);
01019       }
01020    }
01021 
01022    // find empty slot in events list
01023    for (unsigned int i=0; i<gEvents.size(); i++)
01024       if (!gEvents[i]) {
01025          gEvents[i] = e;
01026          e = NULL;
01027          break;
01028       }
01029 
01030    // if no empty slots, add at the end
01031    if (e)
01032       gEvents.push_back(e);
01033 
01034    return HS_SUCCESS;
01035 }

int hs_disconnect_odbc (  ) 

disconnect from ODBC, returns HS_SUCCESS

Definition at line 878 of file history_odbc.cxx.

Referenced by hs_connect_odbc().

00879 {
00880    if (gTrace)
00881       printf("hs_disconnect_odbc!\n");
00882 
00883    if (gSql) {
00884       gSql->Disconnect();
00885       delete gSql;
00886       gSql = NULL;
00887    }
00888 
00889    return HS_SUCCESS;
00890 }

int hs_get_tags_odbc ( const char *  event_name,
int *  n_tags,
TAG **  tags 
)

use event names returned by hs_get_events_odbc(), see hs_get_tags(), returns HS_SUCCESS

Definition at line 1125 of file history_odbc.cxx.

01126 {
01127    assert(gSql);
01128 
01129    *n_tags = 0;
01130    *tags = NULL;
01131 
01132    std::string tname = eventName2tableName(event_name);
01133 
01134    std::vector<std::string> columns = gSql->ListColumns(tname.c_str());
01135 
01136    if (columns.size() < 1) {
01137       cm_msg(MERROR, "hs_get_tags_odbc", "Cannot get columns for table \'%s\', try to reconnect to the database", tname.c_str());
01138 
01139       gSql->Disconnect();
01140       gSql->Connect(gOdbcDsn.c_str());
01141       if (!gSql->IsConnected()) {
01142 
01143          if (gAlarmName.length() > 0) {
01144             char buf[256];
01145             sprintf(buf, "%s lost connection to the history database", gAlarmName.c_str());
01146             al_trigger_alarm(gAlarmName.c_str(), buf, "Alarm", "", AT_INTERNAL);
01147          }
01148 
01149          return HS_FILE_ERROR;
01150       }
01151 
01152       columns = gSql->ListColumns(tname.c_str());      
01153    }
01154 
01155    TAG* t = (TAG*)malloc(sizeof(TAG)*columns.size());
01156    assert(t);
01157 
01158    int n=0;
01159    for (unsigned int j=0; j<columns.size(); j+=2) {
01160       if (columns[j] == "_t_time")
01161          continue;
01162       if (columns[j] == "_i_time")
01163          continue;
01164       STRLCPY(t[n].name, columns[j].c_str());
01165       t[n].type = sql2midasType(columns[j+1].c_str());
01166       t[n].n_data = 1;
01167       n++;
01168    }
01169 
01170    if (0) {
01171       printf("event [%s] table [%s], tags: %d\n", event_name, tname.c_str(), n);
01172       PrintTags(n, t);
01173    }
01174 
01175    *n_tags = n;
01176    *tags = t;
01177 
01178    return HS_SUCCESS;
01179 }

int hs_read_odbc ( time_t  start_time,
time_t  end_time,
time_t  interval,
const char *  event_name,
const char *  tag_name,
int  var_index,
int *  num_entries,
time_t **  time_buffer,
double **  data_buffer 
)

see hs_read(), returns HS_SUCCESS

Definition at line 1181 of file history_odbc.cxx.

01185 {
01186    assert(gSql);
01187 
01188    *num_entries = 0;
01189    *time_buffer = NULL;
01190    *data_buffer = NULL;
01191 
01192    //printf("start %d, end %d, dt %d, interval %d, max points %d\n", start_time, end_time, end_time-start_time, interval, (end_time-start_time)/interval);
01193 
01194    std::string ename = eventName2tableName(event_name);
01195    std::string tname = tagName2columnName(tag_name);
01196 
01197    int status = 1;
01198 
01199    std::vector<std::string> tables = gSql->ListTables();
01200 
01201    if (tables.size() <= 1) {
01202         cm_msg(MERROR, "hs_read_odbc", "ListTables() returned nothing, trying to reconnect to the database");
01203 
01204         gSql->Disconnect();
01205         gSql->Connect(gOdbcDsn.c_str());
01206         if (!gSql->IsConnected()) {
01207 
01208            if (gAlarmName.length() > 0) {
01209               char buf[256];
01210               sprintf(buf, "%s lost connection to the history database", gAlarmName.c_str());
01211               al_trigger_alarm(gAlarmName.c_str(), buf, "Alarm", "", AT_INTERNAL);
01212            }
01213 
01214            return HS_FILE_ERROR;
01215         }
01216 
01217         tables = gSql->ListTables();
01218    }
01219 
01220    int len = strlen(event_name);
01221    for (unsigned int i=0; i<tables.size(); i++) {
01222       //printf("table %s\n", tables[i].c_str());
01223 
01224       const char* t = tables[i].c_str();
01225       const char* s = strstr(t, ename.c_str());
01226 
01227       if (s==t && (t[len]=='_'||t[len]==0)) {
01228 
01229          bool found = false;
01230          std::vector<std::string> columns = gSql->ListColumns(tables[i].c_str());
01231          for (unsigned int j=0; j<columns.size(); j+=2) {
01232             //printf("column %s\n", columns[j].c_str());
01233             if (columns[j] == tname) {
01234                found = true;
01235                break;
01236             }
01237          }
01238 
01239          if (found) {
01240             char cmd[256];
01241             sprintf(cmd, "SELECT _i_time, %s FROM %s where _i_time>=%d and _i_time<=%d;",
01242                     tname.c_str(), tables[i].c_str(),
01243                     (int)start_time, (int)end_time);
01244            
01245             status = gSql->Exec(cmd);
01246 
01247             if (gTrace) {
01248                printf("hs_read_odbc: event %s, name %s, index %d: Read table %s: status %d, nrows: %d\n",
01249                       event_name, tag_name, var_index,
01250                       tables[i].c_str(),
01251                       status,
01252                       gSql->GetNumRows());
01253             }
01254 
01255             if (status)
01256                continue;
01257 
01258             if (gSql->GetNumRows() == 0) {
01259                gSql->Done();
01260                status = SQL_NO_DATA;
01261                continue;
01262             }
01263 
01264             break;
01265          }
01266       }
01267    }
01268 
01269    if (status == SQL_NO_DATA)
01270       return HS_SUCCESS;
01271 
01272    if (status) {
01273       if (gTrace)
01274          printf("hs_read_odbc: event %s, name %s, index %d, could not find the right table? status %d\n",
01275                 event_name, tag_name, var_index,
01276                 status);
01277       
01278       return HS_FILE_ERROR;
01279    }
01280 
01281    int nrows = gSql->GetNumRows();
01282    int ncols = gSql->GetNumColumns();
01283 
01284    if (nrows == 0)
01285       return HS_SUCCESS;
01286 
01287    if (gTrace)
01288       printf("hs_read_odbc: event %s, name %s, index %d, nrows: %d, ncols: %d\n",
01289              event_name, tag_name, var_index,
01290              nrows, ncols);
01291 
01292    if (nrows < 0)
01293       return HS_FILE_ERROR;
01294 
01295    if (ncols < 1)
01296       return HS_FILE_ERROR;
01297 
01298    *num_entries = 0;
01299    *time_buffer = (time_t*)malloc(nrows * sizeof(time_t));
01300    *data_buffer = (double*)malloc(nrows * sizeof(double));
01301   
01302    /* Loop through the rows in the result-set */
01303    int row = 0;
01304    time_t tt = 0;
01305    int ann = 0;
01306    double att = 0;
01307    double avv = 0;
01308    while (gSql->Fetch()) {
01309       time_t t = 0;
01310       double v = 0;
01311      
01312       const char* timedata = gSql->GetColumn(1);
01313       if (timedata)
01314          t = atoi(timedata);
01315      
01316       const char* valuedata = gSql->GetColumn(2);
01317       if (valuedata)
01318          v = atof(valuedata);
01319      
01320       if (t < start_time || t > end_time)
01321          continue;
01322      
01323       //printf("Row %d, time %d, value %f\n", row, t, v);
01324       //printf("tt: %d, ann: %d\n", tt, ann);
01325      
01326       if (tt == 0 || t >= tt + interval) {
01327         
01328          if (ann > 0) {
01329             assert(row < nrows);
01330            
01331             (*time_buffer)[row] = (time_t)(att/ann);
01332             (*data_buffer)[row] = avv/ann;
01333            
01334             row++;
01335             (*num_entries) = row;
01336          }
01337 
01338          ann = 0;
01339          att = 0;
01340          avv = 0;
01341          tt  = t;
01342          
01343       }
01344 
01345       ann++;
01346       att += t;
01347       avv += v;
01348    }
01349 
01350    if (ann > 0) {
01351       assert(row < nrows);
01352 
01353       (*time_buffer)[row] = (time_t)(att/ann);
01354       (*data_buffer)[row] = avv/ann;
01355      
01356       row++;
01357       (*num_entries) = row;
01358    }
01359 
01360    gSql->Done();
01361 
01362    if (gTrace)
01363       printf("hs_read_odbc: return %d events\n", *num_entries);
01364 
01365    return HS_SUCCESS;
01366 }

int hs_set_alarm_odbc ( const char *  alarm_name  ) 

set alarm name for history failures. Use NULL to disable alarms

Definition at line 839 of file history_odbc.cxx.

00840 {
00841    if (alarm_name)
00842       gAlarmName = alarm_name;
00843    else
00844       gAlarmName = "";
00845    return HS_SUCCESS;
00846 }

int hs_write_event_odbc ( const char *  event_name,
time_t  timestamp,
const char *  buffer,
int  buffer_size 
)

see hs_write_event(), returns HS_SUCCESS or HS_FILE_ERROR

Definition at line 1037 of file history_odbc.cxx.

01038 {
01039    if (gTrace)
01040       printf("write event [%s] size %d\n", event_name, buffer_size);
01041 
01042    assert(gSql);
01043 
01044    // if disconnected, try to reconnect
01045 
01046    if (!gSql->IsConnected()) {
01047       time_t now = time(NULL);
01048 
01049       // too early to try reconnecting?
01050       if (gConnectRetry!=0 && now < gNextConnect) {
01051          return HS_FILE_ERROR;
01052       }
01053 
01054       int status = gSql->Connect(gOdbcDsn.c_str());
01055 
01056       if (status != 0) {
01057 
01058          // first retry in 5 seconds
01059          if (gConnectRetry == 0)
01060             gConnectRetry = 5;
01061 
01062          gNextConnect = now + gConnectRetry;
01063 
01064          // exponential backoff
01065          gConnectRetry *= 2;
01066 
01067          // but no more than every 10 minutes
01068          if (gConnectRetry > 10*60)
01069             gConnectRetry = 10*60;
01070 
01071          return HS_FILE_ERROR;
01072       }
01073    }
01074 
01075    gNextConnect = 0;
01076    gConnectRetry = 0;
01077 
01078    Event *e = NULL;
01079 
01080    // find this event
01081    for (size_t i=0; i<gEvents.size(); i++)
01082       if (gEvents[i]->event_name == event_name) {
01083          e = gEvents[i];
01084          break;
01085       }
01086 
01087    // not found
01088    if (!e)
01089       return HS_FILE_ERROR;
01090 
01091    // deactivated because of error?
01092    if (!e->active)
01093       return HS_FILE_ERROR;
01094 
01095    int status = WriteEvent(gSql, e, timestamp, buffer, buffer_size);
01096 
01097    // if could not write to SQL?
01098    if (status != 0) {
01099 
01100       // if lost SQL connection, try again later
01101       if (!gSql->IsConnected()) {
01102          return HS_FILE_ERROR;
01103       }
01104 
01105       // otherwise, deactivate this event, raise alarm
01106 
01107       e->active = 0;
01108 
01109       if (gAlarmName.length() > 0) {
01110          char buf[256];
01111          sprintf(buf, "%s cannot write history event \'%s\', see messages", gAlarmName.c_str(), e->event_name.c_str());
01112          al_trigger_alarm(gAlarmName.c_str(), buf, "Alarm", "", AT_INTERNAL);
01113       }
01114 
01115       return HS_FILE_ERROR;
01116    }
01117 
01118    return HS_SUCCESS;
01119 }

static bool isCompatible ( int  tid,
const char *  sqlType 
) [static]

Definition at line 167 of file history_odbc.cxx.

Referenced by SqlHistory::hs_define_event(), and hs_define_event_odbc().

00168 {
00169    if (0 && gTrace)
00170       printf("compare types midas \'%s\'=\'%s\' and sql \'%s\'\n", midasTypeName(tid), midas2sqlType(tid), sqlType);
00171 
00172    if (sql2midasType(sqlType) == tid)
00173       return true;
00174 
00175    if (strcasecmp(midas2sqlType(tid), sqlType) == 0)
00176       return true;
00177 
00178    // permit writing FLOAT into DOUBLE
00179    if (tid==TID_FLOAT && strcmp(sqlType, "double")==0)
00180       return true;
00181 
00182    // T2K quirk!
00183    // permit writing BYTE into signed tinyint
00184    if (tid==TID_BYTE && strcmp(sqlType, "tinyint")==0)
00185       return true;
00186 
00187    // T2K quirk!
00188    // permit writing WORD into signed tinyint
00189    if (tid==TID_WORD && strcmp(sqlType, "tinyint")==0)
00190       return true;
00191 
00192    return false;
00193 }

static const char* midas2sqlType ( int  tid  )  [static]

Definition at line 151 of file history_odbc.cxx.

Referenced by CreateEvent(), SqlHistory::hs_define_event(), and isCompatible().

00152 {
00153    assert(tid>=0);
00154    assert(tid<15);
00155    return sql_type[tid];
00156 }

static const char* midasTypeName ( int  tid  )  [static]

Definition at line 144 of file history_odbc.cxx.

Referenced by SqlHistory::hs_define_event(), hs_define_event_odbc(), isCompatible(), and PrintTags().

00145 {
00146    assert(tid>=0);
00147    assert(tid<15);
00148    return tid_name[tid];
00149 }

static void PrintTags ( int  ntags,
const TAG  tags[] 
) [static]

Definition at line 687 of file history_odbc.cxx.

Referenced by SqlHistory::hs_define_event(), hs_define_event_odbc(), and hs_get_tags_odbc().

00688 {
00689    for (int i=0; i<ntags; i++)
00690       printf("tag %d: %s %s[%d]\n", i, midasTypeName(tags[i].type), tags[i].name, tags[i].n_data);
00691 }

static int sql2midasType ( const char *  name  )  [static]

Definition at line 158 of file history_odbc.cxx.

Referenced by SqlHistory::hs_get_tags(), hs_get_tags_odbc(), and isCompatible().

00159 {
00160    for (int tid=0; tid<15; tid++)
00161       if (strcasecmp(name, sql_type[tid])==0)
00162          return tid;
00163    printf("sql2midasType: Cannot convert SQL data type \'%s\' to a MIDAS data type!\n", name);
00164    return 0;
00165 }

static std::string tagName2columnName ( const char *  s  )  [static]

Definition at line 894 of file history_odbc.cxx.

Referenced by eventName2tableName(), hs_define_event_odbc(), and hs_read_odbc().

00895 {
00896   char out[1024];
00897   int i;
00898   for (i=0; s[i]!=0; i++)
00899     {
00900       char c = s[i];
00901       if (isalpha(c) || isdigit(c))
00902         out[i] = tolower(c);
00903       else
00904         out[i] = '_';
00905     }
00906 
00907   out[i] = 0;
00908   return out;
00909 }

int WriteEvent ( SqlBase sql,
Event e,
time_t  t,
const char *  buf,
int  size 
)

Definition at line 727 of file history_odbc.cxx.

Referenced by SqlHistory::hs_write_event(), and hs_write_event_odbc().

00728 {
00729    //printf("event %d, time %s", rec.event_id, ctime(&t));
00730 
00731    int n  = e->tags.size();
00732    
00733    std::string tags;
00734    std::string values;
00735    
00736    //if (n>0)
00737    //  printf(" %s", ctime(&t));
00738    
00739    for (int i=0; i<n; i++) {
00740       const Tag*t = &e->tags[i];
00741       
00742       if (t) {
00743          int offset = t->offset;
00744          void* ptr = (void*)(buf+offset);
00745 
00746          int arraySize = t->tag.n_data;
00747          
00748          for (int j=0; j<arraySize; j++) {
00749             tags   += ", ";
00750             values += ", ";
00751             
00752             if (arraySize <= 1)
00753                tags += t->column_name;
00754             else {
00755                tags += t->column_name;
00756                char s[256];
00757                sprintf(s,"_%d", j);
00758                tags += s;
00759             }
00760                 
00761             char s[1024];
00762             
00763             switch (t->tag.type) {
00764             default:
00765                sprintf(s, "unknownType%d", t->tag.type);
00766                break;
00767             case 1: /* BYTE */
00768                sprintf(s, "%u",((uint8_t*)ptr)[j]);
00769                break;
00770             case 2: /* SBYTE */
00771                sprintf(s, "%d",((int8_t*)ptr)[j]);
00772                break;
00773             case 3: /* CHAR */
00774                sprintf(s, "\'%c\'",((char*)ptr)[j]);
00775                break;
00776             case 4: /* WORD */
00777                sprintf(s, "%u",((uint16_t*)ptr)[j]);
00778                break;
00779             case 5: /* SHORT */
00780                sprintf(s, "%d",((int16_t*)ptr)[j]);
00781                break;
00782             case 6: /* DWORD */
00783                sprintf(s, "%u",((uint32_t*)ptr)[j]);
00784                break;
00785             case 7: /* INT */
00786                sprintf(s, "%d",((int32_t*)ptr)[j]);
00787                break;
00788             case 8: /* BOOL */
00789                sprintf(s, "%u",((uint32_t*)ptr)[j]);
00790                break;
00791             case 9: /* FLOAT */
00792                sprintf(s, "\'%.8g\'",((float*)ptr)[j]);
00793                break;
00794             case 10: /* DOUBLE */
00795                sprintf(s, "\'%.16g\'",((double*)ptr)[j]);
00796                     break;
00797             }
00798             
00799             values += s;
00800          }
00801       }
00802    }
00803 
00804    // 2001-02-16 20:38:40.1
00805    char s[1024];
00806    strftime(s,sizeof(s)-1,"%Y-%m-%d %H:%M:%S.0",localtime(&t));
00807    
00808    char sss[102400];
00809    sprintf(sss, "INSERT INTO %s (_t_time, _i_time%s) VALUES (\'%s\', \'%d\'%s);",
00810            e->table_name.c_str(),
00811            tags.c_str(),
00812            s,
00813            (int)t,
00814            values.c_str());
00815 
00816    int status = sql->Exec(sss);
00817    
00818    if (status != 0) {
00819       e->active = false;
00820       return -1;
00821    }
00822 
00823    return 0;
00824 }


Variable Documentation

std::string gAlarmName [static]

Definition at line 45 of file history_odbc.cxx.

Referenced by SqlODBC::Connect(), SqlODBC::Disconnect(), hs_define_event_odbc(), hs_get_tags_odbc(), hs_read_odbc(), hs_set_alarm_odbc(), and hs_write_event_odbc().

int gConnectRetry = 0 [static]

Definition at line 48 of file history_odbc.cxx.

Referenced by hs_write_event_odbc().

std::vector<Event*> gEvents [static]

Definition at line 920 of file history_odbc.cxx.

time_t gNextConnect = 0 [static]

Definition at line 47 of file history_odbc.cxx.

Referenced by hs_write_event_odbc().

std::string gOdbcDsn [static]

Definition at line 46 of file history_odbc.cxx.

Referenced by hs_connect_odbc(), hs_get_tags_odbc(), hs_read_odbc(), and hs_write_event_odbc().

SqlBase* gSql = NULL [static]

Definition at line 830 of file history_odbc.cxx.

Referenced by hs_connect_odbc(), hs_define_event_odbc(), hs_disconnect_odbc(), hs_get_tags_odbc(), hs_read_odbc(), and hs_write_event_odbc().

int gTrace = 0 [static]

Definition at line 44 of file history_odbc.cxx.

Referenced by SqlODBC::Exec(), hs_connect_odbc(), hs_debug_odbc(), hs_define_event_odbc(), hs_disconnect_odbc(), hs_read_odbc(), hs_write_event_odbc(), isCompatible(), and SqlODBC::ReportErrors().

char** sql_type = NULL [static]

Definition at line 142 of file history_odbc.cxx.

Referenced by SqlDebug::Connect(), SqlODBC::Connect(), SqlStdout::Connect(), midas2sqlType(), and sql2midasType().

char* sql_type_mysql[] [static]

Initial value:

 {
   "xxxINVALIDxxxNULL", 
   "tinyint unsigned",  
   "tinyint",           
   "char",              
   "smallint unsigned", 
   "smallint",          
   "integer unsigned",  
   "integer",           
   "tinyint",           
   "float",             
   "double",            
   "tinyint unsigned",  
   "VARCHAR",           
   "xxxINVALIDxxxARRAY",
   "xxxINVALIDxxxSTRUCT",
   "xxxINVALIDxxxKEY",
   "xxxINVALIDxxxLINK"
}

Definition at line 118 of file history_odbc.cxx.

Referenced by SqlDebug::Connect(), SqlODBC::Connect(), and SqlStdout::Connect().

char* sql_type_pgsql[] [static]

Initial value:

 {
   "xxxINVALIDxxxNULL", 
   "SMALLINT",  
   "SMALLINT",  
   "CHAR(1)",   
   "SMALLINT",  
   "SMALLINT",  
   "INTEGER",   
   "INTEGER",   
   "BOOL",      
   "FLOAT(53)", 
   "FLOAT(53)", 
   "SMALLINT",  
   "VARCHAR",   
   "xxxINVALIDxxxARRAY",
   "xxxINVALIDxxxSTRUCT",
   "xxxINVALIDxxxKEY",
   "xxxINVALIDxxxLINK"
}

Definition at line 98 of file history_odbc.cxx.

Referenced by SqlODBC::Connect().

char* tid_name[] [static]

Initial value:

 {
   "NULL",
   "BYTE",
   "SBYTE",
   "CHAR",
   "WORD",
   "SHORT",
   "DWORD",
   "INT",
   "BOOL",
   "FLOAT",
   "DOUBLE",
   "BITFIELD",
   "STRING",
   "ARRAY",
   "STRUCT",
   "KEY",
   "LINK"
}

Definition at line 77 of file history_odbc.cxx.

Referenced by db_check_record(), db_copy(), db_paste(), db_paste_node(), midasTypeName(), and readHstFile().

int tid_size[] [static]

Initial value:

 {
   0,                           
   1,                           
   1,                           
   1,                           
   2,                           
   2,                           
   4,                           
   4,                           
   4,                           
   4,                           
   8,                           
   1,                           
   0,                           
   0,                           
   0,                           
   0,                           
   0                            
}

Definition at line 56 of file history_odbc.cxx.

Referenced by bk_find(), bk_locate(), SqlHistory::hs_define_event(), hs_define_event_odbc(), and readHstFile().


Midas DOC Version 3.0.0 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Sergio Ballestrero - Suzannah Daviel - Doxygen - Peter Green - Qing Gu - Greg Hackman - Gertjan Hofman - Paul Knowles - Exaos Lee - Rudi Meier - Glenn Moloney - Dave Morris - John M O'Donnell - Konstantin Olchanski - Renee Poutissou - Tamsen Schurman - Andreas Suter - Jan M.Wouters - Piotr Adam Zolnierczuk