SqlODBC Class Reference

Inheritance diagram for SqlODBC:

SqlBase

Detailed Description

Definition at line 282 of file history_odbc.cxx.

Public Member Functions

 SqlODBC ()
 ~SqlODBC ()
int Connect (const char *dsn)
int Disconnect ()
bool IsConnected ()
std::vector< std::string > ListTables ()
std::vector< std::string > ListColumns (const char *table_name)
int Exec (const char *sql)
int GetNumRows ()
int GetNumColumns ()
int Fetch ()
const char * GetColumn (int icol)
int Done ()

Data Fields

bool fIsConnected
std::string fDSN
SQLHENV fEnv
SQLHDBC fDB
SQLHSTMT fStmt

Protected Member Functions

void ReportErrors (const char *from, const char *sqlfunc, int status)


Constructor & Destructor Documentation

SqlODBC::SqlODBC (  ) 

Definition at line 315 of file history_odbc.cxx.

00316 {
00317    fIsConnected = false;
00318 }

SqlODBC::~SqlODBC (  ) 

Definition at line 320 of file history_odbc.cxx.

00321 {
00322    Disconnect();
00323 }


Member Function Documentation

int SqlODBC::Connect ( const char *  dsn  )  [virtual]

Implements SqlBase.

Definition at line 325 of file history_odbc.cxx.

Referenced by Exec().

00326 {
00327    if (fIsConnected)
00328       Disconnect();
00329 
00330    fDSN = dsn;
00331 
00332    int status = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &fEnv);
00333 
00334    if (!SQL_SUCCEEDED(status)) {
00335       cm_msg(MERROR, "SqlODBC::Connect", "SQLAllocHandle(SQL_HANDLE_ENV) error %d", status);
00336       return -1;
00337    }
00338 
00339    status = SQLSetEnvAttr(fEnv,
00340                           SQL_ATTR_ODBC_VERSION, 
00341                           (void*)SQL_OV_ODBC2,
00342                           0); 
00343    if (!SQL_SUCCEEDED(status)) {
00344       cm_msg(MERROR, "SqlODBC::Connect", "SQLSetEnvAttr() error %d", status);
00345       SQLFreeHandle(SQL_HANDLE_ENV, fEnv);
00346       return -1;
00347    }
00348 
00349    status = SQLAllocHandle(SQL_HANDLE_DBC, fEnv, &fDB); 
00350    if (!SQL_SUCCEEDED(status)) {
00351       cm_msg(MERROR, "SqlODBC::Connect", "SQLAllocHandle(SQL_HANDLE_DBC) error %d", status);
00352       SQLFreeHandle(SQL_HANDLE_ENV, fEnv);
00353       exit(0);
00354    }
00355 
00356    SQLSetConnectAttr(fDB, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)5, 0);
00357 
00358    if (0) {
00359       // connect to PgSQL database
00360       
00361       sql_type = sql_type_pgsql;
00362       status = SQLConnect(fDB, (SQLCHAR*) dsn, SQL_NTS,
00363                           (SQLCHAR*) "xxx", SQL_NTS,
00364                           (SQLCHAR*) "", SQL_NTS);
00365    }
00366    
00367    if (1) {
00368       // connect to MySQL database
00369       
00370       sql_type = sql_type_mysql;
00371       status = SQLConnect(fDB, (SQLCHAR*) dsn, SQL_NTS,
00372                           (SQLCHAR*) NULL, SQL_NTS,
00373                           (SQLCHAR*) NULL, SQL_NTS);
00374    }
00375 
00376    if ((status != SQL_SUCCESS) && (status != SQL_SUCCESS_WITH_INFO)) {
00377       SQLINTEGER    V_OD_err;
00378       SQLSMALLINT   V_OD_mlen;
00379       SQLCHAR       V_OD_stat[10]; // Status SQL
00380       SQLCHAR       V_OD_msg[200];
00381       
00382       SQLGetDiagRec(SQL_HANDLE_DBC, fDB, 1, V_OD_stat, &V_OD_err, V_OD_msg, 100, &V_OD_mlen);
00383       cm_msg(MERROR, "SqlODBC::Connect", "SQLConnect() error %d, %s (%d)", status, V_OD_msg,V_OD_err);
00384       SQLFreeHandle(SQL_HANDLE_ENV, fEnv);
00385       return -1;
00386    }
00387 
00388    SQLAllocHandle(SQL_HANDLE_STMT, fDB, &fStmt);
00389 
00390    cm_msg(MINFO, "SqlODBC::Connect", "history_odbc: Connected to %s", dsn);
00391 
00392    if (gAlarmName.length()>0)
00393       al_reset_alarm(gAlarmName.c_str());
00394 
00395    fIsConnected = true;
00396 
00397    return 0;
00398 }

