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

FirebirdPreparedStatementWrapper.cpp

Go to the documentation of this file.
00001 #include "../include/FirebirdPreparedStatementWrapper.h"
00002 #include "../include/FirebirdDatabaseLayer.h"
00003 #include "../include/DatabaseErrorCodes.h"
00004 #include "../include/DatabaseLayerException.h"
00005 #include "../include/FirebirdResultSet.h"
00006 
00007 FirebirdPreparedStatementWrapper::FirebirdPreparedStatementWrapper(isc_db_handle pDatabase, isc_tr_handle pTransaction, const wxString& strSQL)
00008  : DatabaseErrorReporter()
00009 {
00010   m_pDatabase = pDatabase;
00011   m_pTransaction = pTransaction;
00012   m_strSQL = strSQL;
00013   m_pStatement = NULL;
00014   m_pParameters = NULL;
00015   m_pParameterCollection = NULL;
00016   m_bManageStatement = true;
00017   m_bManageTransaction = false;
00018  
00019   Prepare();
00020 
00021   if (GetErrorCode() != DATABASE_LAYER_OK)
00022   {
00023     ThrowDatabaseException();
00024   } 
00025 
00026 }
00027 
00028 FirebirdPreparedStatementWrapper::~FirebirdPreparedStatementWrapper()
00029 {
00030   ResetErrorCodes();
00031 
00032   if (m_pParameterCollection)
00033   {
00034     wxDELETE(m_pParameterCollection);
00035   }
00036 
00037   if (m_pStatement && m_bManageStatement)
00038   {
00039     int nReturn = isc_dsql_free_statement(m_Status, &m_pStatement, DSQL_drop);
00040     if (nReturn != 0)
00041     {
00042       wxLogError(_("Error calling isc_dsql_free_statement"));
00043       InterpretErrorCodes();
00044       ThrowDatabaseException();
00045     }
00046   }
00047 }
00048 
00049 void FirebirdPreparedStatementWrapper::Prepare(const wxString& strSQL)
00050 {
00051   m_strSQL = strSQL;
00052   Prepare();
00053 }
00054 
00055 void FirebirdPreparedStatementWrapper::Prepare()
00056 {
00057   ResetErrorCodes();
00058 
00059   int nReturn = isc_dsql_allocate_statement(m_Status, &m_pDatabase, &m_pStatement);
00060   if (nReturn != 0)
00061   {
00062     InterpretErrorCodes();
00063     ThrowDatabaseException();
00064     return;
00065   }
00066   m_pParameters = (XSQLDA*)malloc(XSQLDA_LENGTH(1));
00067   if (m_pParameters == NULL)
00068   {
00069     InterpretErrorCodes();
00070     ThrowDatabaseException();
00071     return;
00072   }
00073   m_pParameters->version = SQLDA_VERSION1;
00074   m_pParameters->sqln = 1;
00075 
00076   wxCharBuffer sqlBuffer = ConvertToUnicodeStream(m_strSQL);
00077   nReturn = isc_dsql_prepare(m_Status, &m_pTransaction, &m_pStatement, 0, (char*)(const char*)sqlBuffer, 1, m_pParameters);
00078   if (nReturn != 0)
00079   {
00080     InterpretErrorCodes();
00081     ThrowDatabaseException();
00082     return;
00083   }
00084 
00085   nReturn = isc_dsql_describe_bind(m_Status, &m_pStatement, 1, m_pParameters);
00086   if (nReturn != 0)
00087   {
00088     InterpretErrorCodes();
00089     ThrowDatabaseException();
00090     return;
00091   }
00092 
00093   if (m_pParameters->sqld > m_pParameters->sqln)
00094   {
00095     int nParameters = m_pParameters->sqld;
00096     free(m_pParameters);
00097     m_pParameters = (XSQLDA*)malloc(XSQLDA_LENGTH(nParameters));
00098     m_pParameters->version = SQLDA_VERSION1;
00099     m_pParameters->sqln = nParameters;
00100     nReturn = isc_dsql_describe_bind(m_Status, &m_pStatement, 1, m_pParameters);
00101     if (nReturn != 0)
00102     {
00103       InterpretErrorCodes();
00104       ThrowDatabaseException();
00105       return;
00106     }
00107   }
00108   m_pParameterCollection = new FirebirdParameterCollection(m_pParameters);
00109   m_pParameterCollection->SetEncoding(GetEncoding());
00110 }
00111 
00112 // set field
00113 void FirebirdPreparedStatementWrapper::SetParam(int nPosition, int nValue)
00114 {
00115   m_pParameterCollection->SetParam(nPosition, nValue);
00116 }
00117 
00118 void FirebirdPreparedStatementWrapper::SetParam(int nPosition, double dblValue)
00119 {
00120   m_pParameterCollection->SetParam(nPosition, dblValue);
00121 }
00122 
00123 void FirebirdPreparedStatementWrapper::SetParam(int nPosition, const wxString& strValue)
00124 {
00125   m_pParameterCollection->SetParam(nPosition, strValue);
00126 }
00127 
00128 void FirebirdPreparedStatementWrapper::SetParam(int nPosition)
00129 {
00130   m_pParameterCollection->SetParam(nPosition);
00131 }
00132 
00133 void FirebirdPreparedStatementWrapper::SetParam(int nPosition, const void* pData, long nDataLength)
00134 {
00135   m_pParameterCollection->SetParam(nPosition, m_pDatabase, m_pTransaction, pData, nDataLength);
00136 }
00137 
00138 void FirebirdPreparedStatementWrapper::SetParam(int nPosition, const wxDateTime& dateValue)
00139 {
00140   m_pParameterCollection->SetParam(nPosition, dateValue);
00141 }
00142 
00143 void FirebirdPreparedStatementWrapper::SetParam(int nPosition, bool bValue)
00144 {
00145   m_pParameterCollection->SetParam(nPosition, bValue);
00146 }
00147 
00148 int FirebirdPreparedStatementWrapper::GetParameterCount()
00149 {
00150   if (m_pParameters == NULL)
00151     return 0;
00152   else
00153     return m_pParameters->sqld;
00154 }
00155   
00156 void FirebirdPreparedStatementWrapper::RunQuery()
00157 {
00158   ResetErrorCodes();
00159 
00160   // Blob ID values are invalidated between execute calls, so re-create any BLOB parameters now
00161   m_pParameterCollection->ResetBlobParameters();
00162   
00163   int nReturn = isc_dsql_execute(m_Status, &m_pTransaction, &m_pStatement, 1, m_pParameters);
00164   if (nReturn != 0)
00165   {
00166     InterpretErrorCodes();
00167     ThrowDatabaseException();
00168   }
00169 }
00170 
00171 DatabaseResultSet* FirebirdPreparedStatementWrapper::RunQueryWithResults()
00172 {
00173   ResetErrorCodes();
00174 
00175   XSQLDA* pOutputSqlda = (XSQLDA*)malloc(XSQLDA_LENGTH(1));
00176   pOutputSqlda->sqln = 1;
00177   pOutputSqlda->version = SQLDA_VERSION1;
00178 
00179   // Make sure that we have enough space allocated for the result set
00180   int nReturn = isc_dsql_describe(m_Status, &m_pStatement, 1, pOutputSqlda);
00181   if (nReturn != 0)
00182   {
00183     free(pOutputSqlda);
00184     InterpretErrorCodes();
00185     ThrowDatabaseException();
00186     return NULL;
00187   }
00188   if (pOutputSqlda->sqld > pOutputSqlda->sqln)
00189   {
00190     int nColumns = pOutputSqlda->sqld;
00191     free(pOutputSqlda);
00192     pOutputSqlda = (XSQLDA*)malloc(XSQLDA_LENGTH(nColumns));
00193     pOutputSqlda->sqln = nColumns;
00194     pOutputSqlda->version = SQLDA_VERSION1;
00195     nReturn = isc_dsql_describe(m_Status, &m_pStatement, 1, pOutputSqlda);
00196     if (nReturn != 0)
00197     {
00198       free(pOutputSqlda);
00199       InterpretErrorCodes();
00200       ThrowDatabaseException();
00201       return NULL;
00202     }
00203   }
00204 
00205   //isc_tr_handle pQueryTransaction = NULL;
00206   //nReturn = isc_start_transaction(m_Status, &pQueryTransaction, 1, &m_pDatabase, 0 /*tpb_length*/, NULL/*tpb*/);
00207   /*if (nReturn != 0)
00208   {
00209     InterpretErrorCodes();
00210     ThrowDatabaseException();
00211     return NULL;
00212   }*/
00213 
00214   // Create the result set object
00215   FirebirdResultSet* pResultSet = new FirebirdResultSet(m_pDatabase, m_pTransaction, m_pStatement, pOutputSqlda);
00216   if (pResultSet)
00217     pResultSet->SetEncoding(GetEncoding());
00218   if (pResultSet->GetErrorCode() != DATABASE_LAYER_OK)
00219   {
00220     SetErrorCode(pResultSet->GetErrorCode());
00221     SetErrorMessage(pResultSet->GetErrorMessage());
00222     
00223     // Wrap the result set deletion in try/catch block if using exceptions.
00224     // We want to make sure the original error gets to the user
00225 #ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
00226     try
00227     {
00228 #endif
00229     delete pResultSet;
00230 #ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
00231     }
00232     catch (DatabaseLayerException& e)
00233     {
00234     }
00235 #endif
00236     
00237 
00238     ThrowDatabaseException();
00239   }
00240   
00241   // Blob ID values are invalidated between execute calls, so re-create any BLOB parameters now
00242   m_pParameterCollection->ResetBlobParameters();
00243   
00244   // Now execute the SQL
00245   //nReturn = isc_dsql_execute2(m_Status, &m_pTransaction, &m_pStatement, 1, m_pParameters, pOutputSqlda);
00246   nReturn = isc_dsql_execute(m_Status, &m_pTransaction, &m_pStatement, 1, m_pParameters);
00247   if (nReturn != 0)
00248   {
00249     InterpretErrorCodes();
00250 
00251     // Wrap the result set deletion in try/catch block if using exceptions.
00252     //We want to make sure the isc_dsql_execute2 error gets to the user
00253 #ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
00254     try
00255     {
00256 #endif
00257     delete pResultSet;
00258 #ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
00259     }
00260     catch (DatabaseLayerException& e)
00261     {
00262     }
00263 #endif
00264     
00265     ThrowDatabaseException();
00266     return NULL;
00267   }
00268 
00269   m_bManageStatement = true;
00270   m_bManageTransaction = false;
00271 
00272   return pResultSet;
00273 }
00274 
00275 bool FirebirdPreparedStatementWrapper::IsSelectQuery()
00276 {
00277   wxString strLocalCopy = m_strSQL;
00278   strLocalCopy.Trim(false);
00279   strLocalCopy.MakeUpper();
00280   return strLocalCopy.StartsWith(_("SELECT "));
00281 }
00282 
00283 void FirebirdPreparedStatementWrapper::InterpretErrorCodes()
00284 {
00285   wxLogError(_("FirebirdPreparesStatementWrapper::InterpretErrorCodes()\n"));
00286 
00287   long nSqlCode = isc_sqlcode(m_Status);
00288   SetErrorCode(FirebirdDatabaseLayer::TranslateErrorCode(nSqlCode));
00289   SetErrorMessage(FirebirdDatabaseLayer::TranslateErrorCodeToString(nSqlCode, m_Status));
00290 }
00291 

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