Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

OdbcDatabaseLayer.cpp

Go to the documentation of this file.
00001 #include "../include/OdbcDatabaseLayer.h"
00002 #include "../include/OdbcPreparedStatement.h"
00003 #include "../include/OdbcResultSet.h"
00004 #include "../include/DatabaseErrorCodes.h"
00005 
00006 
00007 // ctor()
00008 OdbcDatabaseLayer::OdbcDatabaseLayer()
00009  : DatabaseLayer()
00010 {
00011    ResetErrorCodes();
00012 
00013    SQLRETURN nRet = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_sqlEnvHandle);
00014    if ( nRet != SQL_SUCCESS )
00015    {
00016      InterpretErrorCodes( nRet );
00017      ThrowDatabaseException();
00018    }
00019 
00020    nRet = SQLSetEnvAttr(m_sqlEnvHandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
00021    if ( nRet != SQL_SUCCESS )
00022    {
00023      InterpretErrorCodes( nRet );
00024      ThrowDatabaseException();
00025    }
00026 
00027    nRet = SQLAllocHandle(SQL_HANDLE_DBC, m_sqlEnvHandle, &m_sqlHDBC);
00028    if ( nRet != SQL_SUCCESS )
00029    {
00030      InterpretErrorCodes( nRet );
00031      ThrowDatabaseException();
00032    }
00033 
00034    m_sqlStatementHandle = NULL;
00035 
00036    m_strDSN = wxEmptyString;
00037    m_strUser = wxEmptyString;
00038    m_strPassword = wxEmptyString;
00039    m_strConnection = wxEmptyString;
00040 #if wxUSE_GUI
00041    m_bPrompt = false;
00042    m_pParent = NULL;
00043 #endif
00044 }
00045 
00046 OdbcDatabaseLayer::~OdbcDatabaseLayer()
00047 {
00048    Close();
00049 
00050    SQLRETURN nRet = SQLFreeHandle(SQL_HANDLE_DBC, m_sqlHDBC);
00051    if ( nRet != SQL_SUCCESS )
00052    {
00053      InterpretErrorCodes( nRet );
00054      ThrowDatabaseException();
00055    }
00056 
00057    nRet = SQLFreeHandle(SQL_HANDLE_ENV, m_sqlEnvHandle);
00058    if ( nRet != SQL_SUCCESS )
00059    {
00060      InterpretErrorCodes( nRet );
00061      ThrowDatabaseException();
00062    }
00063 }
00064 
00065 bool OdbcDatabaseLayer::Open( )
00066 {
00067    ResetErrorCodes();
00068 
00069    if ( !m_strDSN.IsEmpty() )
00070    {
00071      //wxCharBuffer dsnCharBuffer = ConvertToUnicodeStream(m_strDSN);
00072      //wxCharBuffer userCharBuffer = ConvertToUnicodeStream(m_strUser);
00073      //wxCharBuffer passwordCharBuffer = ConvertToUnicodeStream(m_strPassword);
00074      void* dsnCharBuffer = (void*)m_strDSN.c_str();
00075      void* userCharBuffer = (void*)m_strUser.c_str();
00076      void* passwordCharBuffer = (void*)m_strPassword.c_str();
00077      
00078      SQLRETURN nRet;
00079      nRet = SQLConnect(m_sqlHDBC, (SQLTCHAR FAR*)(const char*)dsnCharBuffer,
00080                 SQL_NTS, (SQLTCHAR FAR*)(const char*)userCharBuffer, SQL_NTS,
00081                 (SQLTCHAR FAR*)(const char*)passwordCharBuffer, SQL_NTS);
00082      if ( nRet != SQL_SUCCESS )
00083      {
00084        InterpretErrorCodes( nRet );
00085        ThrowDatabaseException();
00086      }
00087    }
00088    else if ( !m_strConnection.IsEmpty() )
00089    {
00090      SQLTCHAR buff[8192];
00091      SQLSMALLINT iLen;
00092 
00093      memset(buff, 0, 8192*sizeof(SQLTCHAR));
00094      
00095      //wxCharBuffer connectionCharBuffer = ConvertToUnicodeStream(m_strConnection);
00096      void* connectionCharBuffer = (void*)m_strConnection.c_str();
00097 #if wxUSE_GUI
00098      SQLRETURN nRet = SQLDriverConnect(m_sqlHDBC, m_pParent ? (SQLHWND)m_pParent->GetHandle() : NULL, (SQLTCHAR*)(const char*)connectionCharBuffer,
00099          (SQLSMALLINT)m_strConnection.Length(), (SQLTCHAR*)buff, 8192, &iLen, m_bPrompt ? SQL_DRIVER_PROMPT : SQL_DRIVER_NOPROMPT);
00100 #else
00101      SQLRETURN nRet = SQLDriverConnect(m_sqlHDBC, NULL, (SQLTCHAR*)(const char*)connectionCharBuffer,
00102          (SQLSMALLINT)m_strConnection.Length(), (SQLTCHAR*)buff, 8192, &iLen, SQL_DRIVER_NOPROMPT);
00103 #endif
00104 
00105      if ( nRet != SQL_SUCCESS )
00106      {
00107        InterpretErrorCodes( nRet );
00108        ThrowDatabaseException();
00109      }
00110    }
00111    else
00112    {
00113      return false;
00114    }
00115 
00116    m_bIsConnected = true;    
00117         
00118    return true;
00119 }
00120 
00121 bool OdbcDatabaseLayer::Open( const wxString& strConnection )
00122 {
00123     m_strDSN = wxEmptyString;
00124     m_strUser = wxEmptyString;
00125     m_strPassword = wxEmptyString;
00126     m_strConnection = strConnection;
00127 #if wxUSE_GUI
00128     m_bPrompt = false;
00129     m_pParent = NULL;
00130 #endif
00131 
00132     return Open();
00133 }
00134 
00135 #if wxUSE_GUI
00136 bool OdbcDatabaseLayer::Open(const wxString& strConnection, bool bPromptForInfo, wxWindow* parent)
00137 {
00138     m_strConnection = strConnection;
00139     m_bPrompt = bPromptForInfo;
00140     m_pParent = parent;
00141     m_strDSN = wxEmptyString;
00142     m_strUser = wxEmptyString;
00143     m_strPassword = wxEmptyString;
00144 
00145     return Open();
00146 }
00147 #endif
00148 
00149 bool OdbcDatabaseLayer::Open( const wxString& strDSN, const wxString& strUser, const wxString& strPassword )
00150 {
00151     m_strDSN = strDSN;
00152     m_strUser = strUser;
00153     m_strPassword = strPassword;
00154     m_strConnection = wxEmptyString;
00155 #if wxUSE_GUI
00156     m_bPrompt = false;
00157     m_pParent = NULL;
00158 #endif
00159         
00160     return Open();
00161 }
00162 
00163 bool OdbcDatabaseLayer::Close()
00164 {
00165    ResetErrorCodes();
00166 
00167    CloseResultSets();
00168    CloseStatements();
00169 
00170    if (m_bIsConnected) 
00171    {
00172       SQLRETURN nRet = SQLDisconnect(m_sqlHDBC);
00173       if ( nRet != SQL_SUCCESS )
00174       {
00175         InterpretErrorCodes( nRet );
00176         ThrowDatabaseException();
00177       }
00178 
00179       m_bIsConnected=false;
00180    }
00181 
00182    return true;
00183 }
00184 
00185 void OdbcDatabaseLayer::BeginTransaction()
00186 {
00187    ResetErrorCodes();
00188 
00189    SQLRETURN nRet = SQLSetConnectAttr(m_sqlHDBC, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0);
00190    if ( nRet != SQL_SUCCESS )
00191    {
00192      InterpretErrorCodes( nRet );
00193      ThrowDatabaseException();
00194    }
00195 }
00196 
00197 void OdbcDatabaseLayer::Commit()
00198 {
00199    ResetErrorCodes();
00200 
00201    SQLRETURN nRet = SQLEndTran(SQL_HANDLE_DBC, m_sqlHDBC, SQL_COMMIT);
00202    if ( nRet != SQL_SUCCESS )
00203    {
00204      InterpretErrorCodes( nRet );
00205      ThrowDatabaseException();
00206    }
00207 
00208    nRet = SQLSetConnectAttr(m_sqlHDBC, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_INTEGER);
00209    if ( nRet != SQL_SUCCESS )
00210    {
00211      InterpretErrorCodes( nRet );
00212      ThrowDatabaseException();
00213    }
00214 }
00215 
00216 void OdbcDatabaseLayer::RollBack()
00217 {
00218    ResetErrorCodes();
00219 
00220    SQLRETURN nRet = SQLEndTran(SQL_HANDLE_DBC, m_sqlHDBC, SQL_ROLLBACK);
00221    if ( nRet != SQL_SUCCESS )
00222    {
00223      InterpretErrorCodes( nRet );
00224      ThrowDatabaseException();
00225    }
00226    
00227    nRet = SQLSetConnectAttr(m_sqlHDBC, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_INTEGER);
00228    if ( nRet != SQL_SUCCESS )
00229    {
00230      InterpretErrorCodes( nRet );
00231      ThrowDatabaseException();
00232    }
00233 }
00234 
00235 bool OdbcDatabaseLayer::RunQuery( const wxString& strQuery, bool bParseQuery )
00236 {
00237    ResetErrorCodes();
00238 
00239    //wxPrintf("Running: '%s'\n", strQuery.c_str());
00240    OdbcPreparedStatement* pStatement = (OdbcPreparedStatement*)PrepareStatement( strQuery, bParseQuery );
00241 
00242    if ( pStatement )
00243    {
00244      try
00245      {
00246        pStatement->RunQuery();
00247        wxDELETE( pStatement );
00248        return true;
00249      }
00250      catch (...)
00251      {
00252        wxDELETE( pStatement );
00253        ThrowDatabaseException();
00254        return false;
00255      }
00256    }
00257    else
00258      return false;
00259 }
00260 
00261 DatabaseResultSet* OdbcDatabaseLayer::RunQueryWithResults(const wxString& strQuery)
00262 {
00263    ResetErrorCodes();
00264 
00265    OdbcPreparedStatement* pStatement = (OdbcPreparedStatement*)PrepareStatement( strQuery, true );
00266 
00267    if ( pStatement )
00268    {
00269      try
00270      {
00271        pStatement->SetOneTimer(true);
00272        DatabaseResultSet* pResults = pStatement->RunQueryWithResults(false /*false for "Don't log this result set for cleanup*/);
00273        LogResultSetForCleanup(pResults);
00274        return pResults;
00275      }
00276      catch (...)
00277      {
00278        wxDELETE( pStatement );
00279        ThrowDatabaseException();
00280        return NULL;
00281      }
00282    }
00283    else
00284      return NULL;
00285 }
00286 
00287 SQLHANDLE OdbcDatabaseLayer::allocStmth()
00288 {
00289     ResetErrorCodes();
00290 
00291     SQLHANDLE handle = NULL;
00292         
00293     SQLRETURN nRet = SQLAllocHandle (SQL_HANDLE_STMT, m_sqlHDBC, &handle);
00294     if ( nRet != SQL_SUCCESS )
00295     {
00296         InterpretErrorCodes( nRet );
00297         ThrowDatabaseException();
00298     }
00299     return handle;
00300 }
00301 
00302 PreparedStatement* OdbcDatabaseLayer::PrepareStatement( const wxString& strQuery )
00303 {
00304   PreparedStatement* pStatement = PrepareStatement(strQuery, true);
00305   LogStatementForCleanup(pStatement);
00306   return pStatement;
00307 }
00308 
00309 PreparedStatement* OdbcDatabaseLayer::PrepareStatement( const wxString& strQuery, bool bParseQuery )
00310 {
00311     ResetErrorCodes();
00312 
00313     wxArrayString QueryArray;
00314     if (bParseQuery)
00315       QueryArray = ParseQueries(strQuery);
00316     else
00317       QueryArray.push_back(strQuery);
00318 
00319     OdbcPreparedStatement* pReturnStatement = new OdbcPreparedStatement(m_sqlEnvHandle, m_sqlHDBC);
00320 
00321     if (pReturnStatement)
00322         pReturnStatement->SetEncoding(GetEncoding());
00323 
00324     for (unsigned int i=0; i<(QueryArray.size()); i++)
00325     {
00326         //wxCharBuffer sqlBuffer = ConvertToUnicodeStream(QueryArray[i]);
00327         void* sqlBuffer = (void*)(QueryArray[i].c_str());
00328         //wxPrintf(_("Preparing statement: '%s'\n"), sqlBuffer);
00329 
00330         SQLHSTMT pSqlStatement = allocStmth();
00331         SQLRETURN nRet = SQLPrepare(pSqlStatement, (SQLTCHAR*)(const char*)sqlBuffer, SQL_NTS);
00332         if ( nRet != SQL_SUCCESS && nRet != SQL_SUCCESS_WITH_INFO )
00333         {
00334             InterpretErrorCodes( nRet );
00335             ThrowDatabaseException();
00336             return NULL;
00337         }
00338 
00339         if ( pSqlStatement )
00340             pReturnStatement->AddPreparedStatement( pSqlStatement );
00341     }
00342 
00343     return pReturnStatement;
00344 }
00345 
00346 void OdbcDatabaseLayer::InterpretErrorCodes( long nCode, SQLHSTMT stmth_ptr )
00347 {
00348   wxLogDebug(_("OdbcDatabaseLayer::InterpretErrorCodes()\n"));
00349 
00350   //if ((nCode != SQL_SUCCESS) ) // && (nCode != SQL_SUCCESS_WITH_INFO))
00351   {
00352     SQLINTEGER iNativeCode;
00353     SQLTCHAR strState[ERR_STATE_LEN];
00354     SQLTCHAR strBuffer[ERR_BUFFER_LEN];
00355     SQLSMALLINT iMsgLen;
00356 
00357     memset(strState, 0, ERR_STATE_LEN*sizeof(SQLTCHAR));
00358     memset(strBuffer, 0, ERR_BUFFER_LEN*sizeof(SQLTCHAR));
00359 
00360     if (stmth_ptr)
00361       SQLGetDiagRec(SQL_HANDLE_STMT, stmth_ptr, 1, strState, &iNativeCode, 
00362         strBuffer, ERR_BUFFER_LEN, &iMsgLen);  
00363     else
00364       SQLGetDiagRec(SQL_HANDLE_DBC, m_sqlHDBC, 1, strState, &iNativeCode,
00365         strBuffer, ERR_BUFFER_LEN, &iMsgLen);  
00366  
00367     SetErrorCode((int)iNativeCode);
00368     //SetErrorMessage(ConvertFromUnicodeStream((char*)strBuffer));
00369     SetErrorMessage(wxString((wxChar*)strBuffer));
00370   }
00371 }
00372 

Generated on Sat May 13 17:31:34 2006 for databaselayer by  doxygen 1.4.1