int SqlODBC::Disconnect (  )  [virtual]

Implements SqlBase.

Definition at line 400 of file history_odbc.cxx.

Referenced by Connect(), Exec(), and ~SqlODBC().

00401 {
00402    if (!fIsConnected)
00403       return 0;
00404 
00405    SQLDisconnect(fDB);
00406 
00407    SQLFreeHandle(SQL_HANDLE_DBC,  fDB);
00408    SQLFreeHandle(SQL_HANDLE_STMT, fStmt);
00409    SQLFreeHandle(SQL_HANDLE_ENV,  fEnv);
00410 
00411    fIsConnected = false;
00412 
00413    if (gAlarmName.length() > 0) {
00414       char buf[256];
00415       sprintf(buf, "%s lost connection to the history database", gAlarmName.c_str());
00416       al_trigger_alarm(gAlarmName.c_str(), buf, "Alarm", "", AT_INTERNAL);
00417    }
00418 
00419    return 0;
00420 }

int SqlODBC::Done (  )  [virtual]

Implements SqlBase.

Definition at line 624 of file history_odbc.cxx.

Referenced by ListColumns(), and ListTables().

00625 {
00626    int status = SQLCloseCursor(fStmt);
00627    if (!SQL_SUCCEEDED(status)) {
00628       ReportErrors("SqlODBC::Done", "SQLCloseCursor()", status);
00629       return -1;
00630    }
00631    return 0;
00632 }

int SqlODBC::Exec ( const char *  sql  )  [virtual]

Implements SqlBase.

Definition at line 548 of file history_odbc.cxx.

00549 {
00550    if (!fIsConnected)
00551       return -1;
00552     
00553    int status;
00554 
00555    for (int i=0; i<2; i++) {
00556       if (gTrace)
00557          printf("SqlODBC::Exec: %s\n", sql);
00558 
00559       status = SQLExecDirect(fStmt,(SQLCHAR*)sql,SQL_NTS);
00560 
00561       if (SQL_SUCCEEDED(status)) {
00562          return 0;
00563       }
00564 
00565       if (gTrace)
00566          printf("SqlODBC::Exec: SQLExecDirect() error %d: SQL command: \"%s\"\n", status, sql);
00567       
00568       ReportErrors("SqlODBC::Exec", "SQLExecDirect()", status);
00569       
00570       cm_msg(MINFO, "SqlODBC::Exec", "history_odbc: Trying to reconnect to %s", fDSN.c_str());
00571 
00572       // try to reconnect
00573       std::string dsn = fDSN;
00574       Disconnect();
00575       Connect(dsn.c_str());
00576 
00577       if (!fIsConnected) {
00578          cm_msg(MERROR, "SqlODBC::Exec", "history_odbc: Reconnect to %s failed. Database is down?", fDSN.c_str());
00579       }
00580    }
00581 
00582    return 0;
00583 }

int SqlODBC::Fetch (  )  [virtual]

Implements SqlBase.

Definition at line 609 of file history_odbc.cxx.

Referenced by ListColumns(), and ListTables().

