X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b8126f938c79dc0a33801d8895365dc577df99c7..9fd8f2dd3df305448a0c2d56508c04e26385a76d:/src/common/db.cpp diff --git a/src/common/db.cpp b/src/common/db.cpp index 18184c49b8..a43f461158 100644 --- a/src/common/db.cpp +++ b/src/common/db.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: db.cpp +// Name: src/common/db.cpp // Purpose: Implementation of the wxDb class. The wxDb class represents a connection // to an ODBC data source. The wxDb class allows operations on the data // source such as opening and closing the data source. @@ -21,36 +21,30 @@ // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// -/* -// SYNOPSIS START -// SYNOPSIS STOP -*/ -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "db.h" -#endif - #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif -#ifdef DBDEBUG_CONSOLE - #include "wx/ioswrap.h" -#endif +#if wxUSE_ODBC #ifndef WX_PRECOMP - #include "wx/string.h" #include "wx/object.h" #include "wx/list.h" + #include "wx/string.h" #include "wx/utils.h" #include "wx/log.h" + #include "wx/app.h" #endif + +#ifdef DBDEBUG_CONSOLE + #include "wx/ioswrap.h" +#endif + #include "wx/filefn.h" #include "wx/wxchar.h" -#if wxUSE_ODBC - #include #include #include @@ -60,7 +54,6 @@ #include "wx/db.h" // DLL options compatibility check: -#include "wx/app.h" WX_CHECK_BUILD_OPTIONS("wxODBC") WXDLLIMPEXP_DATA_ODBC(wxDbList*) PtrBegDbList = 0; @@ -85,7 +78,7 @@ static wxString SQLLOGfn = SQL_LOG_FILENAME; // will overwrite the errors of the previously destroyed wxDb object in // this variable. NOTE: This occurs during a CLOSE, not a FREEing of the // connection -wxChar DBerrorList[DB_MAX_ERROR_HISTORY][DB_MAX_ERROR_MSG_LEN]; +wxChar DBerrorList[DB_MAX_ERROR_HISTORY][DB_MAX_ERROR_MSG_LEN+1]; // This type defines the return row-struct form @@ -179,7 +172,7 @@ bool wxDbConnectInf::AllocHenv() // Initialize the ODBC Environment for Database Operations if (SQLAllocEnv(&Henv) != SQL_SUCCESS) { - wxLogDebug(wxT("A problem occured while trying to get a connection to the data source")); + wxLogDebug(wxT("A problem occurred while trying to get a connection to the data source")); return false; } @@ -204,37 +197,37 @@ void wxDbConnectInf::FreeHenv() void wxDbConnectInf::SetDsn(const wxString &dsn) { - wxASSERT(dsn.Length() < sizeof(Dsn)); + wxASSERT(dsn.length() < WXSIZEOF(Dsn)); - wxStrncpy(Dsn, dsn, sizeof(Dsn)-1); - Dsn[sizeof(Dsn)-1] = 0; // Prevent buffer overrun + wxStrncpy(Dsn, dsn, WXSIZEOF(Dsn)-1); + Dsn[WXSIZEOF(Dsn)-1] = 0; // Prevent buffer overrun } // wxDbConnectInf::SetDsn() void wxDbConnectInf::SetUserID(const wxString &uid) { - wxASSERT(uid.Length() < sizeof(Uid)); - wxStrncpy(Uid, uid, sizeof(Uid)-1); - Uid[sizeof(Uid)-1] = 0; // Prevent buffer overrun + wxASSERT(uid.length() < WXSIZEOF(Uid)); + wxStrncpy(Uid, uid, WXSIZEOF(Uid)-1); + Uid[WXSIZEOF(Uid)-1] = 0; // Prevent buffer overrun } // wxDbConnectInf::SetUserID() void wxDbConnectInf::SetPassword(const wxString &password) { - wxASSERT(password.Length() < sizeof(AuthStr)); + wxASSERT(password.length() < WXSIZEOF(AuthStr)); - wxStrncpy(AuthStr, password, sizeof(AuthStr)-1); - AuthStr[sizeof(AuthStr)-1] = 0; // Prevent buffer overrun + wxStrncpy(AuthStr, password, WXSIZEOF(AuthStr)-1); + AuthStr[WXSIZEOF(AuthStr)-1] = 0; // Prevent buffer overrun } // wxDbConnectInf::SetPassword() void wxDbConnectInf::SetConnectionStr(const wxString &connectStr) { - wxASSERT(connectStr.Length() < sizeof(ConnectionStr)); + wxASSERT(connectStr.length() < WXSIZEOF(ConnectionStr)); useConnectionStr = wxStrlen(connectStr) > 0; - wxStrncpy(ConnectionStr, connectStr, sizeof(ConnectionStr)-1); - ConnectionStr[sizeof(ConnectionStr)-1] = 0; // Prevent buffer overrun + wxStrncpy(ConnectionStr, connectStr, WXSIZEOF(ConnectionStr)-1); + ConnectionStr[WXSIZEOF(ConnectionStr)-1] = 0; // Prevent buffer overrun } // wxDbConnectInf::SetConnectionStr() @@ -287,14 +280,23 @@ int wxDbColFor::Format(int Nation, int dbDataType, SWORD sqlDataType, if (i_dbDataType == 0) // Filter unsupported dbDataTypes { - if ((i_sqlDataType == SQL_VARCHAR) || (i_sqlDataType == SQL_LONGVARCHAR)) + if ((i_sqlDataType == SQL_VARCHAR) +#if wxUSE_UNICODE + #if defined(SQL_WCHAR) + || (i_sqlDataType == SQL_WCHAR) + #endif + #if defined(SQL_WVARCHAR) + || (i_sqlDataType == SQL_WVARCHAR) + #endif +#endif + || (i_sqlDataType == SQL_LONGVARCHAR)) i_dbDataType = DB_DATA_TYPE_VARCHAR; if ((i_sqlDataType == SQL_C_DATE) || (i_sqlDataType == SQL_C_TIMESTAMP)) i_dbDataType = DB_DATA_TYPE_DATE; if (i_sqlDataType == SQL_C_BIT) i_dbDataType = DB_DATA_TYPE_INTEGER; if (i_sqlDataType == SQL_NUMERIC) - i_dbDataType = DB_DATA_TYPE_VARCHAR; + i_dbDataType = DB_DATA_TYPE_VARCHAR; // glt - ??? is this right? if (i_sqlDataType == SQL_REAL) i_dbDataType = DB_DATA_TYPE_FLOAT; if (i_sqlDataType == SQL_C_BINARY) @@ -317,8 +319,7 @@ int wxDbColFor::Format(int Nation, int dbDataType, SWORD sqlDataType, case DB_DATA_TYPE_FLOAT: if (decimalDigits == 0) decimalDigits = 2; - tempStr = wxT("%"); - tempStr.Printf(wxT("%s%d.%d"), tempStr.c_str(),columnLength, decimalDigits); + tempStr.Printf(wxT("%%%d.%d"), columnLength, decimalDigits); s_Field.Printf(wxT("%sf"), tempStr.c_str()); break; case DB_DATA_TYPE_DATE: @@ -527,6 +528,12 @@ void wxDb::initialize() typeInfBlob.CaseSensitive = 0; typeInfBlob.MaximumScale = 0; + typeInfMemo.TypeName.Empty(); + typeInfMemo.FsqlType = 0; + typeInfMemo.Precision = 0; + typeInfMemo.CaseSensitive = 0; + typeInfMemo.MaximumScale = 0; + // Error reporting is turned OFF by default silent = true; @@ -567,9 +574,10 @@ const wxChar *wxDb::convertUserID(const wxChar *userID, wxString &UserID) || Dbms() == dbmsXBASE_SEQUITER ) UserID.Empty(); - // Oracle user names may only be in uppercase, so force - // the name to uppercase - if (Dbms() == dbmsORACLE) + // Some databases require user names to be specified in uppercase, + // so force the name to uppercase + if ((Dbms() == dbmsORACLE) || + (Dbms() == dbmsMAXDB)) UserID = UserID.Upper(); return UserID.c_str(); @@ -578,13 +586,13 @@ const wxChar *wxDb::convertUserID(const wxChar *userID, wxString &UserID) bool wxDb::determineDataTypes(bool failOnDataTypeUnsupported) { - int iIndex; + size_t iIndex; // These are the possible SQL types we check for use against the datasource we are connected // to for the purpose of determining which data type to use for the basic character strings // column types // - // NOTE: The first type in this enumeration that is determined to be supported by the + // NOTE: The first type in this enumeration that is determined to be supported by the // datasource/driver is the one that will be used. SWORD PossibleSqlCharTypes[] = { #if wxUSE_UNICODE && defined(SQL_WVARCHAR) @@ -601,7 +609,7 @@ bool wxDb::determineDataTypes(bool failOnDataTypeUnsupported) // to for the purpose of determining which data type to use for the basic non-floating point // column types // - // NOTE: The first type in this enumeration that is determined to be supported by the + // NOTE: The first type in this enumeration that is determined to be supported by the // datasource/driver is the one that will be used. SWORD PossibleSqlIntegerTypes[] = { SQL_INTEGER @@ -611,7 +619,7 @@ bool wxDb::determineDataTypes(bool failOnDataTypeUnsupported) // to for the purpose of determining which data type to use for the basic floating point number // column types // - // NOTE: The first type in this enumeration that is determined to be supported by the + // NOTE: The first type in this enumeration that is determined to be supported by the // datasource/driver is the one that will be used. SWORD PossibleSqlFloatTypes[] = { SQL_DOUBLE, @@ -624,7 +632,7 @@ bool wxDb::determineDataTypes(bool failOnDataTypeUnsupported) // These are the possible SQL types we check for use agains the datasource we are connected // to for the purpose of determining which data type to use for the date/time column types // - // NOTE: The first type in this enumeration that is determined to be supported by the + // NOTE: The first type in this enumeration that is determined to be supported by the // datasource/driver is the one that will be used. SWORD PossibleSqlDateTypes[] = { SQL_TIMESTAMP, @@ -637,13 +645,23 @@ bool wxDb::determineDataTypes(bool failOnDataTypeUnsupported) // These are the possible SQL types we check for use agains the datasource we are connected // to for the purpose of determining which data type to use for the BLOB column types. // - // NOTE: The first type in this enumeration that is determined to be supported by the + // NOTE: The first type in this enumeration that is determined to be supported by the // datasource/driver is the one that will be used. SWORD PossibleSqlBlobTypes[] = { SQL_LONGVARBINARY, SQL_VARBINARY }; + // These are the possible SQL types we check for use agains the datasource we are connected + // to for the purpose of determining which data type to use for the MEMO column types + // (a type which allow to store large strings; like VARCHAR just with a bigger precision) + // + // NOTE: The first type in this enumeration that is determined to be supported by the + // datasource/driver is the one that will be used. + SWORD PossibleSqlMemoTypes[] = { + SQL_LONGVARCHAR, + }; + // Query the data source regarding data type information @@ -690,8 +708,8 @@ bool wxDb::determineDataTypes(bool failOnDataTypeUnsupported) if (!getDbInfo(failOnDataTypeUnsupported)) return false; - // --------------- Varchar - (Variable length character string) --------------- - for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlCharTypes) && + // --------------- Varchar - (Variable length character string) --------------- + for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlCharTypes) && !getDataTypeInfo(PossibleSqlCharTypes[iIndex], typeInfVarchar); ++iIndex) {} @@ -700,8 +718,8 @@ bool wxDb::determineDataTypes(bool failOnDataTypeUnsupported) else if (failOnDataTypeUnsupported) return false; - // --------------- Float --------------- - for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlFloatTypes) && + // --------------- Float --------------- + for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlFloatTypes) && !getDataTypeInfo(PossibleSqlFloatTypes[iIndex], typeInfFloat); ++iIndex) {} @@ -711,7 +729,7 @@ bool wxDb::determineDataTypes(bool failOnDataTypeUnsupported) return false; // --------------- Integer ------------- - for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlIntegerTypes) && + for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlIntegerTypes) && !getDataTypeInfo(PossibleSqlIntegerTypes[iIndex], typeInfInteger); ++iIndex) {} @@ -730,8 +748,8 @@ bool wxDb::determineDataTypes(bool failOnDataTypeUnsupported) typeInfInteger.FsqlType = typeInfFloat.FsqlType; } - // --------------- Date/Time --------------- - for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlDateTypes) && + // --------------- Date/Time --------------- + for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlDateTypes) && !getDataTypeInfo(PossibleSqlDateTypes[iIndex], typeInfDate); ++iIndex) {} @@ -740,8 +758,8 @@ bool wxDb::determineDataTypes(bool failOnDataTypeUnsupported) else if (failOnDataTypeUnsupported) return false; - // --------------- BLOB --------------- - for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlBlobTypes) && + // --------------- BLOB --------------- + for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlBlobTypes) && !getDataTypeInfo(PossibleSqlBlobTypes[iIndex], typeInfBlob); ++iIndex) {} @@ -750,6 +768,16 @@ bool wxDb::determineDataTypes(bool failOnDataTypeUnsupported) else if (failOnDataTypeUnsupported) return false; + // --------------- MEMO --------------- + for (iIndex = 0; iIndex < WXSIZEOF(PossibleSqlMemoTypes) && + !getDataTypeInfo(PossibleSqlMemoTypes[iIndex], typeInfMemo); ++iIndex) + {} + + if (iIndex < WXSIZEOF(PossibleSqlMemoTypes)) + typeInfMemo.FsqlType = PossibleSqlMemoTypes[iIndex]; + else if (failOnDataTypeUnsupported) + return false; + return true; } // wxDb::determineDataTypes @@ -784,6 +812,7 @@ bool wxDb::open(bool failOnDataTypeUnsupported) cout << wxT("FLOAT DATA TYPE: ") << typeInfFloat.TypeName << endl; cout << wxT("DATE DATA TYPE: ") << typeInfDate.TypeName << endl; cout << wxT("BLOB DATA TYPE: ") << typeInfBlob.TypeName << endl; + cout << wxT("MEMO DATA TYPE: ") << typeInfMemo.TypeName << endl; cout << endl; #endif @@ -793,10 +822,15 @@ bool wxDb::open(bool failOnDataTypeUnsupported) bool wxDb::Open(const wxString& inConnectStr, bool failOnDataTypeUnsupported) { - wxASSERT(inConnectStr.Length()); - dsn = wxT(""); - uid = wxT(""); - authStr = wxT(""); + wxASSERT(inConnectStr.length()); + return Open(inConnectStr, NULL, failOnDataTypeUnsupported); +} + +bool wxDb::Open(const wxString& inConnectStr, SQLHWND parentWnd, bool failOnDataTypeUnsupported) +{ + dsn = wxEmptyString; + uid = wxEmptyString; + authStr = wxEmptyString; RETCODE retcode; @@ -822,9 +856,9 @@ bool wxDb::Open(const wxString& inConnectStr, bool failOnDataTypeUnsupported) inConnectionStr = inConnectStr; - retcode = SQLDriverConnect(hdbc, NULL, (SQLTCHAR FAR *)inConnectionStr.c_str(), - (SWORD)inConnectionStr.Length(), (SQLTCHAR FAR *)outConnectBuffer, - sizeof(outConnectBuffer), &outConnectBufferLen, SQL_DRIVER_COMPLETE ); + retcode = SQLDriverConnect(hdbc, parentWnd, (SQLTCHAR FAR *)inConnectionStr.c_str(), + (SWORD)inConnectionStr.length(), (SQLTCHAR FAR *)outConnectBuffer, + WXSIZEOF(outConnectBuffer), &outConnectBufferLen, SQL_DRIVER_COMPLETE ); if ((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO)) @@ -840,13 +874,13 @@ bool wxDb::Open(const wxString& inConnectStr, bool failOnDataTypeUnsupported) /********** wxDb::Open() **********/ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthStr, bool failOnDataTypeUnsupported) { - wxASSERT(Dsn.Length()); + wxASSERT(!Dsn.empty()); dsn = Dsn; uid = Uid; authStr = AuthStr; - inConnectionStr = wxT(""); - outConnectionStr = wxT(""); + inConnectionStr = wxEmptyString; + outConnectionStr = wxEmptyString; RETCODE retcode; @@ -886,7 +920,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); @@ -928,8 +962,8 @@ bool wxDb::Open(wxDb *copyDb) inConnectionStr = copyDb->GetConnectionInStr(); retcode = SQLDriverConnect(hdbc, NULL, (SQLTCHAR FAR *)inConnectionStr.c_str(), - (SWORD)inConnectionStr.Length(), (SQLTCHAR FAR *)outConnectBuffer, - sizeof(outConnectBuffer), &outConnectBufferLen, SQL_DRIVER_COMPLETE); + (SWORD)inConnectionStr.length(), (SQLTCHAR FAR *)outConnectBuffer, + WXSIZEOF(outConnectBuffer), &outConnectBufferLen, SQL_DRIVER_COMPLETE); if ((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO)) @@ -1039,12 +1073,20 @@ bool wxDb::Open(wxDb *copyDb) typeInfBlob.CaseSensitive = copyDb->typeInfBlob.CaseSensitive; typeInfBlob.MaximumScale = copyDb->typeInfBlob.MaximumScale; + // Memo + typeInfMemo.FsqlType = copyDb->typeInfMemo.FsqlType; + typeInfMemo.TypeName = copyDb->typeInfMemo.TypeName; + typeInfMemo.Precision = copyDb->typeInfMemo.Precision; + typeInfMemo.CaseSensitive = copyDb->typeInfMemo.CaseSensitive; + typeInfMemo.MaximumScale = copyDb->typeInfMemo.MaximumScale; + #ifdef DBDEBUG_CONSOLE cout << wxT("VARCHAR DATA TYPE: ") << typeInfVarchar.TypeName << endl; cout << wxT("INTEGER DATA TYPE: ") << typeInfInteger.TypeName << endl; cout << wxT("FLOAT DATA TYPE: ") << typeInfFloat.TypeName << endl; cout << wxT("DATE DATA TYPE: ") << typeInfDate.TypeName << endl; cout << wxT("BLOB DATA TYPE: ") << typeInfBlob.TypeName << endl; + cout << wxT("MEMO DATA TYPE: ") << typeInfMemo.TypeName << endl; cout << endl; #endif @@ -1597,7 +1639,7 @@ bool wxDb::getDataTypeInfo(SWORD fSqlType, wxDbSqlTypeInfo &structSQLTypeInfo) * wxDbSqlTypeInfo is a structure that is filled in with data type information, */ RETCODE retcode; - SDWORD cbRet; + SQLLEN cbRet; // Get information about the data type specified if (SQLGetTypeInfo(hstmt, fSqlType) != SQL_SUCCESS) @@ -1713,8 +1755,9 @@ void wxDb::Close(void) 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 table found using pDb:[%p]"),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(); @@ -1766,25 +1809,21 @@ bool wxDb::DispAllErrors(HENV aHenv, HDBC aHdbc, HSTMT aHstmt) /* * This function is called internally whenever an error condition prevents the user's * request from being executed. This function will query the datasource as to the - * actual error(s) that just occured on the previous request of the datasource. + * actual error(s) that just occurred on the previous request of the datasource. * * The function will retrieve each error condition from the datasource and * Printf the codes/text values into a string which it then logs via logError(). * If in DBDEBUG_CONSOLE mode, the constructed string will be displayed in the console * window and program execution will be paused until the user presses a key. * - * This function always returns a false, so that functions which call this function + * This function always returns false, so that functions which call this function * can have a line like "return (DispAllErrors(henv, hdbc));" to indicate the failure - * of the users request, so that the calling code can then process the error msg log + * of the user's request, so that the calling code can then process the error message log. */ { wxString odbcErrMsg; -#ifdef __VMS - while (SQLError(aHenv, aHdbc, aHstmt, (SQLTCHAR FAR *) sqlState, (SQLINTEGER *) &nativeError, (SQLTCHAR FAR *) errorMsg, SQL_MAX_MESSAGE_LENGTH - 1, &cbErrorMsg) == SQL_SUCCESS) -#else - while (SQLError(aHenv, aHdbc, aHstmt, (SQLTCHAR FAR *) sqlState, (long*) &nativeError, (SQLTCHAR FAR *) errorMsg, SQL_MAX_MESSAGE_LENGTH - 1, &cbErrorMsg) == SQL_SUCCESS) -#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); logError(odbcErrMsg, sqlState); @@ -1811,11 +1850,7 @@ bool wxDb::DispAllErrors(HENV aHenv, HDBC aHdbc, HSTMT aHstmt) /********** wxDb::GetNextError() **********/ bool wxDb::GetNextError(HENV aHenv, HDBC aHdbc, HSTMT aHstmt) { -#ifdef __VMS - if (SQLError(aHenv, aHdbc, aHstmt, (SQLTCHAR FAR *) sqlState, (SQLINTEGER *) &nativeError, (SQLTCHAR FAR *) errorMsg, SQL_MAX_MESSAGE_LENGTH - 1, &cbErrorMsg) == SQL_SUCCESS) -#else - if (SQLError(aHenv, aHdbc, aHstmt, (SQLTCHAR FAR *) sqlState, (long*) &nativeError, (SQLTCHAR FAR *) errorMsg, SQL_MAX_MESSAGE_LENGTH - 1, &cbErrorMsg) == SQL_SUCCESS) -#endif + 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; @@ -1851,7 +1886,7 @@ void wxDb::DispNextError(void) /********** wxDb::logError() **********/ void wxDb::logError(const wxString &errMsg, const wxString &SQLState) { - wxASSERT(errMsg.Length()); + wxASSERT(errMsg.length()); static int pLast = -1; int dbStatus; @@ -1859,7 +1894,7 @@ void wxDb::logError(const wxString &errMsg, const wxString &SQLState) if (++pLast == DB_MAX_ERROR_HISTORY) { int i; - for (i = 0; i < DB_MAX_ERROR_HISTORY; i++) + for (i = 0; i < DB_MAX_ERROR_HISTORY-1; i++) wxStrcpy(errorList[i], errorList[i+1]); pLast--; } @@ -1867,7 +1902,7 @@ void wxDb::logError(const wxString &errMsg, const wxString &SQLState) wxStrncpy(errorList[pLast], errMsg, DB_MAX_ERROR_MSG_LEN); errorList[pLast][DB_MAX_ERROR_MSG_LEN] = 0; - if (SQLState.Length()) + if (SQLState.length()) if ((dbStatus = TranslateSqlState(SQLState)) != DB_ERR_FUNCTION_SEQUENCE_ERROR) DB_STATUS = dbStatus; @@ -2132,7 +2167,7 @@ bool wxDb::CreateView(const wxString &viewName, const wxString &colList, sqlStmt = wxT("CREATE VIEW "); sqlStmt += viewName; - if (colList.Length()) + if (colList.length()) { sqlStmt += wxT(" ("); sqlStmt += colList; @@ -2243,7 +2278,7 @@ bool wxDb::ExecSql(const wxString &pSqlStmt, wxDbColInf** columns, short& numcol short colNum; wxChar name[DB_MAX_COLUMN_NAME_LEN+1]; SWORD Sword; - SDWORD Sdword; + SQLLEN Sqllen; wxDbColInf* pColInf = new wxDbColInf[noCols]; // Fill in column information (name, datatype) @@ -2251,7 +2286,7 @@ bool wxDb::ExecSql(const wxString &pSqlStmt, wxDbColInf** columns, short& numcol { if (SQLColAttributes(hstmt, (UWORD)(colNum+1), SQL_COLUMN_NAME, name, sizeof(name), - &Sword, &Sdword) != SQL_SUCCESS) + &Sword, &Sqllen) != SQL_SUCCESS) { DispAllErrors(henv, hdbc, hstmt); delete[] pColInf; @@ -2262,19 +2297,30 @@ bool wxDb::ExecSql(const wxString &pSqlStmt, wxDbColInf** columns, short& numcol pColInf[colNum].colName[DB_MAX_COLUMN_NAME_LEN] = 0; // Prevent buffer overrun if (SQLColAttributes(hstmt, (UWORD)(colNum+1), SQL_COLUMN_TYPE, - NULL, 0, &Sword, &Sdword) != SQL_SUCCESS) + NULL, 0, &Sword, &Sqllen) != SQL_SUCCESS) { DispAllErrors(henv, hdbc, hstmt); delete[] pColInf; return false; } - switch (Sdword) + switch (Sqllen) { +#if wxUSE_UNICODE + #if defined(SQL_WCHAR) + case SQL_WCHAR: + #endif + #if defined(SQL_WVARCHAR) + case SQL_WVARCHAR: + #endif +#endif case SQL_VARCHAR: case SQL_CHAR: pColInf[colNum].dbDataType = DB_DATA_TYPE_VARCHAR; break; + case SQL_LONGVARCHAR: + pColInf[colNum].dbDataType = DB_DATA_TYPE_MEMO; + break; case SQL_TINYINT: case SQL_SMALLINT: case SQL_INTEGER: @@ -2298,7 +2344,7 @@ bool wxDb::ExecSql(const wxString &pSqlStmt, wxDbColInf** columns, short& numcol #ifdef __WXDEBUG__ default: wxString errMsg; - errMsg.Printf(wxT("SQL Data type %ld currently not supported by wxWidgets"), (long)Sdword); + errMsg.Printf(wxT("SQL Data type %ld currently not supported by wxWidgets"), (long)Sqllen); wxLogDebug(errMsg,wxT("ODBC DEBUG MESSAGE")); #endif } @@ -2323,7 +2369,7 @@ bool wxDb::GetNext(void) /********** wxDb::GetData() **********/ -bool wxDb::GetData(UWORD colNo, SWORD cType, PTR pData, SDWORD maxLen, SDWORD FAR *cbReturned) +bool wxDb::GetData(UWORD colNo, SWORD cType, PTR pData, SDWORD maxLen, SQLLEN FAR *cbReturned) { wxASSERT(pData); wxASSERT(cbReturned); @@ -2353,7 +2399,7 @@ int wxDb::GetKeyFields(const wxString &tableName, wxDbColInf* colInf, UWORD noCo wxChar szPkCol[DB_MAX_COLUMN_NAME_LEN+1]; /* Primary key column */ wxChar szFkCol[DB_MAX_COLUMN_NAME_LEN+1]; /* Foreign key column */ SQLRETURN retcode; - SDWORD cb; + SQLLEN cb; SWORD i; wxString tempStr; /* @@ -2423,7 +2469,7 @@ int wxDb::GetKeyFields(const wxString &tableName, wxDbColInf* colInf, UWORD noCo GetData( 5, SQL_C_SSHORT, &iKeySeq, 0, &cb); GetData( 7, SQL_C_WXCHAR, szFkTable, DB_MAX_TABLE_NAME_LEN+1, &cb); GetData( 8, SQL_C_WXCHAR, szFkCol, DB_MAX_COLUMN_NAME_LEN+1, &cb); - tempStr.Printf(wxT("%s[%s] "),tempStr.c_str(),szFkTable); // [ ] in case there is a blank in the Table name + tempStr << _T('[') << szFkTable << _T(']'); // [ ] in case there is a blank in the Table name } // if } // while @@ -2492,7 +2538,7 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) * 1) The last array element of the tableName[] argument must be zero (null). * This is how the end of the array is detected. * 2) This function returns an array of wxDbColInf structures. If no columns - * were found, or an error occured, this pointer will be zero (null). THE + * were found, or an error occurred, this pointer will be zero (null). THE * CALLING FUNCTION IS RESPONSIBLE FOR DELETING THE MEMORY RETURNED WHEN IT * IS FINISHED WITH IT. i.e. * @@ -2520,7 +2566,7 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) wxDbColInf *colInf = 0; RETCODE retcode; - SDWORD cb; + SQLLEN cb; wxString TableName; @@ -2582,7 +2628,7 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) NULL, 0); // All columns } if (retcode != SQL_SUCCESS) - { // Error occured, abort + { // Error occurred, abort DispAllErrors(henv, hdbc, hstmt); if (colInf) delete [] colInf; @@ -2640,7 +2686,7 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID) } } if (retcode != SQL_NO_DATA_FOUND) - { // Error occured, abort + { // Error occurred, abort DispAllErrors(henv, hdbc, hstmt); if (colInf) delete [] colInf; @@ -2679,7 +2725,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, UWORD *numCols, const wx wxDbColInf *colInf = 0; RETCODE retcode; - SDWORD cb; + SQLLEN cb; wxString TableName; @@ -2738,7 +2784,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, UWORD *numCols, const wx NULL, 0); // All columns } if (retcode != SQL_SUCCESS) - { // Error occured, abort + { // Error occurred, abort DispAllErrors(henv, hdbc, hstmt); if (colInf) delete [] colInf; @@ -2814,7 +2860,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, UWORD *numCols, const wx } } if (retcode != SQL_NO_DATA_FOUND) - { // Error occured, abort + { // Error occurred, abort DispAllErrors(henv, hdbc, hstmt); if (colInf) delete [] colInf; @@ -2843,7 +2889,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, UWORD *numCols, const wx /* BJO 20000503 These are tentative new GetColumns members which should be more database - independant and which always returns the columns in the order they were + independent and which always returns the columns in the order they were created. - The first one (wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const @@ -2994,7 +3040,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh NULL, 0); // All columns } if (retcode != SQL_SUCCESS) - { // Error occured, abort + { // Error occurred, abort DispAllErrors(henv, hdbc, hstmt); if (colInf) delete [] colInf; @@ -3046,10 +3092,21 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh // Get the intern datatype switch (colInf[colNo].sqlDataType) { +#if wxUSE_UNICODE + #if defined(SQL_WCHAR) + case SQL_WCHAR: + #endif + #if defined(SQL_WVARCHAR) + case SQL_WVARCHAR: + #endif +#endif case SQL_VARCHAR: case SQL_CHAR: colInf[colNo].dbDataType = DB_DATA_TYPE_VARCHAR; break; + case SQL_LONGVARCHAR: + colInf[colNo].dbDataType = DB_DATA_TYPE_MEMO; + break; case SQL_TINYINT: case SQL_SMALLINT: case SQL_INTEGER: @@ -3082,7 +3139,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh } } if (retcode != SQL_NO_DATA_FOUND) - { // Error occured, abort + { // Error occurred, abort DispAllErrors(henv, hdbc, hstmt); if (colInf) delete [] colInf; @@ -3234,7 +3291,7 @@ int wxDb::GetColumnCount(const wxString &tableName, const wxChar *userID) NULL, 0); // All columns } if (retcode != SQL_SUCCESS) - { // Error occured, abort + { // Error occurred, abort DispAllErrors(henv, hdbc, hstmt); SQLFreeStmt(hstmt, SQL_CLOSE); return(-1); @@ -3245,7 +3302,7 @@ int wxDb::GetColumnCount(const wxString &tableName, const wxChar *userID) noCols++; if (retcode != SQL_NO_DATA_FOUND) - { // Error occured, abort + { // Error occurred, abort DispAllErrors(henv, hdbc, hstmt); SQLFreeStmt(hstmt, SQL_CLOSE); return(-1); @@ -3266,7 +3323,7 @@ wxDbInf *wxDb::GetCatalog(const wxChar *userID) * -- : uses SQLTables and fills pTableInf; ------ * -- : pColInf is set to NULL and numCols to 0; ------ * -- : returns pDbInf (wxDbInf) ------ - * -- - if unsuccesfull (pDbInf == NULL) ------ + * -- - if unsuccessful (pDbInf == NULL) ------ * -- : pColInf can be filled with GetColumns(..); ------ * -- : numCols can be filled with GetColumnCount(..); ------ * --------------------------------------------------------------------- @@ -3284,7 +3341,7 @@ wxDbInf *wxDb::GetCatalog(const wxChar *userID) int noTab = 0; // Counter while filling table entries int pass; RETCODE retcode; - SDWORD cb; + SQLLEN cb; wxString tblNameSave; wxString UserID; @@ -3392,10 +3449,10 @@ bool wxDb::Catalog(const wxChar *userID, const wxString &fileName) * to avoid undesired unbinding of columns. */ { - wxASSERT(fileName.Length()); + wxASSERT(fileName.length()); RETCODE retcode; - SDWORD cb; + SQLLEN cb; wxChar tblName[DB_MAX_TABLE_NAME_LEN+1]; wxString tblNameSave; wxChar colName[DB_MAX_COLUMN_NAME_LEN+1]; @@ -3403,7 +3460,7 @@ bool wxDb::Catalog(const wxChar *userID, const wxString &fileName) wxChar typeName[30+1]; SDWORD precision, length; - FILE *fp = wxFopen(fileName.fn_str(),wxT("wt")); + FILE *fp = wxFopen(fileName.c_str(),wxT("wt")); if (fp == NULL) return false; @@ -3512,14 +3569,14 @@ bool wxDb::TableExists(const wxString &tableName, const wxChar *userID, const wx * userID != "" ... UserID set equal to 'userID' */ { - wxASSERT(tableName.Length()); + wxASSERT(tableName.length()); wxString TableName; if (Dbms() == dbmsDBASE) { wxString dbName; - if (tablePath.Length()) + if (tablePath.length()) dbName.Printf(wxT("%s/%s.dbf"), tablePath.c_str(), tableName.c_str()); else dbName.Printf(wxT("%s.dbf"), tableName.c_str()); @@ -3589,10 +3646,10 @@ bool wxDb::TableExists(const wxString &tableName, const wxChar *userID, const wx bool wxDb::TablePrivileges(const wxString &tableName, const wxString &priv, const wxChar *userID, const wxChar *schema, const wxString &WXUNUSED(tablePath)) { - wxASSERT(tableName.Length()); + wxASSERT(tableName.length()); wxDbTablePrivilegeInfo result; - SDWORD cbRetVal; + SQLLEN cbRetVal; RETCODE retcode; // We probably need to be able to dynamically set this based on @@ -3738,13 +3795,13 @@ const wxString wxDb::SQLColumnName(const wxChar *colName) bool wxDb::SetSqlLogging(wxDbSqlLogState state, const wxString &filename, bool append) { wxASSERT(state == sqlLogON || state == sqlLogOFF); - wxASSERT(state == sqlLogOFF || filename.Length()); + wxASSERT(state == sqlLogOFF || filename.length()); if (state == sqlLogON) { if (fpSqlLog == 0) { - fpSqlLog = wxFopen(filename.fn_str(), (append ? wxT("at") : wxT("wt"))); + fpSqlLog = wxFopen(filename.c_str(), (append ? wxT("at") : wxT("wt"))); if (fpSqlLog == NULL) return false; } @@ -3768,7 +3825,7 @@ bool wxDb::SetSqlLogging(wxDbSqlLogState state, const wxString &filename, bool a /********** wxDb::WriteSqlLog() **********/ bool wxDb::WriteSqlLog(const wxString &logMsg) { - wxASSERT(logMsg.Length()); + wxASSERT(logMsg.length()); if (fpSqlLog == 0 || sqlLogState == sqlLogOFF) return false; @@ -3924,10 +3981,12 @@ wxDBMS wxDb::Dbms(void) return((wxDBMS)(dbmsType = dbmsXBASE_SEQUITER)); if (!wxStricmp(baseName,wxT("MySQL"))) return((wxDBMS)(dbmsType = dbmsMY_SQL)); + if (!wxStricmp(baseName,wxT("MaxDB"))) + return((wxDBMS)(dbmsType = dbmsMAXDB)); baseName[3] = 0; if (!wxStricmp(baseName,wxT("DB2"))) - return((wxDBMS)(dbmsType = dbmsDBASE)); + return((wxDBMS)(dbmsType = dbmsDB2)); return((wxDBMS)(dbmsType = dbmsUNIDENTIFIED)); @@ -3938,8 +3997,8 @@ bool wxDb::ModifyColumn(const wxString &tableName, const wxString &columnName, int dataType, ULONG columnLength, const wxString &optionalParam) { - wxASSERT(tableName.Length()); - wxASSERT(columnName.Length()); + wxASSERT(tableName.length()); + wxASSERT(columnName.length()); wxASSERT((dataType == DB_DATA_TYPE_VARCHAR && columnLength > 0) || dataType != DB_DATA_TYPE_VARCHAR); @@ -4017,7 +4076,7 @@ bool wxDb::ModifyColumn(const wxString &tableName, const wxString &columnName, } // for passing things like "NOT NULL" - if (optionalParam.Length()) + if (optionalParam.length()) { sqlStmt += wxT(" "); sqlStmt += optionalParam; @@ -4308,7 +4367,7 @@ int wxDbCreateDataSource(const wxString &driverName, const wxString &dsn, const // embedded nulls in strings setupStr.Printf(wxT("DSN=%s%cDescription=%s%cDefaultDir=%s%c"),dsn,2,description,2,defDir,2); - // Replace the separator from above with the '\0' seperator needed + // Replace the separator from above with the '\0' separator needed // by the SQLConfigDataSource() function int k; do @@ -4390,7 +4449,7 @@ bool wxDbGetDataSource(HENV henv, wxChar *Dsn, SWORD DsnMaxLength, wxChar *DsDes ******************************************************************** * * The following functions are all DEPRECATED and are included for - * backward compatability reasons only + * backward compatibility reasons only * ******************************************************************** ********************************************************************/