00001 #include "../include/FirebirdPreparedStatement.h"
00002 #include "../include/FirebirdDatabaseLayer.h"
00003 #include "../include/DatabaseErrorCodes.h"
00004 #include "../include/DatabaseLayerException.h"
00005
00006 #include <wx/tokenzr.h>
00007
00008
00009 FirebirdPreparedStatement::FirebirdPreparedStatement(isc_db_handle pDatabase, isc_tr_handle pTransaction)
00010 : PreparedStatement()
00011 {
00012 m_bManageTransaction = false;
00013 m_pTransaction = pTransaction;
00014 m_pDatabase = pDatabase;
00015 }
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 FirebirdPreparedStatement::~FirebirdPreparedStatement()
00026 {
00027 Close();
00028 }
00029
00030 void FirebirdPreparedStatement::Close()
00031 {
00032 CloseResultSets();
00033
00034 FirebirdStatementVector::iterator start = m_Statements.begin();
00035 FirebirdStatementVector::iterator stop = m_Statements.end();
00036
00037 while (start != stop)
00038 {
00039 wxDELETE((*start));
00040 start++;
00041 }
00042
00043
00044 if (m_bManageTransaction && m_pTransaction)
00045 {
00046 int nReturn = isc_commit_transaction(m_Status, &m_pTransaction);
00047 m_pTransaction = NULL;
00048 if (nReturn != 0)
00049 {
00050 InterpretErrorCodes();
00051 ThrowDatabaseException();
00052 }
00053 }
00054 }
00055
00056 void FirebirdPreparedStatement::AddPreparedStatement(const wxString& strSQL)
00057 {
00058 FirebirdPreparedStatementWrapper* pWrapper = new FirebirdPreparedStatementWrapper(m_pDatabase, m_pTransaction, strSQL);
00059 pWrapper->SetEncoding(GetEncoding());
00060 m_Statements.push_back(pWrapper);
00061 }
00062
00063 FirebirdPreparedStatement* FirebirdPreparedStatement::CreateStatement(isc_db_handle pDatabase, isc_tr_handle pTransaction, const wxString& strSQL, const wxCSConv* conv)
00064 {
00065 wxArrayString Queries = ParseQueries(strSQL);
00066
00067 wxArrayString::iterator start = Queries.begin();
00068 wxArrayString::iterator stop = Queries.end();
00069
00070 FirebirdPreparedStatement *pStatement = NULL;
00071
00072 if (Queries.size() < 1)
00073 {
00074 pStatement = new FirebirdPreparedStatement(pDatabase, pTransaction);
00075 pStatement->SetEncoding(conv);
00076
00077 pStatement->SetErrorCode(DATABASE_LAYER_ERROR);
00078 pStatement->SetErrorMessage(_("No SQL Statements found"));
00079
00080 #ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
00081
00082
00083
00084 try
00085 {
00086 delete pStatement;
00087 }
00088 catch (DatabaseLayerException& e)
00089 {
00090 }
00091
00092 DatabaseLayerException error(pStatement->GetErrorCode(), pStatement->GetErrorMessage());
00093 throw error;
00094 #endif
00095 return pStatement;
00096 }
00097
00098
00099
00100 if (pTransaction == NULL)
00101 {
00102 pTransaction = 0L;
00103 ISC_STATUS_ARRAY status;
00104 int nReturn = isc_start_transaction(status, &pTransaction, 1, &pDatabase, 0 , NULL);
00105 pStatement = new FirebirdPreparedStatement(pDatabase, pTransaction);
00106 pStatement->SetEncoding(conv);
00107 if (nReturn != 0)
00108 {
00109 long nSqlCode = isc_sqlcode(status);
00110 pStatement->SetErrorCode(FirebirdDatabaseLayer::TranslateErrorCode(nSqlCode));
00111 pStatement->SetErrorMessage(FirebirdDatabaseLayer::TranslateErrorCodeToString(nSqlCode, status));
00112
00113 #ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
00114
00115
00116
00117 try
00118 {
00119 delete pStatement;
00120 }
00121 catch (DatabaseLayerException& e)
00122 {
00123 }
00124
00125 DatabaseLayerException error(pStatement->GetErrorCode(), pStatement->GetErrorMessage());
00126 throw error;
00127 #endif
00128 return pStatement;
00129 }
00130
00131 pStatement->SetManageTransaction(true);
00132 }
00133 else
00134 {
00135 pStatement = new FirebirdPreparedStatement(pDatabase, pTransaction);
00136 pStatement->SetEncoding(conv);
00137 pStatement->SetManageTransaction(false);
00138 }
00139
00140 while (start != stop)
00141 {
00142 pStatement->AddPreparedStatement((*start));
00143 if (pStatement->GetErrorCode() != DATABASE_LAYER_OK)
00144 {
00145
00146
00147
00148 #ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
00149
00150 DatabaseLayerException error(pStatement->GetErrorCode(), pStatement->GetErrorMessage());
00151
00152 try
00153 {
00154 delete pStatement;
00155 }
00156 catch (DatabaseLayerException& e)
00157 {
00158 }
00159
00160
00161 throw error;
00162 #endif
00163
00164 return pStatement;
00165 }
00166 start++;
00167 }
00168
00169
00170 return pStatement;
00171 }
00172
00173
00174 void FirebirdPreparedStatement::SetParamInt(int nPosition, int nValue)
00175 {
00176 int nIndex = FindStatementAndAdjustPositionIndex(&nPosition);
00177 if (nIndex > -1)
00178 m_Statements[nIndex]->SetParam(nPosition, nValue);
00179 else
00180 SetInvalidParameterPositionError(nPosition);
00181 }
00182
00183 void FirebirdPreparedStatement::SetParamDouble(int nPosition, double dblValue)
00184 {
00185 int nIndex = FindStatementAndAdjustPositionIndex(&nPosition);
00186 if (nIndex > -1)
00187 m_Statements[nIndex]->SetParam(nPosition, dblValue);
00188 else
00189 SetInvalidParameterPositionError(nPosition);
00190 }
00191
00192 void FirebirdPreparedStatement::SetParamString(int nPosition, const wxString& strValue)
00193 {
00194 int nIndex = FindStatementAndAdjustPositionIndex(&nPosition);
00195 if (nIndex > -1)
00196 m_Statements[nIndex]->SetParam(nPosition, strValue);
00197 else
00198 SetInvalidParameterPositionError(nPosition);
00199 }
00200
00201 void FirebirdPreparedStatement::SetParamNull(int nPosition)
00202 {
00203 int nIndex = FindStatementAndAdjustPositionIndex(&nPosition);
00204 if (nIndex > -1)
00205 m_Statements[nIndex]->SetParam(nPosition);
00206 else
00207 SetInvalidParameterPositionError(nPosition);
00208 }
00209
00210 void FirebirdPreparedStatement::SetParamBlob(int nPosition, const void* pData, long nDataLength)
00211 {
00212 int nIndex = FindStatementAndAdjustPositionIndex(&nPosition);
00213 if (nIndex > -1)
00214 m_Statements[nIndex]->SetParam(nPosition, pData, nDataLength);
00215 else
00216 SetInvalidParameterPositionError(nPosition);
00217 }
00218
00219 void FirebirdPreparedStatement::SetParamDate(int nPosition, const wxDateTime& dateValue)
00220 {
00221 int nIndex = FindStatementAndAdjustPositionIndex(&nPosition);
00222 if (nIndex > -1)
00223 m_Statements[nIndex]->SetParam(nPosition, dateValue);
00224 else
00225 SetInvalidParameterPositionError(nPosition);
00226 }
00227
00228 void FirebirdPreparedStatement::SetParamBool(int nPosition, bool bValue)
00229 {
00230 int nIndex = FindStatementAndAdjustPositionIndex(&nPosition);
00231 if (nIndex > -1)
00232 m_Statements[nIndex]->SetParam(nPosition, bValue);
00233 else
00234 SetInvalidParameterPositionError(nPosition);
00235 }
00236
00237 int FirebirdPreparedStatement::GetParameterCount()
00238 {
00239 FirebirdStatementVector::iterator start = m_Statements.begin();
00240 FirebirdStatementVector::iterator stop = m_Statements.end();
00241
00242 int nParameters = 0;
00243 while (start != stop)
00244 {
00245 nParameters += (*start)->GetParameterCount();
00246 start++;
00247 }
00248 return nParameters;
00249 }
00250
00251 void FirebirdPreparedStatement::RunQuery()
00252 {
00253 FirebirdStatementVector::iterator start = m_Statements.begin();
00254 FirebirdStatementVector::iterator stop = m_Statements.end();
00255
00256 while (start != stop)
00257 {
00258 (*start)->RunQuery();
00259 if ((*start)->GetErrorCode() != DATABASE_LAYER_OK)
00260 {
00261 SetErrorCode((*start)->GetErrorCode());
00262 SetErrorMessage((*start)->GetErrorMessage());
00263 return;
00264 }
00265
00266 start++;
00267 }
00268
00269
00270 if (m_bManageTransaction)
00271 {
00272 int nReturn = isc_commit_retaining(m_Status, &m_pTransaction);
00273
00274
00275 if (nReturn != 0)
00276 {
00277 InterpretErrorCodes();
00278 ThrowDatabaseException();
00279 }
00280 }
00281 }
00282
00283 DatabaseResultSet* FirebirdPreparedStatement::RunQueryWithResults()
00284 {
00285 if (m_Statements.size() > 0)
00286 {
00287
00288 for (unsigned int i=0; i<m_Statements.size()-1; i++)
00289 {
00290 m_Statements[i]->RunQuery();
00291 if (m_Statements[i]->GetErrorCode() != DATABASE_LAYER_OK)
00292 {
00293 SetErrorCode(m_Statements[i]->GetErrorCode());
00294 SetErrorMessage(m_Statements[i]->GetErrorMessage());
00295 return NULL;
00296 }
00297 }
00298
00299 FirebirdPreparedStatementWrapper* pLastStatement = m_Statements[m_Statements.size()-1];
00300
00301 if (m_bManageTransaction)
00302 {
00303
00304 int nReturn = isc_commit_transaction(m_Status, &m_pTransaction);
00305
00306 if (nReturn != 0)
00307 {
00308 InterpretErrorCodes();
00309 ThrowDatabaseException();
00310 }
00311
00312
00313 nReturn = isc_start_transaction(m_Status, &m_pTransaction, 1, &m_pDatabase, 0 , NULL);
00314 if (nReturn != 0)
00315 {
00316 InterpretErrorCodes();
00317 ThrowDatabaseException();
00318 return NULL;
00319 }
00320
00321
00322 pLastStatement->SetTransaction(m_pTransaction);
00323 }
00324
00325
00326
00327
00328 DatabaseResultSet* pResultSet = pLastStatement->RunQueryWithResults();
00329 if (pResultSet)
00330 pResultSet->SetEncoding(GetEncoding());
00331 if (pLastStatement->GetErrorCode() != DATABASE_LAYER_OK)
00332 {
00333 SetErrorCode(pLastStatement->GetErrorCode());
00334 SetErrorMessage(pLastStatement->GetErrorMessage());
00335
00336
00337
00338 #ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
00339 try
00340 {
00341 #endif
00342 if (pResultSet)
00343 delete pResultSet;
00344 #ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS
00345 }
00346 catch (DatabaseLayerException& e)
00347 {
00348 }
00349 #endif
00350
00351 return NULL;
00352 }
00353
00354 LogResultSetForCleanup(pResultSet);
00355 return pResultSet;
00356 }
00357 else
00358 return NULL;
00359 }
00360
00361 int FirebirdPreparedStatement::FindStatementAndAdjustPositionIndex(int* pPosition)
00362 {
00363
00364 if (m_Statements.size() <= 1)
00365 return 0;
00366
00367
00368
00369
00370 for (unsigned int i=0; i<m_Statements.size(); i++)
00371 {
00372 int nParametersInThisStatement = 0;
00373 nParametersInThisStatement = m_Statements[i]->GetParameterCount();
00374 if (*pPosition > nParametersInThisStatement)
00375 {
00376 *pPosition -= nParametersInThisStatement;
00377 }
00378 else
00379 {
00380
00381 return i;
00382 }
00383 }
00384 return -1;
00385 }
00386
00387 void FirebirdPreparedStatement::SetInvalidParameterPositionError(int nPosition)
00388 {
00389 SetErrorCode(DATABASE_LAYER_ERROR);
00390 SetErrorMessage(_("Invalid Prepared Statement Parameter"));
00391
00392 ThrowDatabaseException();
00393 }
00394
00395 void FirebirdPreparedStatement::InterpretErrorCodes()
00396 {
00397 wxLogError(_("FirebirdPreparesStatement::InterpretErrorCodes()\n"));
00398
00399 long nSqlCode = isc_sqlcode(m_Status);
00400 SetErrorCode(FirebirdDatabaseLayer::TranslateErrorCode(nSqlCode));
00401 SetErrorMessage(FirebirdDatabaseLayer::TranslateErrorCodeToString(nSqlCode, m_Status));
00402 }
00403