00610 {
00611    int status = SQLFetch(fStmt);
00612 
00613    if (status == SQL_NO_DATA)
00614       return 0;
00615 
00616    if (!SQL_SUCCEEDED(status)) {
00617       ReportErrors("SqlODBC::Fetch", "SQLFetch()", status);
00618       return -1;
00619    }
00620 
00621    return 1;
00622 }

const char * SqlODBC::GetColumn ( int  icol  )  [virtual]

Implements SqlBase.

Definition at line 634 of file history_odbc.cxx.

Referenced by ListColumns(), and ListTables().

00635 {
00636   static char buf[1024];
00637   SQLINTEGER indicator;
00638   int status = SQLGetData(fStmt, icol, SQL_C_CHAR, buf, sizeof(buf), &indicator);
00639 
00640   if (!SQL_SUCCEEDED(status)) {
00641     return NULL;
00642   }
00643 
00644   if (indicator == SQL_NULL_DATA)
00645     return NULL;
00646 
00647   return buf;
00648 }

int SqlODBC::GetNumColumns (  )  [virtual]

Implements SqlBase.

Definition at line 597 of file history_odbc.cxx.

Referenced by ListColumns(), and ListTables().

00598 {
00599    SQLSMALLINT ncols = 0;
00600    /* How many columns are there */
00601    int status = SQLNumResultCols(fStmt, &ncols);
00602    if (!SQL_SUCCEEDED(status)) {
00603       ReportErrors("SqlODBC::GetNumColumns", "SQLNumResultCols()", status);
00604       return -1;
00605    }
00606    return ncols;
00607 }

int SqlODBC::GetNumRows (  )  [virtual]

Implements SqlBase.

Definition at line 585 of file history_odbc.cxx.

Referenced by ListColumns(), and ListTables().

00586 {
00587    SQLINTEGER nrows = 0;
00588    /* How many rows are there */
00589    int status = SQLRowCount(fStmt, &nrows);
00590    if (!SQL_SUCCEEDED(status)) {
00591       ReportErrors("SqlODBC::GetNumRow", "SQLRowCount()", status);
00592       return -1;
00593    }
00594    return nrows;
00595 }

bool SqlODBC::IsConnected (  )  [virtual]

Implements SqlBase.

Definition at line 422 of file history_odbc.cxx.

00423 {
00424    return fIsConnected;
00425 }

std::vector< std::string > SqlODBC::ListColumns ( const char *  table_name  )  [virtual]

Implements SqlBase.

Definition at line 504 of file history_odbc.cxx.

00505 {
00506    std::vector<std::string> list;
00507 
00508    if (!fIsConnected)
00509       return list;
00510 
00511    /* Retrieve a list of tables */
00512    int status = SQLColumns(fStmt, NULL, 0, NULL, 0, (SQLCHAR*)table, SQL_NTS, NULL, 0);
00513    if (!SQL_SUCCEEDED(status)) {
00514       ReportErrors("SqlODBC::ListColumns", "SQLColumns()", status);
00515       return list;
00516    }
00517 
00518    int ncols = GetNumColumns();
00519    int nrows = GetNumRows(); // nrows seems to be always "-1"
00520 
00521    if (ncols <= 0 /*|| nrows <= 0*/) {
00522       cm_msg(MERROR, "SqlODBC::ListColumns", "Error: SQLColumns(\'%s\') returned unexpected number of columns %d or number of rows %d, status %d", table, ncols, nrows, status);
00523    }
00524 
00525    //printf("get columns [%s]: status %d, ncols %d, nrows %d\n", table, status, ncols, nrows);
00526 
00527    int row = 0;
00528    while (Fetch()) {
00529       if (0) {
00530          printf("row %d: ", row);
00531          for (int i=1; i<=ncols; i++) {
00532             const char* s = GetColumn(i);
00533             printf("[%s]", s);
00534          }
00535          printf("\n");
00536          row++;
00537       }
00538 
00539       list.push_back(GetColumn(4)); // column name
00540       list.push_back(GetColumn(6)); // column type
00541    }
00542 
00543    Done();
00544 
00545    return list;
00546 }

std::vector< std::string > SqlODBC::ListTables (  )  [virtual]

