X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e262868d430219d285e8a4d4aeaaa6fe4e6fde25..b6a20a20d010d643e52914f51aa0700df0da925f:/src/common/db.cpp diff --git a/src/common/db.cpp b/src/common/db.cpp index f7227632ff..8403a4ca42 100644 --- a/src/common/db.cpp +++ b/src/common/db.cpp @@ -22,19 +22,19 @@ // Notice: This class library and its intellectual design are free of charge for use, // modification, enhancement, debugging under the following conditions: // 1) These classes may only be used as part of the implementation of a -// wxWindows-based application -// 2) All enhancements and bug fixes are to be submitted back to the wxWindows -// user groups free of all charges for use with the wxWindows library. +// wxWidgets-based application +// 2) All enhancements and bug fixes are to be submitted back to the wxWidgets +// user groups free of all charges for use with the wxWidgets library. // 3) These classes may not be distributed as part of any other class library, // DLL, text (written or electronic), other than a complete distribution of -// the wxWindows GUI development toolkit. +// the wxWidgets GUI development toolkit. /////////////////////////////////////////////////////////////////////////////// /* // SYNOPSIS START // SYNOPSIS STOP */ -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "db.h" #endif @@ -53,9 +53,6 @@ #include "wx/object.h" #include "wx/list.h" #include "wx/utils.h" - #if wxUSE_GUI - #include "wx/msgdlg.h" - #endif #include "wx/log.h" #endif #include "wx/filefn.h" @@ -71,8 +68,11 @@ #include "wx/db.h" -WXDLLEXPORT_DATA(wxDbList*) PtrBegDbList = 0; +// DLL options compatibility check: +#include "wx/app.h" +WX_CHECK_BUILD_OPTIONS("wxODBC") +WXDLLIMPEXP_DATA_ODBC(wxDbList*) PtrBegDbList = 0; wxChar const *SQL_LOG_FILENAME = wxT("sqllog.txt"); wxChar const *SQL_CATALOG_FILENAME = wxT("catalog.txt"); @@ -167,10 +167,13 @@ bool wxDbConnectInf::Initialize() Dsn[0] = 0; Uid[0] = 0; AuthStr[0] = 0; + ConnectionStr[0] = 0; Description.Empty(); FileType.Empty(); DefaultDir.Empty(); + useConnectionStr = FALSE; + return TRUE; } // wxDbConnectInf::Initialize() @@ -219,7 +222,7 @@ void wxDbConnectInf::SetDsn(const wxString &dsn) void wxDbConnectInf::SetUserID(const wxString &uid) { wxASSERT(uid.Length() < sizeof(Uid)); - wxStrcpy(Uid,uid); + wxStrcpy(Uid, uid); } // wxDbConnectInf::SetUserID() @@ -227,9 +230,17 @@ void wxDbConnectInf::SetPassword(const wxString &password) { wxASSERT(password.Length() < sizeof(AuthStr)); - wxStrcpy(AuthStr,password); + wxStrcpy(AuthStr, password); } // wxDbConnectInf::SetPassword() +void wxDbConnectInf::SetConnectionStr(const wxString &connectStr) +{ + wxASSERT(connectStr.Length() < sizeof(ConnectionStr)); + + useConnectionStr = wxStrlen(connectStr) > 0; + + wxStrcpy(ConnectionStr, connectStr); +} // wxDbConnectInf::SetConnectionStr() /********** wxDbColFor Constructor **********/ @@ -540,6 +551,7 @@ void wxDb::initialize() // Mark database as not open as of yet dbIsOpen = FALSE; dbIsCached = FALSE; + dbOpenedWithConnectionString = FALSE; } // wxDb::initialize() @@ -562,7 +574,8 @@ const wxChar *wxDb::convertUserID(const wxChar *userID, wxString &UserID) UserID.Empty(); // dBase does not use user names, and some drivers fail if you try to pass one - if (Dbms() == dbmsDBASE) + if ( Dbms() == dbmsDBASE + || Dbms() == dbmsXBASE_SEQUITER ) UserID.Empty(); // Oracle user names may only be in uppercase, so force @@ -574,48 +587,8 @@ const wxChar *wxDb::convertUserID(const wxChar *userID, wxString &UserID) } // wxDb::convertUserID() -/********** wxDb::Open() **********/ -bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthStr) +bool wxDb::open(bool failOnDataTypeUnsupported) { - wxASSERT(Dsn.Length()); - dsn = Dsn; - uid = Uid; - authStr = AuthStr; - - RETCODE retcode; - - if (!FwdOnlyCursors()) - { - // Specify that the ODBC cursor library be used, if needed. This must be - // specified before the connection is made. - retcode = SQLSetConnectOption(hdbc, SQL_ODBC_CURSORS, SQL_CUR_USE_IF_NEEDED); - -#ifdef DBDEBUG_CONSOLE - if (retcode == SQL_SUCCESS) - cout << wxT("SQLSetConnectOption(CURSOR_LIB) successful") << endl; - else - cout << wxT("SQLSetConnectOption(CURSOR_LIB) failed") << endl; -#endif - } - - // Connect to the data source - retcode = SQLConnect(hdbc, (UCHAR FAR *) dsn.c_str(), SQL_NTS, - (UCHAR FAR *) uid.c_str(), SQL_NTS, - (UCHAR FAR *) authStr.c_str(), SQL_NTS); - -/* - if (retcode == SQL_SUCCESS_WITH_INFO) - DispAllErrors(henv, hdbc); - else if (retcode != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); - - if (retcode == SQL_ERROR) - return(DispAllErrors(henv, hdbc)); -*/ - if ((retcode != SQL_SUCCESS) && - (retcode != SQL_SUCCESS_WITH_INFO)) - return(DispAllErrors(henv, hdbc)); - /* If using Intersolv branded ODBC drivers, this is the place where you would substitute your branded driver license information @@ -636,7 +609,7 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt return(FALSE); // Query the data source for inf. about itself - if (!getDbInfo()) + if (!getDbInfo(failOnDataTypeUnsupported)) return(FALSE); // Query the data source regarding data type information @@ -695,7 +668,10 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt if (!getDataTypeInfo(SQL_FLOAT,typeInfFloat)) if (!getDataTypeInfo(SQL_DECIMAL,typeInfFloat)) if (!getDataTypeInfo(SQL_NUMERIC,typeInfFloat)) - return(FALSE); + { + if (failOnDataTypeUnsupported) + return(FALSE); + } else typeInfFloat.FsqlType = SQL_NUMERIC; else @@ -713,7 +689,10 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt // If SQL_INTEGER is not supported, use the floating point // data type to store integers as well as floats if (!getDataTypeInfo(typeInfFloat.FsqlType, typeInfInteger)) - return(FALSE); + { + if (failOnDataTypeUnsupported) + return(FALSE); + } else typeInfInteger.FsqlType = typeInfFloat.FsqlType; } @@ -721,32 +700,42 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt typeInfInteger.FsqlType = SQL_INTEGER; // Date/Time - if (Dbms() != dbmsDBASE) - { - if (!getDataTypeInfo(SQL_TIMESTAMP,typeInfDate)) - return(FALSE); - else - typeInfDate.FsqlType = SQL_TIMESTAMP; - } - else + if (!getDataTypeInfo(SQL_TIMESTAMP,typeInfDate)) { if (!getDataTypeInfo(SQL_DATE,typeInfDate)) - return(FALSE); + { +#ifdef SQL_DATETIME + if (getDataTypeInfo(SQL_DATETIME,typeInfDate)) + { + typeInfDate.FsqlType = SQL_TIME; + } + else +#endif // SQL_DATETIME defined + { + if (failOnDataTypeUnsupported) + return(FALSE); + } + } else typeInfDate.FsqlType = SQL_DATE; } + else + typeInfDate.FsqlType = SQL_TIMESTAMP; + if (!getDataTypeInfo(SQL_LONGVARBINARY, typeInfBlob)) { if (!getDataTypeInfo(SQL_VARBINARY,typeInfBlob)) - return(FALSE); + { + if (failOnDataTypeUnsupported) + return(FALSE); + } else typeInfBlob.FsqlType = SQL_VARBINARY; } else typeInfBlob.FsqlType = SQL_LONGVARBINARY; -//typeInfBlob.TypeName = "BLOB"; #ifdef DBDEBUG_CONSOLE cout << wxT("VARCHAR DATA TYPE: ") << typeInfVarchar.TypeName << endl; @@ -759,22 +748,117 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt // Completed Successfully return(TRUE); +} + +bool wxDb::Open(const wxString& inConnectStr, bool failOnDataTypeUnsupported) +{ + wxASSERT(inConnectStr.Length()); + dsn = wxT(""); + uid = wxT(""); + authStr = wxT(""); + + RETCODE retcode; + + if (!FwdOnlyCursors()) + { + // Specify that the ODBC cursor library be used, if needed. This must be + // specified before the connection is made. + retcode = SQLSetConnectOption(hdbc, SQL_ODBC_CURSORS, SQL_CUR_USE_IF_NEEDED); + +#ifdef DBDEBUG_CONSOLE + if (retcode == SQL_SUCCESS) + cout << wxT("SQLSetConnectOption(CURSOR_LIB) successful") << endl; + else + cout << wxT("SQLSetConnectOption(CURSOR_LIB) failed") << endl; +#else + wxUnusedVar(retcode); +#endif + } + + // Connect to the data source + SQLTCHAR outConnectBuffer[SQL_MAX_CONNECTSTR_LEN+1]; // MS recommends at least 1k buffer + short outConnectBufferLen; + + inConnectionStr = inConnectStr; + + retcode = SQLDriverConnect(hdbc, NULL, (SQLTCHAR FAR *)inConnectionStr.c_str(), + inConnectionStr.Length(), (SQLTCHAR FAR *)outConnectBuffer, + sizeof(outConnectBuffer), &outConnectBufferLen, SQL_DRIVER_COMPLETE ); + + if ((retcode != SQL_SUCCESS) && + (retcode != SQL_SUCCESS_WITH_INFO)) + return(DispAllErrors(henv, hdbc)); + + outConnectBuffer[outConnectBufferLen] = 0; + outConnectionStr = outConnectBuffer; + dbOpenedWithConnectionString = TRUE; + + return open(failOnDataTypeUnsupported); +} + +/********** wxDb::Open() **********/ +bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthStr, bool failOnDataTypeUnsupported) +{ + wxASSERT(Dsn.Length()); + dsn = Dsn; + uid = Uid; + authStr = AuthStr; + + inConnectionStr = wxT(""); + outConnectionStr = wxT(""); + + RETCODE retcode; + + if (!FwdOnlyCursors()) + { + // Specify that the ODBC cursor library be used, if needed. This must be + // specified before the connection is made. + retcode = SQLSetConnectOption(hdbc, SQL_ODBC_CURSORS, SQL_CUR_USE_IF_NEEDED); + +#ifdef DBDEBUG_CONSOLE + if (retcode == SQL_SUCCESS) + cout << wxT("SQLSetConnectOption(CURSOR_LIB) successful") << endl; + else + cout << wxT("SQLSetConnectOption(CURSOR_LIB) failed") << endl; +#else + wxUnusedVar( retcode ); +#endif + } + + // 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); + + if ((retcode != SQL_SUCCESS) && + (retcode != SQL_SUCCESS_WITH_INFO)) + return(DispAllErrors(henv, hdbc)); + + return open(failOnDataTypeUnsupported); } // wxDb::Open() -bool wxDb::Open(wxDbConnectInf *dbConnectInf) +bool wxDb::Open(wxDbConnectInf *dbConnectInf, bool failOnDataTypeUnsupported) { - return Open(dbConnectInf->GetDsn(), dbConnectInf->GetUserID(), - dbConnectInf->GetPassword()); + wxASSERT(dbConnectInf); + + // Use the connection string if one is present + if (dbConnectInf->UseConnectionStr()) + return Open(GetConnectionInStr(), failOnDataTypeUnsupported); + else + return Open(dbConnectInf->GetDsn(), dbConnectInf->GetUserID(), + dbConnectInf->GetPassword(), failOnDataTypeUnsupported); } // wxDb::Open() bool wxDb::Open(wxDb *copyDb) { - dsn = copyDb->GetDatasourceName(); - uid = copyDb->GetUsername(); - authStr = copyDb->GetPassword(); + dsn = copyDb->GetDatasourceName(); + uid = copyDb->GetUsername(); + authStr = copyDb->GetPassword(); + inConnectionStr = copyDb->GetConnectionInStr(); + outConnectionStr = copyDb->GetConnectionOutStr(); RETCODE retcode; @@ -789,15 +873,41 @@ bool wxDb::Open(wxDb *copyDb) cout << wxT("SQLSetConnectOption(CURSOR_LIB) successful") << endl; else cout << wxT("SQLSetConnectOption(CURSOR_LIB) failed") << endl; +#else + wxUnusedVar( retcode ); #endif } - // Connect to the data source - retcode = SQLConnect(hdbc, (UCHAR FAR *) dsn.c_str(), SQL_NTS, - (UCHAR FAR *) uid.c_str(), SQL_NTS, - (UCHAR FAR *) authStr.c_str(), SQL_NTS); + if (copyDb->OpenedWithConnectionString()) + { + // Connect to the data source + SQLTCHAR outConnectBuffer[SQL_MAX_CONNECTSTR_LEN+1]; + short outConnectBufferLen; + + inConnectionStr = copyDb->GetConnectionInStr(); - if (retcode == SQL_ERROR) + retcode = SQLDriverConnect(hdbc, NULL, (SQLTCHAR FAR *)inConnectionStr.c_str(), + inConnectionStr.Length(), (SQLTCHAR FAR *)outConnectBuffer, + sizeof(outConnectBuffer), &outConnectBufferLen, SQL_DRIVER_COMPLETE); + + if ((retcode != SQL_SUCCESS) && + (retcode != SQL_SUCCESS_WITH_INFO)) + return(DispAllErrors(henv, hdbc)); + + outConnectBuffer[outConnectBufferLen] = 0; + outConnectionStr = outConnectBuffer; + dbOpenedWithConnectionString = TRUE; + } + 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); + } + + if ((retcode != SQL_SUCCESS) && + (retcode != SQL_SUCCESS_WITH_INFO)) return(DispAllErrors(henv, hdbc)); /* @@ -971,113 +1081,263 @@ bool wxDb::setConnectionOptions(void) /********** wxDb::getDbInfo() **********/ -bool wxDb::getDbInfo(void) +bool wxDb::getDbInfo(bool failOnDataTypeUnsupported) { SWORD cb; RETCODE retcode; - if (SQLGetInfo(hdbc, SQL_SERVER_NAME, (UCHAR*) dbInf.serverName, 80, &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_SERVER_NAME, (UCHAR*) dbInf.serverName, 80, &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_DATABASE_NAME, (UCHAR*) dbInf.databaseName, 128, &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_DATABASE_NAME, (UCHAR*) dbInf.databaseName, 128, &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_DBMS_NAME, (UCHAR*) dbInf.dbmsName, 40, &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_DBMS_NAME, (UCHAR*) dbInf.dbmsName, 40, &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } // 16-Mar-1999 // After upgrading to MSVC6, the original 20 char buffer below was insufficient, // causing database connectivity to fail in some cases. retcode = SQLGetInfo(hdbc, SQL_DBMS_VER, (UCHAR*) dbInf.dbmsVer, 64, &cb); - if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) - return(DispAllErrors(henv, hdbc)); + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_ACTIVE_CONNECTIONS, (UCHAR*) &dbInf.maxConnections, sizeof(dbInf.maxConnections), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_ACTIVE_CONNECTIONS, (UCHAR*) &dbInf.maxConnections, sizeof(dbInf.maxConnections), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_ACTIVE_STATEMENTS, (UCHAR*) &dbInf.maxStmts, sizeof(dbInf.maxStmts), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_ACTIVE_STATEMENTS, (UCHAR*) &dbInf.maxStmts, sizeof(dbInf.maxStmts), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_DRIVER_NAME, (UCHAR*) dbInf.driverName, 40, &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_DRIVER_NAME, (UCHAR*) dbInf.driverName, 40, &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_DRIVER_ODBC_VER, (UCHAR*) dbInf.odbcVer, 60, &cb) == SQL_ERROR) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_DRIVER_ODBC_VER, (UCHAR*) dbInf.odbcVer, 60, &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } retcode = SQLGetInfo(hdbc, SQL_ODBC_VER, (UCHAR*) dbInf.drvMgrOdbcVer, 60, &cb); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) - return(DispAllErrors(henv, hdbc)); + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_DRIVER_VER, (UCHAR*) dbInf.driverVer, 60, &cb) == SQL_ERROR) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_DRIVER_VER, (UCHAR*) dbInf.driverVer, 60, &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_ODBC_API_CONFORMANCE, (UCHAR*) &dbInf.apiConfLvl, sizeof(dbInf.apiConfLvl), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_ODBC_API_CONFORMANCE, (UCHAR*) &dbInf.apiConfLvl, sizeof(dbInf.apiConfLvl), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_ODBC_SAG_CLI_CONFORMANCE, (UCHAR*) &dbInf.cliConfLvl, sizeof(dbInf.cliConfLvl), &cb) != SQL_SUCCESS) -// return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_ODBC_SAG_CLI_CONFORMANCE, (UCHAR*) &dbInf.cliConfLvl, sizeof(dbInf.cliConfLvl), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) { // Not all drivers support this call - Nick Gorham(unixODBC) dbInf.cliConfLvl = 0; + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; } - if (SQLGetInfo(hdbc, SQL_ODBC_SQL_CONFORMANCE, (UCHAR*) &dbInf.sqlConfLvl, sizeof(dbInf.sqlConfLvl), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_ODBC_SQL_CONFORMANCE, (UCHAR*) &dbInf.sqlConfLvl, sizeof(dbInf.sqlConfLvl), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_OUTER_JOINS, (UCHAR*) dbInf.outerJoins, 2, &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_OUTER_JOINS, (UCHAR*) dbInf.outerJoins, 2, &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_PROCEDURES, (UCHAR*) dbInf.procedureSupport, 2, &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_PROCEDURES, (UCHAR*) dbInf.procedureSupport, 2, &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_ACCESSIBLE_TABLES, (UCHAR*) dbInf.accessibleTables, 2, &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_ACCESSIBLE_TABLES, (UCHAR*) dbInf.accessibleTables, 2, &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_CURSOR_COMMIT_BEHAVIOR, (UCHAR*) &dbInf.cursorCommitBehavior, sizeof(dbInf.cursorCommitBehavior), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_CURSOR_COMMIT_BEHAVIOR, (UCHAR*) &dbInf.cursorCommitBehavior, sizeof(dbInf.cursorCommitBehavior), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_CURSOR_ROLLBACK_BEHAVIOR, (UCHAR*) &dbInf.cursorRollbackBehavior, sizeof(dbInf.cursorRollbackBehavior), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_CURSOR_ROLLBACK_BEHAVIOR, (UCHAR*) &dbInf.cursorRollbackBehavior, sizeof(dbInf.cursorRollbackBehavior), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_NON_NULLABLE_COLUMNS, (UCHAR*) &dbInf.supportNotNullClause, sizeof(dbInf.supportNotNullClause), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_NON_NULLABLE_COLUMNS, (UCHAR*) &dbInf.supportNotNullClause, sizeof(dbInf.supportNotNullClause), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_ODBC_SQL_OPT_IEF, (UCHAR*) dbInf.supportIEF, 2, &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_ODBC_SQL_OPT_IEF, (UCHAR*) dbInf.supportIEF, 2, &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_DEFAULT_TXN_ISOLATION, (UCHAR*) &dbInf.txnIsolation, sizeof(dbInf.txnIsolation), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_DEFAULT_TXN_ISOLATION, (UCHAR*) &dbInf.txnIsolation, sizeof(dbInf.txnIsolation), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_TXN_ISOLATION_OPTION, (UCHAR*) &dbInf.txnIsolationOptions, sizeof(dbInf.txnIsolationOptions), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_TXN_ISOLATION_OPTION, (UCHAR*) &dbInf.txnIsolationOptions, sizeof(dbInf.txnIsolationOptions), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_FETCH_DIRECTION, (UCHAR*) &dbInf.fetchDirections, sizeof(dbInf.fetchDirections), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_FETCH_DIRECTION, (UCHAR*) &dbInf.fetchDirections, sizeof(dbInf.fetchDirections), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_LOCK_TYPES, (UCHAR*) &dbInf.lockTypes, sizeof(dbInf.lockTypes), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_LOCK_TYPES, (UCHAR*) &dbInf.lockTypes, sizeof(dbInf.lockTypes), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_POS_OPERATIONS, (UCHAR*) &dbInf.posOperations, sizeof(dbInf.posOperations), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_POS_OPERATIONS, (UCHAR*) &dbInf.posOperations, sizeof(dbInf.posOperations), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_POSITIONED_STATEMENTS, (UCHAR*) &dbInf.posStmts, sizeof(dbInf.posStmts), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_POSITIONED_STATEMENTS, (UCHAR*) &dbInf.posStmts, sizeof(dbInf.posStmts), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_SCROLL_CONCURRENCY, (UCHAR*) &dbInf.scrollConcurrency, sizeof(dbInf.scrollConcurrency), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_SCROLL_CONCURRENCY, (UCHAR*) &dbInf.scrollConcurrency, sizeof(dbInf.scrollConcurrency), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_SCROLL_OPTIONS, (UCHAR*) &dbInf.scrollOptions, sizeof(dbInf.scrollOptions), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_SCROLL_OPTIONS, (UCHAR*) &dbInf.scrollOptions, sizeof(dbInf.scrollOptions), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_STATIC_SENSITIVITY, (UCHAR*) &dbInf.staticSensitivity, sizeof(dbInf.staticSensitivity), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_STATIC_SENSITIVITY, (UCHAR*) &dbInf.staticSensitivity, sizeof(dbInf.staticSensitivity), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_TXN_CAPABLE, (UCHAR*) &dbInf.txnCapable, sizeof(dbInf.txnCapable), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_TXN_CAPABLE, (UCHAR*) &dbInf.txnCapable, sizeof(dbInf.txnCapable), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } - if (SQLGetInfo(hdbc, SQL_LOGIN_TIMEOUT, (UCHAR*) &dbInf.loginTimeout, sizeof(dbInf.loginTimeout), &cb) != SQL_SUCCESS) - return(DispAllErrors(henv, hdbc)); + retcode = SQLGetInfo(hdbc, SQL_LOGIN_TIMEOUT, (UCHAR*) &dbInf.loginTimeout, sizeof(dbInf.loginTimeout), &cb); + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) + { + DispAllErrors(henv, hdbc); + if (failOnDataTypeUnsupported) + return FALSE; + } #ifdef DBDEBUG_CONSOLE cout << wxT("***** DATA SOURCE INFORMATION *****") << endl; @@ -1295,8 +1555,10 @@ bool wxDb::getDataTypeInfo(SWORD fSqlType, wxDbSqlTypeInfo &structSQLTypeInfo) // Get information about the data type specified if (SQLGetTypeInfo(hstmt, fSqlType) != SQL_SUCCESS) return(DispAllErrors(henv, hdbc, hstmt)); + // Fetch the record - if ((retcode = SQLFetch(hstmt)) != SQL_SUCCESS) + retcode = SQLFetch(hstmt); + if (retcode != SQL_SUCCESS) { #ifdef DBDEBUG_CONSOLE if (retcode == SQL_NO_DATA_FOUND) @@ -1308,6 +1570,7 @@ bool wxDb::getDataTypeInfo(SWORD fSqlType, wxDbSqlTypeInfo &structSQLTypeInfo) } wxChar typeName[DB_TYPE_NAME_LEN+1]; + // Obtain columns from the record if (SQLGetData(hstmt, 1, SQL_C_CHAR, (UCHAR*) typeName, DB_TYPE_NAME_LEN, &cbRet) != SQL_SUCCESS) return(DispAllErrors(henv, hdbc, hstmt)); @@ -1395,19 +1658,19 @@ void wxDb::Close(void) #ifdef __WXDEBUG__ wxTablesInUse *tiu; - wxNode *pNode; - pNode = TablesInUse.First(); + wxList::compatibility_iterator pNode; + pNode = TablesInUse.GetFirst(); wxString s,s2; while (pNode) { - tiu = (wxTablesInUse *)pNode->Data(); + tiu = (wxTablesInUse *)pNode->GetData(); if (tiu->pDb == this) { s.Printf(wxT("(%-20s) tableID:[%6lu] pDb:[%p]"), tiu->tableName,tiu->tableID,tiu->pDb); - s2.Printf(wxT("Orphaned found using pDb:[%p]"),this); - wxLogDebug (s.c_str(),s2.c_str()); + s2.Printf(wxT("Orphaned table found using pDb:[%p]"),this); + wxLogDebug(s.c_str(),s2.c_str()); } - pNode = pNode->Next(); + pNode = pNode->GetNext(); } #endif @@ -1470,7 +1733,7 @@ bool wxDb::DispAllErrors(HENV aHenv, HDBC aHdbc, HSTMT aHstmt) { wxString odbcErrMsg; - while (SQLError(aHenv, aHdbc, aHstmt, (UCHAR FAR *) sqlState, &nativeError, (UCHAR FAR *) errorMsg, SQL_MAX_MESSAGE_LENGTH - 1, &cbErrorMsg) == SQL_SUCCESS) + 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); logError(odbcErrMsg, sqlState); @@ -1497,7 +1760,7 @@ bool wxDb::DispAllErrors(HENV aHenv, HDBC aHdbc, HSTMT aHstmt) /********** wxDb::GetNextError() **********/ bool wxDb::GetNextError(HENV aHenv, HDBC aHdbc, HSTMT aHstmt) { - if (SQLError(aHenv, aHdbc, aHstmt, (UCHAR FAR *) sqlState, &nativeError, (UCHAR FAR *) errorMsg, SQL_MAX_MESSAGE_LENGTH - 1, &cbErrorMsg) == SQL_SUCCESS) + if (SQLError(aHenv, aHdbc, aHstmt, (SQLTCHAR FAR *) sqlState, &nativeError, (SQLTCHAR FAR *) errorMsg, SQL_MAX_MESSAGE_LENGTH - 1, &cbErrorMsg) == SQL_SUCCESS) return(TRUE); else return(FALSE); @@ -1784,7 +2047,7 @@ bool wxDb::Grant(int privileges, const wxString &tableName, const wxString &user } sqlStmt += wxT(" ON "); - sqlStmt += tableName; + sqlStmt += SQLTableName(tableName); sqlStmt += wxT(" TO "); sqlStmt += userList; @@ -1853,7 +2116,7 @@ bool wxDb::DropView(const wxString &viewName) cout << endl << sqlStmt.c_str() << endl; #endif - if (SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) + if (SQLExecDirect(hstmt, (SQLTCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) { // Check for "Base table not found" error and ignore GetNextError(henv, hdbc, hstmt); @@ -1886,7 +2149,7 @@ bool wxDb::ExecSql(const wxString &pSqlStmt) SQLFreeStmt(hstmt, SQL_CLOSE); - retcode = SQLExecDirect(hstmt, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS); + retcode = SQLExecDirect(hstmt, (SQLTCHAR FAR *) pSqlStmt.c_str(), SQL_NTS); if (retcode == SQL_SUCCESS || (Dbms() == dbmsDB2 && (retcode == SQL_SUCCESS_WITH_INFO || retcode == SQL_NO_DATA_FOUND))) { @@ -1964,7 +2227,7 @@ int wxDb::GetKeyFields(const wxString &tableName, wxDbColInf* colInf, UWORD noCo retcode = SQLPrimaryKeys(hstmt, NULL, 0, /* Catalog name */ NULL, 0, /* Schema name */ - (UCHAR FAR *) tableName.c_str(), SQL_NTS); /* Table name */ + (SQLTCHAR FAR *) tableName.c_str(), SQL_NTS); /* Table name */ /*---------------------------------------------------------------------*/ /* Fetch and display the result set. This will be a list of the */ @@ -1991,7 +2254,7 @@ int wxDb::GetKeyFields(const wxString &tableName, wxDbColInf* colInf, UWORD noCo retcode = SQLForeignKeys(hstmt, NULL, 0, /* Primary catalog */ NULL, 0, /* Primary schema */ - (UCHAR FAR *)tableName.c_str(), SQL_NTS,/* Primary table */ + (SQLTCHAR FAR *)tableName.c_str(), SQL_NTS,/* Primary table */ NULL, 0, /* Foreign catalog */ NULL, 0, /* Foreign schema */ NULL, 0); /* Foreign table */ @@ -2037,14 +2300,13 @@ int wxDb::GetKeyFields(const wxString &tableName, wxDbColInf* colInf, UWORD noCo NULL, 0, /* Primary table */ NULL, 0, /* Foreign catalog */ NULL, 0, /* Foreign schema */ - (UCHAR *)tableName.c_str(), SQL_NTS);/* Foreign table */ + (SQLTCHAR *)tableName.c_str(), SQL_NTS);/* Foreign table */ /*---------------------------------------------------------------------*/ /* Fetch and display the result set. This will be all of the */ /* primary keys in other tables that are referred to by foreign */ /* keys in the tableName table. */ /*---------------------------------------------------------------------*/ - i = 0; while ((retcode == SQL_SUCCESS) || (retcode == SQL_SUCCESS_WITH_INFO)) { retcode = SQLFetch(hstmt); @@ -2154,8 +2416,8 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) { retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers - (UCHAR *) UserID.c_str(), SQL_NTS, // Owner - (UCHAR *) TableName.c_str(), SQL_NTS, + (SQLTCHAR *) UserID.c_str(), SQL_NTS, // Owner + (SQLTCHAR *) TableName.c_str(), SQL_NTS, NULL, 0); // All columns } else @@ -2163,7 +2425,7 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers NULL, 0, // Owner - (UCHAR *) TableName.c_str(), SQL_NTS, + (SQLTCHAR *) TableName.c_str(), SQL_NTS, NULL, 0); // All columns } if (retcode != SQL_SUCCESS) @@ -2309,8 +2571,8 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, UWORD *numCols, const wx { retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers - (UCHAR *) UserID.c_str(), SQL_NTS, // Owner - (UCHAR *) TableName.c_str(), SQL_NTS, + (SQLTCHAR *) UserID.c_str(), SQL_NTS, // Owner + (SQLTCHAR *) TableName.c_str(), SQL_NTS, NULL, 0); // All columns } else @@ -2318,7 +2580,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, UWORD *numCols, const wx retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers NULL, 0, // Owner - (UCHAR *) TableName.c_str(), SQL_NTS, + (SQLTCHAR *) TableName.c_str(), SQL_NTS, NULL, 0); // All columns } if (retcode != SQL_SUCCESS) @@ -2655,7 +2917,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh #ifdef __WXDEBUG__ default: wxString errMsg; - errMsg.Printf(wxT("SQL Data type %d currently not supported by wxWindows"), colInf[colNo].sqlDataType); + errMsg.Printf(wxT("SQL Data type %d currently not supported by wxWidgets"), colInf[colNo].sqlDataType); wxLogDebug(errMsg,wxT("ODBC DEBUG MESSAGE")); #endif } @@ -2687,7 +2949,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh // Build a generic SELECT statement which returns 0 rows wxString Stmt; - Stmt.Printf(wxT("select * from %s where 0=1"), tableName); + Stmt.Printf(wxT("select * from \"%s\" where 0=1"), tableName); // Execute query if (SQLExecDirect(hstmt, (UCHAR FAR *) Stmt.c_str(), SQL_NTS) != SQL_SUCCESS) @@ -2802,8 +3064,8 @@ int wxDb::GetColumnCount(const wxString &tableName, const wxChar *userID) { retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers - (UCHAR *) UserID.c_str(), SQL_NTS, // Owner - (UCHAR *) TableName.c_str(), SQL_NTS, + (SQLTCHAR *) UserID.c_str(), SQL_NTS, // Owner + (SQLTCHAR *) TableName.c_str(), SQL_NTS, NULL, 0); // All columns } else @@ -2811,7 +3073,7 @@ int wxDb::GetColumnCount(const wxString &tableName, const wxChar *userID) retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers NULL, 0, // Owner - (UCHAR *) TableName.c_str(), SQL_NTS, + (SQLTCHAR *) TableName.c_str(), SQL_NTS, NULL, 0); // All columns } if (retcode != SQL_SUCCESS) @@ -2862,7 +3124,6 @@ wxDbInf *wxDb::GetCatalog(const wxChar *userID) * to avoid undesired unbinding of columns. */ { - wxDbInf *pDbInf = NULL; // Array of catalog entries int noTab = 0; // Counter while filling table entries int pass; RETCODE retcode; @@ -2873,7 +3134,10 @@ wxDbInf *wxDb::GetCatalog(const wxChar *userID) convertUserID(userID,UserID); //------------------------------------------------------------- - pDbInf = new wxDbInf; // Create the Database Array + // Create the Database Array of catalog entries + + wxDbInf *pDbInf = new wxDbInf; + //------------------------------------------------------------- // Table Information // Pass 1 - Determine how many Tables there are. @@ -2893,7 +3157,7 @@ wxDbInf *wxDb::GetCatalog(const wxChar *userID) { retcode = SQLTables(hstmt, NULL, 0, // All qualifiers - (UCHAR *) UserID.c_str(), SQL_NTS, // User specified + (SQLTCHAR *) UserID.c_str(), SQL_NTS, // User specified NULL, 0, // All tables NULL, 0); // All columns } @@ -2982,7 +3246,7 @@ bool wxDb::Catalog(const wxChar *userID, const wxString &fileName) wxChar typeName[30+1]; SDWORD precision, length; - FILE *fp = fopen(fileName.c_str(),wxT("wt")); + FILE *fp = wxFopen(fileName.c_str(),wxT("wt")); if (fp == NULL) return(FALSE); @@ -2999,7 +3263,7 @@ bool wxDb::Catalog(const wxChar *userID, const wxString &fileName) { retcode = SQLColumns(hstmt, NULL, 0, // All qualifiers - (UCHAR *) UserID.c_str(), SQL_NTS, // User specified + (SQLTCHAR *) UserID.c_str(), SQL_NTS, // User specified NULL, 0, // All tables NULL, 0); // All columns } @@ -3022,42 +3286,42 @@ bool wxDb::Catalog(const wxChar *userID, const wxString &fileName) tblNameSave.Empty(); int cnt = 0; - while (true) + while (TRUE) { retcode = SQLFetch(hstmt); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) break; + GetData(3,SQL_C_CHAR, (UCHAR *) tblName, DB_MAX_TABLE_NAME_LEN+1, &cb); + GetData(4,SQL_C_CHAR, (UCHAR *) colName, DB_MAX_COLUMN_NAME_LEN+1,&cb); + GetData(5,SQL_C_SSHORT,(UCHAR *)&sqlDataType, 0, &cb); + GetData(6,SQL_C_CHAR, (UCHAR *) typeName, sizeof(typeName), &cb); + GetData(7,SQL_C_SLONG, (UCHAR *)&precision, 0, &cb); + GetData(8,SQL_C_SLONG, (UCHAR *)&length, 0, &cb); + if (wxStrcmp(tblName, tblNameSave.c_str())) { if (cnt) - fputs(wxT("\n"), fp); - fputs(wxT("================================ "), fp); - fputs(wxT("================================ "), fp); - fputs(wxT("===================== "), fp); - fputs(wxT("========= "), fp); - fputs(wxT("=========\n"), fp); + wxFputs(wxT("\n"), fp); + wxFputs(wxT("================================ "), fp); + wxFputs(wxT("================================ "), fp); + wxFputs(wxT("===================== "), fp); + wxFputs(wxT("========= "), fp); + wxFputs(wxT("=========\n"), fp); outStr.Printf(wxT("%-32s %-32s %-21s %9s %9s\n"), wxT("TABLE NAME"), wxT("COLUMN NAME"), wxT("DATA TYPE"), wxT("PRECISION"), wxT("LENGTH")); - fputs(outStr.c_str(), fp); - fputs(wxT("================================ "), fp); - fputs(wxT("================================ "), fp); - fputs(wxT("===================== "), fp); - fputs(wxT("========= "), fp); - fputs(wxT("=========\n"), fp); + wxFputs(outStr.c_str(), fp); + wxFputs(wxT("================================ "), fp); + wxFputs(wxT("================================ "), fp); + wxFputs(wxT("===================== "), fp); + wxFputs(wxT("========= "), fp); + wxFputs(wxT("=========\n"), fp); tblNameSave = tblName; } - GetData(3,SQL_C_CHAR, (UCHAR *) tblName, DB_MAX_TABLE_NAME_LEN+1, &cb); - GetData(4,SQL_C_CHAR, (UCHAR *) colName, DB_MAX_COLUMN_NAME_LEN+1,&cb); - GetData(5,SQL_C_SSHORT,(UCHAR *)&sqlDataType, 0, &cb); - GetData(6,SQL_C_CHAR, (UCHAR *) typeName, sizeof(typeName), &cb); - GetData(7,SQL_C_SLONG, (UCHAR *)&precision, 0, &cb); - GetData(8,SQL_C_SLONG, (UCHAR *)&length, 0, &cb); - - outStr.Printf(wxT("%-32s %-32s (%04d)%-15s %9d %9d\n"), + outStr.Printf(wxT("%-32s %-32s (%04d)%-15s %9ld %9ld\n"), tblName, colName, sqlDataType, typeName, precision, length); - if (fputs(outStr.c_str(), fp) == EOF) + if (wxFputs(outStr.c_str(), fp) == EOF) { SQLFreeStmt(hstmt, SQL_CLOSE); fclose(fp); @@ -3132,8 +3396,8 @@ bool wxDb::TableExists(const wxString &tableName, const wxChar *userID, const wx { retcode = SQLTables(hstmt, NULL, 0, // All qualifiers - (UCHAR *) UserID.c_str(), SQL_NTS, // Only tables owned by this user - (UCHAR FAR *)TableName.c_str(), SQL_NTS, + (SQLTCHAR *) UserID.c_str(), SQL_NTS, // Only tables owned by this user + (SQLTCHAR FAR *)TableName.c_str(), SQL_NTS, NULL, 0); // All table types } else @@ -3141,7 +3405,7 @@ bool wxDb::TableExists(const wxString &tableName, const wxChar *userID, const wx retcode = SQLTables(hstmt, NULL, 0, // All qualifiers NULL, 0, // All owners - (UCHAR FAR *)TableName.c_str(), SQL_NTS, + (SQLTCHAR FAR *)TableName.c_str(), SQL_NTS, NULL, 0); // All table types } if (retcode != SQL_SUCCESS) @@ -3163,7 +3427,7 @@ bool wxDb::TableExists(const wxString &tableName, const wxChar *userID, const wx /********** wxDb::TablePrivileges() **********/ bool wxDb::TablePrivileges(const wxString &tableName, const wxString &priv, const wxChar *userID, - const wxChar *schema, const wxString &tablePath) + const wxChar *schema, const wxString &WXUNUSED(tablePath)) { wxASSERT(tableName.Length()); @@ -3199,19 +3463,19 @@ bool wxDb::TablePrivileges(const wxString &tableName, const wxString &priv, cons { retcode = SQLTablePrivileges(hstmt, NULL, 0, // Catalog - (UCHAR FAR *)Schema.c_str(), SQL_NTS, // Schema - (UCHAR FAR *)TableName.c_str(), SQL_NTS); + (SQLTCHAR FAR *)Schema.c_str(), SQL_NTS, // Schema + (SQLTCHAR FAR *)TableName.c_str(), SQL_NTS); } else { retcode = SQLTablePrivileges(hstmt, NULL, 0, // Catalog NULL, 0, // Schema - (UCHAR FAR *)TableName.c_str(), SQL_NTS); + (SQLTCHAR FAR *)TableName.c_str(), SQL_NTS); } #ifdef DBDEBUG_CONSOLE - fprintf(stderr ,wxT("SQLTablePrivileges() returned %i \n"),retcode); + wxFprintf(stderr ,wxT("SQLTablePrivileges() returned %i \n"),retcode); #endif if ((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO)) @@ -3247,7 +3511,7 @@ bool wxDb::TablePrivileges(const wxString &tableName, const wxString &priv, cons return(DispAllErrors(henv, hdbc, hstmt)); } #ifdef DBDEBUG_CONSOLE - fprintf(stderr,wxT("Scanning %s privilege on table %s.%s granted by %s to %s\n"), + wxFprintf(stderr,wxT("Scanning %s privilege on table %s.%s granted by %s to %s\n"), result.privilege,result.tableOwner,result.tableName, result.grantor, result.grantee); #endif @@ -3281,6 +3545,34 @@ bool wxDb::TablePrivileges(const wxString &tableName, const wxString &priv, cons } // wxDb::TablePrivileges +const wxString wxDb::SQLTableName(const wxChar *tableName) +{ + wxString TableName; + + if (Dbms() == dbmsACCESS) + TableName = _T("\""); + TableName += tableName; + if (Dbms() == dbmsACCESS) + TableName += _T("\""); + + return TableName; +} // wxDb::SQLTableName() + + +const wxString wxDb::SQLColumnName(const wxChar *colName) +{ + wxString ColName; + + if (Dbms() == dbmsACCESS) + ColName = _T("\""); + ColName += colName; + if (Dbms() == dbmsACCESS) + ColName += _T("\""); + + return ColName; +} // wxDb::SQLColumnName() + + /********** wxDb::SetSqlLogging() **********/ bool wxDb::SetSqlLogging(wxDbSqlLogState state, const wxString &filename, bool append) { @@ -3291,7 +3583,7 @@ bool wxDb::SetSqlLogging(wxDbSqlLogState state, const wxString &filename, bool a { if (fpSqlLog == 0) { - fpSqlLog = fopen(filename, (append ? wxT("at") : wxT("wt"))); + fpSqlLog = wxFopen(filename, (append ? wxT("at") : wxT("wt"))); if (fpSqlLog == NULL) return(FALSE); } @@ -3320,11 +3612,11 @@ bool wxDb::WriteSqlLog(const wxString &logMsg) if (fpSqlLog == 0 || sqlLogState == sqlLogOFF) return(FALSE); - if (fputs(wxT("\n"), fpSqlLog) == EOF) + if (wxFputs(wxT("\n"), fpSqlLog) == EOF) return(FALSE); - if (fputs(logMsg, fpSqlLog) == EOF) + if (wxFputs(logMsg, fpSqlLog) == EOF) return(FALSE); - if (fputs(wxT("\n"), fpSqlLog) == EOF) + if (wxFputs(wxT("\n"), fpSqlLog) == EOF) return(FALSE); return(TRUE); @@ -3432,13 +3724,13 @@ wxDBMS wxDb::Dbms(void) if (!wxStricmp(dbInf.dbmsName,wxT("Microsoft SQL Server"))) return((wxDBMS)(dbmsType = dbmsMS_SQL_SERVER)); - if (!wxStricmp(dbInf.dbmsName,wxT("MySQL"))) - return((wxDBMS)(dbmsType = dbmsMY_SQL)); - if (!wxStricmp(dbInf.dbmsName,wxT("PostgreSQL"))) // v6.5.0 + + baseName[10] = 0; + if (!wxStricmp(baseName,wxT("PostgreSQL"))) // v6.5.0 return((wxDBMS)(dbmsType = dbmsPOSTGRES)); baseName[9] = 0; - if (!wxStricmp(dbInf.dbmsName,wxT("Pervasive"))) + if (!wxStricmp(baseName,wxT("Pervasive"))) return((wxDBMS)(dbmsType = dbmsPERVASIVE_SQL)); baseName[8] = 0; @@ -3448,16 +3740,18 @@ wxDBMS wxDb::Dbms(void) baseName[6] = 0; if (!wxStricmp(baseName,wxT("Oracle"))) return((wxDBMS)(dbmsType = dbmsORACLE)); - if (!wxStricmp(dbInf.dbmsName,wxT("ACCESS"))) + if (!wxStricmp(baseName,wxT("ACCESS"))) return((wxDBMS)(dbmsType = dbmsACCESS)); - if (!wxStricmp(dbInf.dbmsName,wxT("MySQL"))) - return((wxDBMS)(dbmsType = dbmsMY_SQL)); if (!wxStricmp(baseName,wxT("Sybase"))) return((wxDBMS)(dbmsType = dbmsSYBASE_ASE)); baseName[5] = 0; if (!wxStricmp(baseName,wxT("DBASE"))) return((wxDBMS)(dbmsType = dbmsDBASE)); + if (!wxStricmp(baseName,wxT("xBase"))) + return((wxDBMS)(dbmsType = dbmsXBASE_SEQUITER)); + if (!wxStricmp(baseName,wxT("MySQL"))) + return((wxDBMS)(dbmsType = dbmsMY_SQL)); baseName[3] = 0; if (!wxStricmp(baseName,wxT("DB2"))) @@ -3510,10 +3804,10 @@ bool wxDb::ModifyColumn(const wxString &tableName, const wxString &columnName, switch (Dbms()) { case dbmsORACLE : - alterSlashModify = "MODIFY"; + alterSlashModify = _T("MODIFY"); break; case dbmsMS_SQL_SERVER : - alterSlashModify = "ALTER COLUMN"; + alterSlashModify = _T("ALTER COLUMN"); break; case dbmsUNIDENTIFIED : return FALSE; @@ -3523,20 +3817,30 @@ bool wxDb::ModifyColumn(const wxString &tableName, const wxString &columnName, case dbmsPOSTGRES : case dbmsACCESS : case dbmsDBASE : + case dbmsXBASE_SEQUITER : default : - alterSlashModify = "MODIFY"; + alterSlashModify = _T("MODIFY"); break; } // create the SQL statement - sqlStmt.Printf(wxT("ALTER TABLE %s %s %s %s"), tableName.c_str(), alterSlashModify.c_str(), + if ( Dbms() == dbmsMY_SQL ) + { + sqlStmt.Printf(wxT("ALTER TABLE %s %s %s %s"), tableName.c_str(), alterSlashModify.c_str(), + columnName.c_str(), dataTypeName.c_str()); + } + else + { + sqlStmt.Printf(wxT("ALTER TABLE \"%s\" \"%s\" \"%s\" %s"), tableName.c_str(), alterSlashModify.c_str(), columnName.c_str(), dataTypeName.c_str()); + } // For varchars only, append the size of the column - if (dataType == DB_DATA_TYPE_VARCHAR) + if (dataType == DB_DATA_TYPE_VARCHAR && + (Dbms() != dbmsMY_SQL || dataTypeName != _T("text"))) { wxString s; - s.Printf(wxT("(%d)"), columnLength); + s.Printf(wxT("(%lu)"), columnLength); sqlStmt += s; } @@ -3553,7 +3857,7 @@ bool wxDb::ModifyColumn(const wxString &tableName, const wxString &columnName, /********** wxDbGetConnection() **********/ -wxDb WXDLLEXPORT *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCursors) +wxDb WXDLLIMPEXP_ODBC *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCursors) { wxDbList *pList; @@ -3571,17 +3875,42 @@ wxDb WXDLLEXPORT *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCurso // The database connection must be for the same datasource // name and must currently not be in use. if (pList->Free && - (pList->PtrDb->FwdOnlyCursors() == FwdOnlyCursors) && - (!wxStrcmp(pDbConfig->GetDsn(), pList->Dsn))) // Found a free connection + (pList->PtrDb->FwdOnlyCursors() == FwdOnlyCursors)) { - pList->Free = FALSE; - return(pList->PtrDb); + if (pDbConfig->UseConnectionStr()) + { + if (pList->PtrDb->OpenedWithConnectionString() && + (!wxStrcmp(pDbConfig->GetConnectionStr(), pList->ConnectionStr))) + { + // Found a free connection + pList->Free = FALSE; + return(pList->PtrDb); + } + } + else + { + if (!pList->PtrDb->OpenedWithConnectionString() && + (!wxStrcmp(pDbConfig->GetDsn(), pList->Dsn))) + { + // Found a free connection + pList->Free = FALSE; + return(pList->PtrDb); + } + } } - if (!wxStrcmp(pDbConfig->GetDsn(), pList->Dsn) && - !wxStrcmp(pDbConfig->GetUserID(), pList->Uid) && - !wxStrcmp(pDbConfig->GetPassword(), pList->AuthStr)) - matchingDbConnection = pList->PtrDb; + if (pDbConfig->UseConnectionStr()) + { + if (!wxStrcmp(pDbConfig->GetConnectionStr(), pList->ConnectionStr)) + matchingDbConnection = pList->PtrDb; + } + else + { + if (!wxStrcmp(pDbConfig->GetDsn(), pList->Dsn) && + !wxStrcmp(pDbConfig->GetUserID(), pList->Uid) && + !wxStrcmp(pDbConfig->GetPassword(), pList->AuthStr)) + matchingDbConnection = pList->PtrDb; + } } // No available connections. A new connection must be made and @@ -3603,18 +3932,28 @@ wxDb WXDLLEXPORT *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCurso } // Initialize new node in the linked list - pList->PtrNext = 0; - pList->Free = FALSE; - pList->Dsn = pDbConfig->GetDsn(); - pList->Uid = pDbConfig->GetUserID(); - pList->AuthStr = pDbConfig->GetPassword(); + pList->PtrNext = 0; + pList->Free = FALSE; + pList->Dsn = pDbConfig->GetDsn(); + pList->Uid = pDbConfig->GetUserID(); + pList->AuthStr = pDbConfig->GetPassword(); + pList->ConnectionStr = pDbConfig->GetConnectionStr(); pList->PtrDb = new wxDb(pDbConfig->GetHenv(), FwdOnlyCursors); - bool opened = FALSE; + bool opened; if (!matchingDbConnection) - opened = pList->PtrDb->Open(pDbConfig->GetDsn(), pDbConfig->GetUserID(), pDbConfig->GetPassword()); + { + if (pDbConfig->UseConnectionStr()) + { + opened = pList->PtrDb->Open(pDbConfig->GetConnectionStr()); + } + else + { + opened = pList->PtrDb->Open(pDbConfig->GetDsn(), pDbConfig->GetUserID(), pDbConfig->GetPassword()); + } + } else opened = pList->PtrDb->Open(matchingDbConnection); @@ -3622,7 +3961,7 @@ wxDb WXDLLEXPORT *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCurso if (opened) { pList->PtrDb->setCached(TRUE); // Prevent a user from deleting a cached connection - pList->PtrDb->SetSqlLogging(SQLLOGstate,SQLLOGfn,TRUE); + pList->PtrDb->SetSqlLogging(SQLLOGstate, SQLLOGfn, TRUE); return(pList->PtrDb); } else // Unable to connect, destroy list item @@ -3630,11 +3969,12 @@ wxDb WXDLLEXPORT *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCurso if (pList->PtrPrev) pList->PtrPrev->PtrNext = 0; else - PtrBegDbList = 0; // Empty list again - pList->PtrDb->CommitTrans(); // Commit any open transactions on wxDb object - pList->PtrDb->Close(); // Close the wxDb object - delete pList->PtrDb; // Deletes the wxDb object - delete pList; // Deletes the linked list object + PtrBegDbList = 0; // Empty list again + + pList->PtrDb->CommitTrans(); // Commit any open transactions on wxDb object + pList->PtrDb->Close(); // Close the wxDb object + delete pList->PtrDb; // Deletes the wxDb object + delete pList; // Deletes the linked list object return(0); } @@ -3642,7 +3982,7 @@ wxDb WXDLLEXPORT *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCurso /********** wxDbFreeConnection() **********/ -bool WXDLLEXPORT wxDbFreeConnection(wxDb *pDb) +bool WXDLLIMPEXP_ODBC wxDbFreeConnection(wxDb *pDb) { wxDbList *pList; @@ -3660,7 +4000,7 @@ bool WXDLLEXPORT wxDbFreeConnection(wxDb *pDb) /********** wxDbCloseConnections() **********/ -void WXDLLEXPORT wxDbCloseConnections(void) +void WXDLLIMPEXP_ODBC wxDbCloseConnections(void) { wxDbList *pList, *pNext; @@ -3682,7 +4022,7 @@ void WXDLLEXPORT wxDbCloseConnections(void) /********** wxDbConnectionsInUse() **********/ -int WXDLLEXPORT wxDbConnectionsInUse(void) +int WXDLLIMPEXP_ODBC wxDbConnectionsInUse(void) { wxDbList *pList; int cnt = 0; @@ -3702,8 +4042,10 @@ int WXDLLEXPORT wxDbConnectionsInUse(void) /********** wxDbLogExtendedErrorMsg() **********/ // DEBUG ONLY function -const wxChar WXDLLEXPORT *wxDbLogExtendedErrorMsg(const wxChar *userText, wxDb *pDb, - char *ErrFile, int ErrLine) +const wxChar WXDLLIMPEXP_ODBC *wxDbLogExtendedErrorMsg(const wxChar *userText, + wxDb *pDb, + const wxChar *ErrFile, + int ErrLine) { static wxString msg; msg = userText; @@ -3722,7 +4064,7 @@ const wxChar WXDLLEXPORT *wxDbLogExtendedErrorMsg(const wxChar *userText, wxDb * msg.Append (wxT("\nODBC errors:\n")); msg += wxT("\n"); - + // Display errors for this connection int i; for (i = 0; i < DB_MAX_ERROR_HISTORY; i++) @@ -3859,8 +4201,8 @@ bool wxDbGetDataSource(HENV henv, wxChar *Dsn, SWORD DsnMax, wxChar *DsDesc, { SWORD cb1,cb2; - if (SQLDataSources(henv, direction, (UCHAR FAR *) Dsn, DsnMax, &cb1, - (UCHAR FAR *) DsDesc, DsDescMax, &cb2) == SQL_SUCCESS) + if (SQLDataSources(henv, direction, (SQLTCHAR FAR *) Dsn, DsnMax, &cb1, + (SQLTCHAR FAR *) DsDesc, DsDescMax, &cb2) == SQL_SUCCESS) return(TRUE); else return(FALSE); @@ -3889,22 +4231,22 @@ bool GetDataSource(HENV henv, char *Dsn, SWORD DsnMax, char *DsDesc, SWORD DsDes return wxDbGetDataSource(henv, Dsn, DsnMax, DsDesc, DsDescMax, direction); } /***** DEPRECATED: use wxDbGetConnection() *****/ -wxDb WXDLLEXPORT *GetDbConnection(DbStuff *pDbStuff, bool FwdOnlyCursors) +wxDb WXDLLIMPEXP_ODBC *GetDbConnection(DbStuff *pDbStuff, bool FwdOnlyCursors) { return wxDbGetConnection((wxDbConnectInf *)pDbStuff, FwdOnlyCursors); } /***** DEPRECATED: use wxDbFreeConnection() *****/ -bool WXDLLEXPORT FreeDbConnection(wxDb *pDb) +bool WXDLLIMPEXP_ODBC FreeDbConnection(wxDb *pDb) { return wxDbFreeConnection(pDb); } /***** DEPRECATED: use wxDbCloseConnections() *****/ -void WXDLLEXPORT CloseDbConnections(void) +void WXDLLIMPEXP_ODBC CloseDbConnections(void) { wxDbCloseConnections(); } /***** DEPRECATED: use wxDbConnectionsInUse() *****/ -int WXDLLEXPORT NumberDbConnectionsInUse(void) +int WXDLLIMPEXP_ODBC NumberDbConnectionsInUse(void) { return wxDbConnectionsInUse(); }