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
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
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
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
00206
00207
00208
00209
00210
00211
00212
00213
00214
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
00224
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
00242 m_pParameterCollection->ResetBlobParameters();
00243
00244
00245
00246 nReturn = isc_dsql_execute(m_Status, &m_pTransaction, &m_pStatement, 1, m_pParameters);
00247 if (nReturn != 0)
00248 {
00249 InterpretErrorCodes();
00250
00251
00252
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