Implements SqlBase.

Definition at line 463 of file history_odbc.cxx.

00464 {
00465    std::vector<std::string> list;
00466 
00467    if (!fIsConnected)
00468       return list;
00469 
00470    /* Retrieve a list of tables */
00471    int status = SQLTables(fStmt, NULL, 0, NULL, 0, NULL, 0, (SQLCHAR*)"TABLE", SQL_NTS);
00472    if (!SQL_SUCCEEDED(status)) {
00473       ReportErrors("SqlODBC::ListTables", "SQLTables()", status);
00474       return list;
00475    }
00476 
00477    int ncols = GetNumColumns();
00478    int nrows = GetNumRows();
00479 
00480    if (ncols <= 0 || nrows <= 0) {
00481       cm_msg(MERROR, "SqlODBC::ListTables", "Error: SQLTables() returned unexpected number of columns %d or number of rows %d, status %d", ncols, nrows, status);
00482    }
00483 
00484    int row = 0;
00485    while (Fetch()) {
00486       if (0) {
00487          printf("row %d: ", row);
00488          for (int i=1; i<=ncols; i++) {
00489             const char* s = GetColumn(i);
00490             printf("[%s]", s);
00491          }
00492          printf("\n");
00493          row++;
00494       }
00495 
00496       list.push_back(GetColumn(3));
00497    }
00498 
00499    Done();
00500 
00501    return list;
00502 }

void SqlODBC::ReportErrors ( const char *  from,
const char *  sqlfunc,
int  status 
) [protected]

Definition at line 427 of file history_odbc.cxx.

Referenced by Done(), Exec(), Fetch(), GetNumColumns(), GetNumRows(), ListColumns(), and ListTables().

00428 {
00429    if (gTrace)
00430       printf("%s: %s error %d\n", from, sqlfunc, status);
00431 
00432    for (int i=1; ; i++) {
00433       SQLCHAR            state[10]; // Status SQL
00434       SQLINTEGER                 error;
00435       SQLCHAR              message[1024];
00436       SQLSMALLINT                mlen;
00437       
00438       status = SQLGetDiagRec(SQL_HANDLE_STMT,
00439                              fStmt,
00440                              i,
00441                              state,
00442                              &error,
00443                              message,
00444                              sizeof(message),
00445                              &mlen);
00446       
00447       if (status == SQL_NO_DATA)
00448          break;
00449 
00450       if (!SQL_SUCCEEDED(status)) {
00451          cm_msg(MERROR, "SqlODBC::ReportErrors", "SQLGetDiagRec() error %d", status);
00452          break;
00453       }
00454       
00455       if (1 || (error != 1060) && (error != 1050)) {
00456          if (gTrace)
00457             printf("%s: %s error: state: \'%s\', message: \'%s\', native error: %d\n", from, sqlfunc, state, message, error);
00458          cm_msg(MERROR, from, "%s error: state: \'%s\', message: \'%s\', native error: %d", sqlfunc, state, message, error);
00459       }
00460    }
00461 }


Field Documentation

SQLHDBC SqlODBC::fDB

Definition at line 290 of file history_odbc.cxx.

Referenced by Connect(), and Disconnect().

std::string SqlODBC::fDSN

Definition at line 287 of file history_odbc.cxx.

Referenced by Connect(), and Exec().

SQLHENV SqlODBC::fEnv

Definition at line 289 of file history_odbc.cxx.

Referenced by Connect(), and Disconnect().

bool SqlODBC::fIsConnected

Definition at line 285 of file history_odbc.cxx.

Referenced by Connect(), Disconnect(), Exec(), IsConnected(), ListColumns(), ListTables(), and SqlODBC().

SQLHSTMT SqlODBC::fStmt

Definition at line 291 of file history_odbc.cxx.

Referenced by Connect(), Disconnect(), Done(), Exec(), Fetch(), GetColumn(), GetNumColumns(), GetNumRows(), ListColumns(), ListTables(), and ReportErrors().


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