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

SqliteDatabaseLayer.cpp

Go to the documentation of this file.
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 // ctor()
00009 SqliteDatabaseLayer::SqliteDatabaseLayer()
00010  : DatabaseLayer()
00011 {
00012   m_pDatabase = NULL; //&m_Database; //new sqlite3;
00013   wxCSConv conv(_("UTF-8"));
00014   SetEncoding(&conv);
00015 }
00016 
00017 SqliteDatabaseLayer::SqliteDatabaseLayer(const wxString& strDatabase)
00018  : DatabaseLayer()
00019 {
00020   m_pDatabase = NULL; //new sqlite3;
00021   wxCSConv conv(_("UTF-8"));
00022   SetEncoding(&conv);
00023   Open(strDatabase);
00024 }
00025 
00026 // dtor()
00027 SqliteDatabaseLayer::~SqliteDatabaseLayer()
00028 {
00029   //wxPrintf(_("~SqliteDatabaseLayer()\n"));
00030   Close();
00031   //wxDELETE(m_pDatabase);
00032 }
00033 
00034 // open database
00035 bool SqliteDatabaseLayer::Open(const wxString& strDatabase)
00036 {
00037   ResetErrorCodes();
00038 
00039   //if (m_pDatabase == NULL)
00040   //  m_pDatabase = new sqlite3;
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 // close database  
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 // query database
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     // Create a Prepared statement for the last SQL statement and get a result set from it
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   // Ultimately, this will probably be a map of SQLite database error code values to DatabaseLayer values
00257   // For now though, we'll just return error
00258   int nReturn = nCode;
00259   /*
00260   switch (nCode)
00261   {
00262     case SQLITE_ERROR:
00263       nReturn = DATABASE_LAYER_SQL_SYNTAX_ERROR;
00264       break;
00265     case SQLITE_INTERNAL:
00266       nReturn = DATABASE_LAYER_ERROR;
00267       break;
00268     case SQLITE_PERM:
00269       nReturn = DATABASE_LAYER_ERROR;
00270       break;
00271     case SQLITE_ABORT:
00272       nReturn = DATABASE_LAYER_ERROR;
00273       break;
00274     case SQLITE_BUSY:
00275       nReturn = DATABASE_LAYER_ERROR;
00276       break;
00277     case SQLITE_LOCKED:
00278       nReturn = DATABASE_LAYER_ERROR;
00279       break;
00280     case SQLITE_NOMEM:
00281       nReturn = DATABASE_LAYER_ALLOCATION_ERROR;
00282       break;
00283     case SQLITE_READONLY:
00284       nReturn = DATABASE_LAYER_ERROR;
00285       break;
00286     case SQLITE_INTERRUPT:
00287       nReturn = DATABASE_LAYER_ERROR;
00288       break;
00289     case SQLITE_IOERR:
00290       nReturn = DATABASE_LAYER_ERROR;
00291       break;
00292     case SQLITE_CORRUPT:
00293       nReturn = DATABASE_LAYER_ERROR;
00294       break;
00295     case SQLITE_NOTFOUND:
00296       nReturn = DATABASE_LAYER_ERROR;
00297       break;
00298     case SQLITE_FULL:
00299       nReturn = DATABASE_LAYER_ERROR;
00300       break;
00301     case SQLITE_CANTOPEN:
00302       nReturn = DATABASE_LAYER_ERROR;
00303       break;
00304     case SQLITE_PROTOCOL:
00305       nReturn = DATABASE_LAYER_ERROR;
00306       break;
00307     case SQLITE_SCHEMA:
00308       nReturn = DATABASE_LAYER_ERROR;
00309       break;
00310     case SQLITE_TOOBIG:
00311       nReturn = DATABASE_LAYER_ERROR;
00312       break;
00313     case SQLITE_CONSTRAINT:
00314       nReturn = DATABASE_LAYER_CONSTRAINT_VIOLATION;
00315       break;
00316     case SQLITE_MISMATCH:
00317       nReturn = DATABASE_LAYER_INCOMPATIBLE_FIELD_TYPE;
00318       break;
00319     case SQLITE_MISUSE:
00320       nReturn = DATABASE_LAYER_ERROR;
00321       break;
00322     case SQLITE_NOLFS:
00323       nReturn = DATABASE_LAYER_ERROR;
00324       break;
00325     case SQLITE_AUTH:
00326       nReturn = DATABASE_LAYER_ERROR;
00327       break;
00328     default:
00329       nReturn = DATABASE_LAYER_ERROR;
00330       break;
00331   }
00332   */
00333   return nReturn;
00334 }
00335 

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