#endif
#include "wx/filefn.h"
-#include "wx/wxchar.h"
+#include "wx/crt.h"
#include <stdio.h>
#include <string.h>
#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")
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
// 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)
{
if ((Dbms() == dbmsORACLE) ||
(Dbms() == dbmsMAXDB))
UserID = UserID.Upper();
-
- return UserID.c_str();
} // wxDb::convertUserID()
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))
}
// 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))
// 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);
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))
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) &&
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
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)
{
{
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)
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);
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)))
{
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 */
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 */
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 */
{
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
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)
{
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
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)
{
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
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)
{
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
}
{
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
}
{
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
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)
{
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
} // 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)