X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/670f9935630beb2123a5ca62894ae92a3f0efa4f..d94de683a60b20153591cc3f8f52a97cf9ce9453:/src/common/db.cpp diff --git a/src/common/db.cpp b/src/common/db.cpp index d0b9bf6499..cf4f9a28b9 100644 --- a/src/common/db.cpp +++ b/src/common/db.cpp @@ -43,7 +43,7 @@ #endif #include "wx/filefn.h" -#include "wx/wxchar.h" +#include "wx/crt.h" #include #include @@ -53,6 +53,13 @@ #include "wx/db.h" +// FIXME-UTF8: get rid of this after switching to Unicode-only builds: +#if wxUSE_UNICODE + #define WXSQLCAST(s) ((SQLTCHAR FAR *)(wchar_t*)(s).wchar_str()) +#else + #define WXSQLCAST(s) ((SQLTCHAR FAR *)(char*)(s).char_str()) +#endif + // DLL options compatibility check: WX_CHECK_BUILD_OPTIONS("wxODBC") @@ -62,7 +69,10 @@ wxChar const *SQL_LOG_FILENAME = wxT("sqllog.txt"); wxChar const *SQL_CATALOG_FILENAME = wxT("catalog.txt"); #ifdef __WXDEBUG__ + #include "wx/thread.h" + extern wxList TablesInUse; + extern wxCriticalSection csTablesInUse; #endif // SQL Log defaults to be used by GetDbConnection @@ -557,7 +567,7 @@ void wxDb::initialize() // immediately, as the value is not good after // this function has left scope. // -const wxChar *wxDb::convertUserID(const wxChar *userID, wxString &UserID) +void wxDb::convertUserID(const wxChar *userID, wxString &UserID) { if (userID) { @@ -579,8 +589,6 @@ const wxChar *wxDb::convertUserID(const wxChar *userID, wxString &UserID) if ((Dbms() == dbmsORACLE) || (Dbms() == dbmsMAXDB)) UserID = UserID.Upper(); - - return UserID.c_str(); } // wxDb::convertUserID() @@ -856,9 +864,9 @@ bool wxDb::Open(const wxString& inConnectStr, SQLHWND parentWnd, bool failOnData inConnectionStr = inConnectStr; - retcode = SQLDriverConnect(hdbc, parentWnd, (SQLTCHAR FAR *)inConnectionStr.c_str(), + retcode = SQLDriverConnect(hdbc, parentWnd, WXSQLCAST(inConnectionStr), (SWORD)inConnectionStr.length(), (SQLTCHAR FAR *)outConnectBuffer, - sizeof(outConnectBuffer), &outConnectBufferLen, SQL_DRIVER_COMPLETE ); + WXSIZEOF(outConnectBuffer), &outConnectBufferLen, SQL_DRIVER_COMPLETE ); if ((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO)) @@ -901,9 +909,10 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt } // Connect to the data source - retcode = SQLConnect(hdbc, (SQLTCHAR FAR *) dsn.c_str(), SQL_NTS, - (SQLTCHAR FAR *) uid.c_str(), SQL_NTS, - (SQLTCHAR FAR *) authStr.c_str(), SQL_NTS); + retcode = SQLConnect(hdbc, + WXSQLCAST(dsn), SQL_NTS, + WXSQLCAST(uid), SQL_NTS, + WXSQLCAST(authStr), SQL_NTS); if ((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO)) @@ -920,7 +929,7 @@ bool wxDb::Open(wxDbConnectInf *dbConnectInf, bool failOnDataTypeUnsupported) // Use the connection string if one is present if (dbConnectInf->UseConnectionStr()) - return Open(GetConnectionInStr(), failOnDataTypeUnsupported); + return Open(dbConnectInf->GetConnectionStr(), failOnDataTypeUnsupported); else return Open(dbConnectInf->GetDsn(), dbConnectInf->GetUserID(), dbConnectInf->GetPassword(), failOnDataTypeUnsupported); @@ -961,9 +970,9 @@ bool wxDb::Open(wxDb *copyDb) inConnectionStr = copyDb->GetConnectionInStr(); - retcode = SQLDriverConnect(hdbc, NULL, (SQLTCHAR FAR *)inConnectionStr.c_str(), + retcode = SQLDriverConnect(hdbc, NULL, WXSQLCAST(inConnectionStr), (SWORD)inConnectionStr.length(), (SQLTCHAR FAR *)outConnectBuffer, - sizeof(outConnectBuffer), &outConnectBufferLen, SQL_DRIVER_COMPLETE); + WXSIZEOF(outConnectBuffer), &outConnectBufferLen, SQL_DRIVER_COMPLETE); if ((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO)) @@ -976,9 +985,10 @@ bool wxDb::Open(wxDb *copyDb) else { // Connect to the data source - retcode = SQLConnect(hdbc, (SQLTCHAR FAR *) dsn.c_str(), SQL_NTS, - (SQLTCHAR FAR *) uid.c_str(), SQL_NTS, - (SQLTCHAR FAR *) authStr.c_str(), SQL_NTS); + retcode = SQLConnect(hdbc, + WXSQLCAST(dsn), SQL_NTS, + WXSQLCAST(uid), SQL_NTS, + WXSQLCAST(authStr), SQL_NTS); } if ((retcode != SQL_SUCCESS) && @@ -1746,20 +1756,24 @@ void wxDb::Close(void) wxASSERT(nTables == 0); #ifdef __WXDEBUG__ - wxTablesInUse *tiu; - wxList::compatibility_iterator pNode; - pNode = TablesInUse.GetFirst(); - wxString s,s2; - while (pNode) { - tiu = (wxTablesInUse *)pNode->GetData(); - if (tiu->pDb == this) + wxCriticalSectionLocker lock(csTablesInUse); + wxTablesInUse *tiu; + wxList::compatibility_iterator pNode; + pNode = TablesInUse.GetFirst(); + wxString s,s2; + while (pNode) { - s.Printf(wxT("(%-20s) tableID:[%6lu] pDb:[%p]"), tiu->tableName,tiu->tableID,tiu->pDb); - s2.Printf(wxT("Orphaned table found using pDb:[%p]"),this); - wxLogDebug(s.c_str(),s2.c_str()); + tiu = (wxTablesInUse *)pNode->GetData(); + if (tiu->pDb == this) + { + s.Printf(wxT("(%-20s) tableID:[%6lu] pDb:[%p]"), + tiu->tableName, tiu->tableID, wx_static_cast(void*, tiu->pDb)); + s2.Printf(wxT("Orphaned table found using pDb:[%p]"), wx_static_cast(void*, this)); + wxLogDebug(s.c_str(),s2.c_str()); + } + pNode = pNode->GetNext(); } - pNode = pNode->GetNext(); } #endif @@ -1824,7 +1838,8 @@ bool wxDb::DispAllErrors(HENV aHenv, HDBC aHdbc, HSTMT aHstmt) while (SQLError(aHenv, aHdbc, aHstmt, (SQLTCHAR FAR *) sqlState, &nativeError, (SQLTCHAR FAR *) errorMsg, SQL_MAX_MESSAGE_LENGTH - 1, &cbErrorMsg) == SQL_SUCCESS) { - odbcErrMsg.Printf(wxT("SQL State = %s\nNative Error Code = %li\nError Message = %s\n"), sqlState, nativeError, errorMsg); + odbcErrMsg.Printf(wxT("SQL State = %s\nNative Error Code = %li\nError Message = %s\n"), + sqlState, (long)nativeError, errorMsg); logError(odbcErrMsg, sqlState); if (!silent) { @@ -1862,7 +1877,8 @@ void wxDb::DispNextError(void) { wxString odbcErrMsg; - odbcErrMsg.Printf(wxT("SQL State = %s\nNative Error Code = %li\nError Message = %s\n"), sqlState, nativeError, errorMsg); + odbcErrMsg.Printf(wxT("SQL State = %s\nNative Error Code = %li\nError Message = %s\n"), + sqlState, (long)nativeError, errorMsg); logError(odbcErrMsg, sqlState); if (silent) @@ -2206,7 +2222,7 @@ bool wxDb::DropView(const wxString &viewName) cout << endl << sqlStmt.c_str() << endl; #endif - if (SQLExecDirect(hstmt, (SQLTCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) + if (SQLExecDirect(hstmt, WXSQLCAST(sqlStmt), SQL_NTS) != SQL_SUCCESS) { // Check for "Base table not found" error and ignore GetNextError(henv, hdbc, hstmt); @@ -2239,7 +2255,7 @@ bool wxDb::ExecSql(const wxString &pSqlStmt) SQLFreeStmt(hstmt, SQL_CLOSE); - retcode = SQLExecDirect(hstmt, (SQLTCHAR FAR *) pSqlStmt.c_str(), SQL_NTS); + retcode = SQLExecDirect(hstmt, WXSQLCAST(pSqlStmt), SQL_NTS); if (retcode == SQL_SUCCESS || (Dbms() == dbmsDB2 && (retcode == SQL_SUCCESS_WITH_INFO || retcode == SQL_NO_DATA_FOUND))) { @@ -2420,7 +2436,7 @@ int wxDb::GetKeyFields(const wxString &tableName, wxDbColInf* colInf, UWORD noCo retcode = SQLPrimaryKeys(hstmt, NULL, 0, /* Catalog name */ NULL, 0, /* Schema name */ - (SQLTCHAR FAR *) tableName.c_str(), SQL_NTS); /* Table name */ + WXSQLCAST(tableName), SQL_NTS); /* Table name */ /*---------------------------------------------------------------------*/ /* Fetch and display the result set. This will be a list of the */ @@ -2447,7 +2463,7 @@ int wxDb::GetKeyFields(const wxString &tableName, wxDbColInf* colInf, UWORD noCo retcode = SQLForeignKeys(hstmt, NULL, 0, /* Primary catalog */ NULL, 0, /* Primary schema */ - (SQLTCHAR FAR *)tableName.c_str(), SQL_NTS,/* Primary table */ + WXSQLCAST(tableName), SQL_NTS,/* Primary table */ NULL, 0, /* Foreign catalog */ NULL, 0, /* Foreign schema */ NULL, 0); /* Foreign table */ @@ -2496,7 +2512,7 @@ int wxDb::GetKeyFields(const wxString &tableName, wxDbColInf* colInf, UWORD noCo NULL, 0, /* Primary table */ NULL, 0, /* Foreign catalog */ NULL, 0, /* Foreign schema */ - (SQLTCHAR *)tableName.c_str(), SQL_NTS);/* Foreign table */ + WXSQLCAST(tableName), SQL_NTS);/* Foreign table */ /*---------------------------------------------------------------------*/ /* Fetch and display the result set. This will be all of the */ @@ -2614,8 +2630,8 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) { retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers - (SQLTCHAR *) UserID.c_str(), SQL_NTS, // Owner - (SQLTCHAR *) TableName.c_str(), SQL_NTS, + WXSQLCAST(UserID), SQL_NTS, // Owner + WXSQLCAST(TableName), SQL_NTS, NULL, 0); // All columns } else @@ -2623,7 +2639,7 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers NULL, 0, // Owner - (SQLTCHAR *) TableName.c_str(), SQL_NTS, + WXSQLCAST(TableName), SQL_NTS, NULL, 0); // All columns } if (retcode != SQL_SUCCESS) @@ -2770,8 +2786,8 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, UWORD *numCols, const wx { retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers - (SQLTCHAR *) UserID.c_str(), SQL_NTS, // Owner - (SQLTCHAR *) TableName.c_str(), SQL_NTS, + WXSQLCAST(UserID), SQL_NTS, // Owner + WXSQLCAST(TableName), SQL_NTS, NULL, 0); // All columns } else @@ -2779,7 +2795,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, UWORD *numCols, const wx retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers NULL, 0, // Owner - (SQLTCHAR *) TableName.c_str(), SQL_NTS, + WXSQLCAST(TableName), SQL_NTS, NULL, 0); // All columns } if (retcode != SQL_SUCCESS) @@ -3277,8 +3293,8 @@ int wxDb::GetColumnCount(const wxString &tableName, const wxChar *userID) { retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers - (SQLTCHAR *) UserID.c_str(), SQL_NTS, // Owner - (SQLTCHAR *) TableName.c_str(), SQL_NTS, + WXSQLCAST(UserID), SQL_NTS, // Owner + WXSQLCAST(TableName), SQL_NTS, NULL, 0); // All columns } else @@ -3286,7 +3302,7 @@ int wxDb::GetColumnCount(const wxString &tableName, const wxChar *userID) retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers NULL, 0, // Owner - (SQLTCHAR *) TableName.c_str(), SQL_NTS, + WXSQLCAST(TableName), SQL_NTS, NULL, 0); // All columns } if (retcode != SQL_SUCCESS) @@ -3370,7 +3386,7 @@ wxDbInf *wxDb::GetCatalog(const wxChar *userID) { retcode = SQLTables(hstmt, NULL, 0, // All qualifiers - (SQLTCHAR *) UserID.c_str(), SQL_NTS, // User specified + WXSQLCAST(UserID), SQL_NTS, // User specified NULL, 0, // All tables NULL, 0); // All columns } @@ -3477,7 +3493,7 @@ bool wxDb::Catalog(const wxChar *userID, const wxString &fileName) { retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers - (SQLTCHAR *) UserID.c_str(), SQL_NTS, // User specified + WXSQLCAST(UserID), SQL_NTS, // User specified NULL, 0, // All tables NULL, 0); // All columns } @@ -3612,8 +3628,8 @@ bool wxDb::TableExists(const wxString &tableName, const wxChar *userID, const wx { retcode = SQLTables(hstmt, NULL, 0, // All qualifiers - (SQLTCHAR *) UserID.c_str(), SQL_NTS, // Only tables owned by this user - (SQLTCHAR FAR *)TableName.c_str(), SQL_NTS, + WXSQLCAST(UserID), SQL_NTS, // Only tables owned by this user + WXSQLCAST(TableName), SQL_NTS, NULL, 0); // All table types } else @@ -3621,7 +3637,7 @@ bool wxDb::TableExists(const wxString &tableName, const wxChar *userID, const wx retcode = SQLTables(hstmt, NULL, 0, // All qualifiers NULL, 0, // All owners - (SQLTCHAR FAR *)TableName.c_str(), SQL_NTS, + WXSQLCAST(TableName), SQL_NTS, NULL, 0); // All table types } if (retcode != SQL_SUCCESS) @@ -3680,15 +3696,15 @@ bool wxDb::TablePrivileges(const wxString &tableName, const wxString &priv, cons { retcode = SQLTablePrivileges(hstmt, NULL, 0, // Catalog - (SQLTCHAR FAR *)Schema.c_str(), SQL_NTS, // Schema - (SQLTCHAR FAR *)TableName.c_str(), SQL_NTS); + WXSQLCAST(Schema), SQL_NTS, // Schema + WXSQLCAST(TableName), SQL_NTS); } else { retcode = SQLTablePrivileges(hstmt, NULL, 0, // Catalog NULL, 0, // Schema - (SQLTCHAR FAR *)TableName.c_str(), SQL_NTS); + WXSQLCAST(TableName), SQL_NTS); } #ifdef DBDEBUG_CONSOLE @@ -4085,6 +4101,28 @@ bool wxDb::ModifyColumn(const wxString &tableName, const wxString &columnName, } // wxDb::ModifyColumn() +/********** wxDb::EscapeSqlChars() **********/ +wxString wxDb::EscapeSqlChars(const wxString& valueOrig) +{ + wxString value(valueOrig); + switch (Dbms()) + { + case dbmsACCESS: + // Access doesn't seem to care about backslashes, so only escape single quotes. + value.Replace(wxT("'"), wxT("''")); + break; + + default: + // All the others are supposed to be the same for now, add special + // handling for them if necessary + value.Replace(wxT("\\"), wxT("\\\\")); + value.Replace(wxT("'"), wxT("\\'")); + break; + } + + return value; +} // wxDb::EscapeSqlChars() + /********** wxDbGetConnection() **********/ wxDb WXDLLIMPEXP_ODBC *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCursors)