00001 #include "../include/SqliteDatabaseLayer.h"
00002 #include "../include/SqliteResultSet.h"
00003 #include "../include/SqlitePreparedStatement.h"
00004 #include "../include/DatabaseErrorCodes.h"
00005
00006 #include <wx/tokenzr.h>
00007
00008
00009 SqliteDatabaseLayer::SqliteDatabaseLayer()
00010 : DatabaseLayer()
00011 {
00012 m_pDatabase = NULL;
00013 wxCSConv conv(_("UTF-8"));
00014 SetEncoding(&conv);
00015 }
00016
00017 SqliteDatabaseLayer::SqliteDatabaseLayer(const wxString& strDatabase)
00018 : DatabaseLayer()
00019 {
00020 m_pDatabase = NULL;
00021 wxCSConv conv(_("UTF-8"));
00022 SetEncoding(&conv);
00023 Open(strDatabase);
00024 }
00025
00026
00027 SqliteDatabaseLayer::~SqliteDatabaseLayer()
00028 {
00029
00030 Close();
00031
00032 }
00033
00034
00035 bool SqliteDatabaseLayer::Open(const wxString& strDatabase)
00036 {
00037 ResetErrorCodes();
00038
00039
00040
00041
00042 wxCharBuffer databaseNameBuffer = ConvertToUnicodeStream(strDatabase);
00043 int nReturn = sqlite3_open(databaseNameBuffer, &m_pDatabase);
00044 if (nReturn != SQLITE_OK)
00045 {
00046 SetErrorCode(SqliteDatabaseLayer::TranslateErrorCode(sqlite3_errcode(m_pDatabase)));
00047 SetErrorMessage(ConvertFromUnicodeStream(sqlite3_errmsg(m_pDatabase)));
00048 ThrowDatabaseException();
00049 return false;
00050 }
00051 return true;
00052 }
00053
00054
00055 bool SqliteDatabaseLayer::Close()
00056 {
00057 ResetErrorCodes();
00058
00059 CloseResultSets();
00060 CloseStatements();
00061
00062 if (m_pDatabase != NULL)
00063 {
00064 int nReturn = sqlite3_close(m_pDatabase);
00065 if (nReturn != SQLITE_OK)
00066 {
00067 SetErrorCode(SqliteDatabaseLayer::TranslateErrorCode(sqlite3_errcode(m_pDatabase)));
00068 SetErrorMessage(ConvertFromUnicodeStream(sqlite3_errmsg(m_pDatabase)));
00069 ThrowDatabaseException();
00070 return false;
00071 }
00072 m_pDatabase = NULL;
00073 }
00074
00075 return true;
00076 }
00077
00078 void SqliteDatabaseLayer::BeginTransaction()
00079 {
00080 wxLogDebug(_("Beginning transaction"));
00081 RunQuery(_("begin transaction;"), false);
00082 }
00083
00084 void SqliteDatabaseLayer::Commit()
00085 {
00086 wxLogDebug(_("Commiting transaction"));
00087 RunQuery(_("commit transaction;"), false);
00088 }
00089
00090 void SqliteDatabaseLayer::RollBack()
00091 {
00092 wxLogDebug(_("Rolling back transaction"));
00093 RunQuery(_("rollback transaction;"), false);
00094 }
00095
00096
00097 bool SqliteDatabaseLayer::RunQuery(const wxString& strQuery, bool bParseQuery)
00098 {
00099 ResetErrorCodes();
00100
00101 if (m_pDatabase == NULL)
00102 return false;
00103
00104 wxArrayString QueryArray;
00105 if (bParseQuery)
00106 QueryArray = ParseQueries(strQuery);
00107 else
00108 QueryArray.push_back(strQuery);
00109
00110 wxArrayString::iterator start = QueryArray.begin();
00111 wxArrayString::iterator stop = QueryArray.end();
00112
00113 while (start != stop)
00114 {
00115 char* szErrorMessage = NULL;
00116 wxString strErrorMessage = _("");
00117 wxCharBuffer sqlBuffer = ConvertToUnicodeStream(*start);
00118 int nReturn = sqlite3_exec(m_pDatabase, sqlBuffer, 0, 0, &szErrorMessage);
00119
00120 if (szErrorMessage != NULL)
00121 {
00122 strErrorMessage = ConvertFromUnicodeStream(szErrorMessage);
00123 sqlite3_free(szErrorMessage);
00124 }
00125
00126 if (nReturn != SQLITE_OK)
00127 {
00128 SetErrorCode(SqliteDatabaseLayer::TranslateErrorCode(sqlite3_errcode(m_pDatabase)));
00129 SetErrorMessage(strErrorMessage);
00130 ThrowDatabaseException();
00131 return false;
00132 }
00133
00134 start++;
00135 }
00136 return true;
00137 }
00138
00139 DatabaseResultSet* SqliteDatabaseLayer::RunQueryWithResults(const wxString& strQuery)
00140 {
00141 ResetErrorCodes();
00142
00143 if (m_pDatabase != NULL)
00144 {
00145 wxArrayString QueryArray = ParseQueries(strQuery);
00146
00147 for (unsigned int i=0; i<(QueryArray.size()-1); i++)
00148 {
00149 char* szErrorMessage = NULL;
00150 wxString strErrorMessage = _("");
00151 wxCharBuffer sqlBuffer = ConvertToUnicodeStream(QueryArray[i]);
00152 int nReturn = sqlite3_exec(m_pDatabase, sqlBuffer, 0, 0, &szErrorMessage);
00153
00154 if (szErrorMessage != NULL)
00155 {
00156 SetErrorCode(SqliteDatabaseLayer::TranslateErrorCode(sqlite3_errcode(m_pDatabase)));
00157 strErrorMessage = ConvertFromUnicodeStream(szErrorMessage);
00158 sqlite3_free(szErrorMessage);
00159 return NULL;
00160 }
00161
00162 if (nReturn != SQLITE_OK)
00163 {
00164 SetErrorCode(SqliteDatabaseLayer::TranslateErrorCode(sqlite3_errcode(m_pDatabase)));
00165 SetErrorMessage(strErrorMessage);
00166 ThrowDatabaseException();
00167 return NULL;
00168 }
00169 }
00170
00171
00172 SqlitePreparedStatement* pStatement = (SqlitePreparedStatement*)PrepareStatement(QueryArray[QueryArray.size()-1], false);
00173 SqliteResultSet* pResultSet = new SqliteResultSet(pStatement, true);
00174 if (pResultSet)
00175 pResultSet->SetEncoding(GetEncoding());
00176
00177 LogResultSetForCleanup(pResultSet);
00178 return pResultSet;
00179 }
00180 else
00181 {
00182 return NULL;
00183 }
00184 }
00185
00186 PreparedStatement* SqliteDatabaseLayer::PrepareStatement(const wxString& strQuery)
00187 {
00188 return PrepareStatement(strQuery, true);
00189 }
00190
00191 PreparedStatement* SqliteDatabaseLayer::PrepareStatement(const wxString& strQuery, bool bLogForCleanup)
00192 {
00193 ResetErrorCodes();
00194
00195 if (m_pDatabase != NULL)
00196 {
00197 SqlitePreparedStatement* pReturnStatement = new SqlitePreparedStatement(m_pDatabase);
00198 if (pReturnStatement)
00199 pReturnStatement->SetEncoding(GetEncoding());
00200
00201 wxArrayString QueryArray = ParseQueries(strQuery);
00202
00203 wxArrayString::iterator start = QueryArray.begin();
00204 wxArrayString::iterator stop = QueryArray.end();
00205
00206 while (start != stop)
00207 {
00208 const char* szTail=0;
00209 wxCharBuffer sqlBuffer;
00210 do
00211 {
00212 sqlite3_stmt* pStatement;
00213 wxString strSQL;
00214 if (szTail != 0)
00215 {
00216 strSQL = (wxChar*)szTail;
00217 }
00218 else
00219 {
00220 strSQL = (*start);
00221 }
00222 sqlBuffer = ConvertToUnicodeStream(strSQL);
00223 int nReturn = sqlite3_prepare(m_pDatabase, sqlBuffer, -1, &pStatement, &szTail);
00224
00225 if (nReturn != SQLITE_OK)
00226 {
00227 SetErrorCode(SqliteDatabaseLayer::TranslateErrorCode(nReturn));
00228 SetErrorMessage(ConvertFromUnicodeStream(sqlite3_errmsg(m_pDatabase)));
00229 wxDELETE(pReturnStatement);
00230 ThrowDatabaseException();
00231 return NULL;
00232 }
00233 pReturnStatement->AddPreparedStatement(pStatement);
00234
00235 #if wxUSE_UNICODE
00236 } while (strlen(szTail) > 0);
00237 #else
00238 } while (wxStrlen(szTail) > 0);
00239 #endif
00240
00241 start++;
00242 }
00243
00244 if (bLogForCleanup)
00245 LogStatementForCleanup(pReturnStatement);
00246 return pReturnStatement;
00247 }
00248 else
00249 {
00250 return NULL;
00251 }
00252 }
00253
00254 int SqliteDatabaseLayer::TranslateErrorCode(int nCode)
00255 {
00256
00257
00258 int nReturn = nCode;
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 return nReturn;
00334 }
00335