00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "CTB.hxx"
00013 #include "CTBsystem.hxx"
00014
00015 #include "CTBodbc.hxx"
00016 #include "CTBodbcConnect.hxx"
00017
00023
00025
00026 CTBodbcConnect::CTBodbcConnect()
00027 : m_hdbc(0),
00028 mb_connected(false),
00029 mb_trace(false)
00030 {
00031 }
00032
00033
00035
00036 CTBodbcConnect::~CTBodbcConnect()
00037 {
00038 Disconnect();
00039 }
00040
00041
00043
00044 bool CTBodbcConnect::Connect(const char* c_dcs)
00045 {
00046 RETCODE i_rc;
00047 UCHAR c_buf[257];
00048 SWORD i_buflen;
00049 float f_tretry = 0.;
00050 float f_twait = 10.;
00051
00052 if (!m_henv) {
00053 i_rc = SQLAllocEnv (&m_henv);
00054 TraceODBCCall("CTBodbcConnect::Connect->SQLAllocEnv",i_rc);
00055 if (i_rc != SQL_SUCCESS) {
00056 PrintError(cerr);
00057 return false;
00058 }
00059 }
00060
00061 if (!m_hdbc) {
00062 i_rc = SQLAllocConnect (m_henv, &m_hdbc);
00063 TraceODBCCall("CTBodbcConnect::Connect->SQLAllocConnect",i_rc);
00064 if (i_rc != SQL_SUCCESS) {
00065 PrintError(cerr);
00066 return false;
00067 }
00068 }
00069
00070 if (mb_connected) {
00071 return false;
00072 }
00073
00074 for (bool b_retry = true; b_retry;) {
00075 i_rc = SQLDriverConnect(m_hdbc, 0,
00076 (UCHAR *) c_dcs,SQL_NTS,
00077 (UCHAR *) c_buf,sizeof (c_buf),&i_buflen,
00078 SQL_DRIVER_COMPLETE);
00079 TraceODBCCall("CTBodbcConnect::Connect->SQLDriverConnect",i_rc);
00080
00081 if (i_rc != SQL_SUCCESS && i_rc != SQL_SUCCESS_WITH_INFO) {
00082 PrintError(cerr);
00083 if (f_tretry < 3600.) {
00084 cerr << "CTBodbcConnect-I Retry in "
00085 << (int) f_twait << "seconds" << endl;
00086 CTBsystem::Sleep(f_twait);
00087 f_tretry += f_twait;
00088 if (f_twait < 320.) f_twait *= 2.;
00089 } else {
00090 return false;
00091 }
00092 } else {
00093 b_retry = false;
00094 }
00095 }
00096
00097 mb_connected = true;
00098 return true;
00099 }
00100
00101
00103
00104 bool CTBodbcConnect::Disconnect()
00105 {
00106 RETCODE i_rc;
00107
00108 if (!mb_connected) return false;
00109
00110 i_rc = SQLDisconnect(m_hdbc);
00111 TraceODBCCall("CTBodbcConnect::~CTBodbcConnect->SQLDisconnect",i_rc);
00112 if (m_hdbc) {
00113 i_rc = SQLFreeConnect(m_hdbc);
00114 TraceODBCCall("CTBodbcConnect::~CTBodbcConnect->SQLFreeConnect",i_rc);
00115 }
00116 mb_connected = false;
00117 return true;
00118 }
00119
00120
00122
00123 bool CTBodbcConnect::AutoCommit(bool b_val)
00124 {
00125 RETCODE i_rc;
00126
00127 i_rc = SQLSetConnectOption(m_hdbc,SQL_AUTOCOMMIT,
00128 b_val ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
00129 TraceODBCCall("CTBodbcConnect::AutoCommit->SQLDSetConnectOption",i_rc);
00130 if (i_rc != SQL_SUCCESS && i_rc != SQL_SUCCESS_WITH_INFO) {
00131 PrintError(cerr);
00132 return false;
00133 }
00134
00135 return true;
00136 }
00137
00138
00140
00141 bool CTBodbcConnect::Commit()
00142 {
00143 RETCODE i_rc;
00144
00145 i_rc = SQLTransact(m_henv,m_hdbc,SQL_COMMIT);
00146 TraceODBCCall("CTBodbcConnect::Commit->SQLTransact",i_rc);
00147 if (i_rc != SQL_SUCCESS && i_rc != SQL_SUCCESS_WITH_INFO) {
00148 PrintError(cerr);
00149 return false;
00150 }
00151
00152 return true;
00153 }
00154
00155
00157
00158 bool CTBodbcConnect::Rollback()
00159 {
00160 RETCODE i_rc;
00161
00162 i_rc = SQLTransact(m_henv,m_hdbc,SQL_ROLLBACK);
00163 TraceODBCCall("CTBodbcConnect::Commit->SQLTransact",i_rc);
00164 if (i_rc != SQL_SUCCESS && i_rc != SQL_SUCCESS_WITH_INFO) {
00165 PrintError(cerr);
00166 return false;
00167 }
00168
00169 return true;
00170 }
00171
00172
00174
00175 bool CTBodbcConnect::Trace(bool b_trace)
00176 {
00177 bool b_old = mb_trace;
00178 mb_trace = b_trace;
00179 return b_old;
00180 }
00181
00182
00184
00185 void CTBodbcConnect::PrintError(ostream& os)
00186 {
00187 unsigned char c_state[16];
00188 unsigned char c_msg[SQL_MAX_MESSAGE_LENGTH];
00189
00190 while (SQLError(m_henv,m_hdbc,SQL_NULL_HSTMT,c_state,0,
00191 c_msg,SQL_MAX_MESSAGE_LENGTH-1,0) == SQL_SUCCESS) {
00192 os << c_msg << " SQLSTATE " << c_state << endl;
00193 }
00194 while (SQLError(m_henv,SQL_NULL_HDBC,SQL_NULL_HSTMT,c_state,0,
00195 c_msg,SQL_MAX_MESSAGE_LENGTH-1,0) == SQL_SUCCESS) {
00196 os << c_msg << " SQLSTATE " << c_state << endl;
00197 }
00198 return;
00199 }
00200
00201
00203
00204 void CTBodbcConnect::ToStream(ostream& os) const
00205 {
00206 os << "DBMS Product Information\n";
00207 PrintInfo(SQL_DBMS_NAME,"SQL_DBMS_NAME:",os);
00208 PrintInfo(SQL_DBMS_VER,"SQL_DBMS_VER:",os);
00209 PrintInfo(SQL_DATABASE_NAME,"SQL_DATABASE_NAME:",os);
00210
00211
00212
00213 PrintInfo(SQL_DATA_SOURCE_NAME,"SQL_DATA_SOURCE_NAME:",os);
00214
00215
00216
00217
00218 PrintInfo(SQL_DRIVER_NAME,"SQL_DRIVER_NAME:",os);
00219 PrintInfo(SQL_DRIVER_ODBC_VER,"SQL_DRIVER_ODBC_VER:",os);
00220 PrintInfo(SQL_DRIVER_VER,"SQL_DRIVER_VER:",os);
00221
00222
00223
00224
00225
00226
00227 PrintInfo(SQL_ODBC_VER,"SQL_ODBC_VER:",os);
00228
00229 PrintInfo(SQL_ROW_UPDATES,"SQL_ROW_UPDATES:",os);
00230 PrintInfo(SQL_SEARCH_PATTERN_ESCAPE,"SQL_SEARCH_PATTERN_ESCAPE:",os);
00231 PrintInfo(SQL_SERVER_NAME,"SQL_SERVER_NAME:",os);
00232
00233 PrintInfo(SQL_ACCESSIBLE_PROCEDURES,"SQL_ACCESSIBLE_PROCEDURES:",os);
00234 PrintInfo(SQL_ACCESSIBLE_TABLES,"SQL_ACCESSIBLE_TABLES:",os);
00235
00236
00237
00238
00239 PrintInfo(SQL_DATA_SOURCE_READ_ONLY,"SQL_DATA_SOURCE_READ_ONLY:",os);
00240
00241 PrintInfo(SQL_MULT_RESULT_SETS,"SQL_MULT_RESULT_SETS:",os);
00242 PrintInfo(SQL_MULTIPLE_ACTIVE_TXN,"SQL_MULTIPLE_ACTIVE_TXN:",os);
00243 PrintInfo(SQL_NEED_LONG_DATA_LEN,"SQL_NEED_LONG_DATA_LEN:",os);
00244
00245 PrintInfo(SQL_OWNER_TERM,"SQL_OWNER_TERM:",os);
00246 PrintInfo(SQL_PROCEDURE_TERM,"SQL_PROCEDURE_TERM:",os);
00247 PrintInfo(SQL_QUALIFIER_TERM,"SQL_QUALIFIER_TERM:",os);
00248
00249
00250
00251 PrintInfo(SQL_TABLE_TERM,"SQL_TABLE_TERM:",os);
00252
00253
00254 PrintInfo(SQL_USER_NAME,"SQL_USER_NAME:",os);
00255
00256
00257 PrintInfo(SQL_COLUMN_ALIAS,"SQL_COLUMN_ALIAS:",os);
00258
00259 PrintInfo(SQL_EXPRESSIONS_IN_ORDERBY,"SQL_EXPRESSIONS_IN_ORDERBY:",os);
00260
00261
00262
00263
00264 PrintInfo(SQL_LIKE_ESCAPE_CLAUSE,"SQL_LIKE_ESCAPE_CLAUSE:",os);
00265
00266
00267
00268 PrintInfo(SQL_ORDER_BY_COLUMNS_IN_SELECT,"SQL_ORDER_BY_COLUMNS_IN_SELECT:",os);
00269 PrintInfo(SQL_OUTER_JOINS,"SQL_OUTER_JOINS:",os);
00270
00271
00272 PrintInfo(SQL_PROCEDURES,"SQL_PROCEDURES:",os);
00273
00274 PrintInfo(SQL_QUALIFIER_NAME_SEPARATOR,"SQL_QUALIFIER_NAME_SEPARATOR:",os);
00275
00276
00277 PrintInfo(SQL_SPECIAL_CHARACTERS,"SQL_SPECIAL_CHARACTERS:",os);
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 return;
00330 }
00331
00332
00334
00339 void CTBodbcConnect::TraceODBCCall(const char* c_text, RETCODE i_rc)
00340 {
00341 if (!mb_trace) return;
00342
00343 cout << c_text << ": ";
00344 switch(i_rc){
00345 case SQL_INVALID_HANDLE:
00346 cout << "SQL_INVALID_HANDLE";
00347 break;
00348 case SQL_ERROR:
00349 cout << "SQL_ERROR";
00350 break;
00351 case SQL_SUCCESS:
00352 cout << "SQL_SUCCESS";
00353 break;
00354 case SQL_SUCCESS_WITH_INFO:
00355 cout << "SQL_SUCCESS_WITH_INFO";
00356 break;
00357 case SQL_NO_DATA_FOUND:
00358 cout << "SQL_NO_DATA_FOUND";
00359 break;
00360 default:
00361 cout << i_rc;
00362 break;
00363 }
00364 cout << endl;
00365 return;
00366 }
00367
00368
00370
00371 void CTBodbcConnect::PrintInfo(UWORD i_infotype, const char* c_prefix,
00372 ostream& os) const
00373 {
00374 RETCODE i_rc;
00375 char c_buf[256];
00376 SWORD i_rsize;
00377
00378 if (mb_connected) {
00379 i_rc = SQLGetInfo(m_hdbc,i_infotype,c_buf,256,&i_rsize);
00380 os << " " << c_prefix << " " << c_buf << "\n";
00381 }
00382 return;
00383 }
00384
00385
00386 HENV CTBodbcConnect::m_henv;
00387
00388
00389 #if (defined(CTB__OutLine) || defined(CTBodbcConnect__OutLine))
00390 #define inline
00391 #include "CTBodbcConnect.icc"
00392 #undef inline
00393 #endif