00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #include        "odbcpp/handle.h"
00025 #include        <sstream>
00026 #include        <iostream>
00027 
00028 
00029 namespace odbcpp
00030 {
00031 
00032 
00121 diag_t::diag_t() :
00122         
00123         
00124         
00125         
00126         f_native_errno(0)
00127 {
00128 }
00129 
00130 
00138 std::string diag_t::msg() const
00139 {
00140         std::ostringstream      result;
00141 
00142         result << "[server:" << f_server
00143                 << "][connection:" << f_connection
00144                 << "][state:" << f_odbc_state
00145                 << "][native_errno:" << f_native_errno
00146                 << "] " << f_message;
00147 
00148         return result.str();
00149 }
00150 
00151 
00152 
00153 
00154 
00191 diagnostic::diagnostic(SQLINTEGER odbcpp_errno, const std::string& message)
00192 {
00193         diag_t d;
00194 
00195         
00196         
00197         d.f_message = message;
00198         d.f_odbc_state = "HY000";
00199         d.f_native_errno = odbcpp_errno;
00200 
00201         f_diag.push_back(d);
00202 }
00203 
00204 
00216 diagnostic::diagnostic(SQLSMALLINT handle_type, SQLHANDLE hdl, handle *parent)
00217 {
00218         if(hdl == 0) {
00219                 if(parent == 0) {
00220                         diag_t d;
00221 
00222                         
00223                         
00224                         d.f_message = "no handle available to read an error";
00225                         d.f_odbc_state = "HY001";
00226                         d.f_native_errno = odbcpp_error::ODBCPP_INTERNAL;
00227 
00228                         f_diag.push_back(d);
00229                 }
00230                 else {
00231                         set(parent->get_handle_type(), parent->get_handle());
00232                 }
00233         }
00234         else {
00235                 set(handle_type, hdl);
00236         }
00237 }
00238 
00239 
00240 
00241 
00274 void diagnostic::set(SQLSMALLINT handle_type, SQLHANDLE handle)
00275 {
00276         SQLSMALLINT     record;
00277 
00278         
00279         
00280         
00281         get_length(handle_type, handle, 0, SQL_DIAG_ROW_COUNT, f_affected_rows);
00282 
00283         
00284         for(record = 1;; ++record) {
00285                 diag_t d;
00286                 if(!get_string(handle_type, handle, record, SQL_DIAG_SERVER_NAME, d.f_server)) {
00287                         return;
00288                 }
00289                 if(!get_string(handle_type, handle, record, SQL_DIAG_CONNECTION_NAME, d.f_connection)) {
00290                         return;
00291                 }
00292                 if(!get_string(handle_type, handle, record, SQL_DIAG_MESSAGE_TEXT, d.f_message)) {
00293                         return;
00294                 }
00295                 if(!get_integer(handle_type, handle, record, SQL_DIAG_NATIVE, d.f_native_errno)) {
00296                         return;
00297                 }
00298                 if(!get_string(handle_type, handle, record, SQL_DIAG_SQLSTATE, d.f_odbc_state)) {
00299                         return;
00300                 }
00301                 f_diag.push_back(d);
00302         }
00303 }
00304 
00305 
00313 std::string diagnostic::msg() const
00314 {
00315         std::string     result;
00316         SQLSMALLINT     record;
00317 
00318         for(record = 0; record < size(); ++record) {
00319                 if(!result.empty()) {
00320                         result += "\n";
00321                 }
00322                 result += f_diag[record].msg();
00323         }
00324 
00325         return result;
00326 }
00327 
00328 
00397 bool diagnostic::get_string(SQLSMALLINT handle_type, SQLHANDLE handle,
00398                 SQLSMALLINT record, SQLSMALLINT identifier, std::string& string)
00399 {
00400         SQLCHAR         buffer[1024];
00401         SQLSMALLINT     size;
00402         SQLRETURN       return_code;
00403 
00404         
00405         string.clear();
00406 
00407         
00408         size = sizeof(buffer);  
00409         return_code = SQLGetDiagField(handle_type, handle, record,
00410                 identifier, buffer, sizeof(buffer), &size);
00411 
00412         switch(return_code) {
00413         case SQL_SUCCESS:
00414         case SQL_SUCCESS_WITH_INFO:     
00415                 break;
00416 
00417         
00418         
00419         
00420 
00421         default:
00422         
00423                 
00424                 
00425                 return false;
00426 
00427         }
00428         
00429         buffer[sizeof(buffer) - 1] = '\0';
00430         string = reinterpret_cast<char *>(buffer);
00431 
00432         return true;
00433 }
00434 
00435 
00455 bool diagnostic::get_integer(SQLSMALLINT handle_type, SQLHANDLE handle,
00456                 SQLSMALLINT record, SQLSMALLINT identifier, SQLINTEGER& integer)
00457 {
00458         SQLSMALLINT     size;
00459         SQLRETURN       return_code;
00460 
00461         
00462         integer = 0;
00463 
00464         size = sizeof(integer);
00465         return_code = SQLGetDiagField(handle_type, handle, record,
00466                         identifier, &integer, sizeof(integer), &size);
00467         switch(return_code) {
00468         case SQL_SUCCESS:
00469         case SQL_SUCCESS_WITH_INFO:     
00470                 break;
00471 
00472         
00473         
00474         
00475 
00476         default:
00477         
00478                 
00479                 
00480                 return false;
00481 
00482         }
00483 
00484         return true;
00485 }
00486 
00487 
00507 bool diagnostic::get_length(SQLSMALLINT handle_type, SQLHANDLE handle,
00508                 SQLSMALLINT record, SQLSMALLINT identifier, SQLLEN& length)
00509 {
00510         SQLSMALLINT     size;
00511         SQLRETURN       return_code;
00512 
00513         
00514         length = 0;
00515 
00516         size = sizeof(length);
00517         return_code = SQLGetDiagField(handle_type, handle, record,
00518                         identifier, &length, sizeof(length), &size);
00519         switch(return_code) {
00520         case SQL_SUCCESS:
00521         case SQL_SUCCESS_WITH_INFO:     
00522                 break;
00523 
00524         
00525         
00526         
00527 
00528         default:
00529         
00530                 
00531                 
00532                 return false;
00533 
00534         }
00535 
00536         return true;
00537 }
00538 
00539 
00560 }       
00561 
00562 
00563