X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1e92909e9aaaadde61f917a2f34a241caa2b51db..236a9de39afa090fdee3cf91cb5364ceca69e3f8:/src/common/db.cpp diff --git a/src/common/db.cpp b/src/common/db.cpp index 06ca878d3c..12f614d4c5 100644 --- a/src/common/db.cpp +++ b/src/common/db.cpp @@ -5,7 +5,7 @@ // source such as opening and closing the data source. // Author: Doug Card // Modified by: George Tasker -// Mods: Dec, 1998: +// Mods: Dec, 1998: // -Added support for SQL statement logging and database cataloging // Mods: April, 1999 // -Added QUERY_ONLY mode support to reduce default number of cursors @@ -47,7 +47,7 @@ #endif #ifdef DBDEBUG_CONSOLE - #include + #include "wx/ioswrap.h" #endif #ifdef __BORLANDC__ @@ -61,6 +61,7 @@ #include "wx/list.h" #include "wx/utils.h" #include "wx/msgdlg.h" + #include "wx/log.h" #endif #include "wx/filefn.h" #include "wx/wxchar.h" @@ -93,6 +94,9 @@ DbList WXDLLEXPORT *PtrBegDbList = 0; +char const *SQL_LOG_FILENAME = "sqllog.txt"; +char const *SQL_CATALOG_FILENAME = "catalog.txt"; + #ifdef __WXDEBUG__ extern wxList TablesInUse; #endif @@ -101,14 +105,14 @@ DbList WXDLLEXPORT *PtrBegDbList = 0; enum sqlLog SQLLOGstate = sqlLogOFF; //char SQLLOGfn[DB_PATH_MAX+1] = SQL_LOG_FILENAME; -char *SQLLOGfn = SQL_LOG_FILENAME; +char *SQLLOGfn = (char*) SQL_LOG_FILENAME; // The wxDB::errorList is copied to this variable when the wxDB object // is closed. This way, the error list is still available after the -// database object is closed. This is necessary if the database +// database object is closed. This is necessary if the database // connection fails so the calling application can show the operator // why the connection failed. Note: as each wxDB object is closed, it -// will overwrite the errors of the previously destroyed wxDB object in +// will overwrite the errors of the previously destroyed wxDB object in // this variable. char DBerrorList[DB_MAX_ERROR_HISTORY][DB_MAX_ERROR_MSG_LEN]; @@ -222,7 +226,7 @@ wxDB::wxDB(HENV &aHenv, bool FwdOnlyCursors) fpSqlLog = 0; // Sql Log file pointer sqlLogState = sqlLogOFF; // By default, logging is turned off nTables = 0; - + wxStrcpy(sqlState,""); wxStrcpy(errorMsg,""); nativeError = cbErrorMsg = 0; @@ -253,10 +257,10 @@ wxDB::wxDB(HENV &aHenv, bool FwdOnlyCursors) typeInfDate.Precision = 0; typeInfDate.CaseSensitive = 0; typeInfDate.MaximumScale = 0; - + // Error reporting is turned OFF by default silent = TRUE; - + // Copy the HENV into the db class henv = aHenv; fwdOnlyCursors = FwdOnlyCursors; @@ -451,12 +455,12 @@ bool wxDB::setConnectionOptions(void) // Display the connection options to verify them #ifdef DBDEBUG_CONSOLE long l; - cout << ">>>>> CONNECTION OPTIONS <<<<<<" << endl; - + cout << "****** CONNECTION OPTIONS ******" << endl; + if (SQLGetConnectOption(hdbc, SQL_AUTOCOMMIT, &l) != SQL_SUCCESS) return(DispAllErrors(henv, hdbc)); cout << "AUTOCOMMIT: " << (l == SQL_AUTOCOMMIT_OFF ? "OFF" : "ON") << endl; - + if (SQLGetConnectOption(hdbc, SQL_ODBC_CURSORS, &l) != SQL_SUCCESS) return(DispAllErrors(henv, hdbc)); cout << "ODBC CURSORS: "; @@ -473,7 +477,7 @@ bool wxDB::setConnectionOptions(void) break; } cout << endl; - + if (SQLGetConnectOption(hdbc, SQL_OPT_TRACE, &l) != SQL_SUCCESS) return(DispAllErrors(henv, hdbc)); cout << "TRACING: " << (l == SQL_OPT_TRACE_OFF ? "OFF" : "ON") << endl; @@ -590,7 +594,7 @@ bool wxDB::getDbInfo(void) return(DispAllErrors(henv, hdbc)); #ifdef DBDEBUG_CONSOLE - cout << ">>>>> DATA SOURCE INFORMATION <<<<<" << endl; + cout << "***** DATA SOURCE INFORMATION *****" << endl; cout << "SERVER Name: " << dbInf.serverName << endl; cout << "DBMS Name: " << dbInf.dbmsName << "; DBMS Version: " << dbInf.dbmsVer << endl; cout << "ODBC Version: " << dbInf.odbcVer << "; Driver Version: " << dbInf.driverVer << endl; @@ -894,7 +898,7 @@ void wxDB::Close(void) { s.sprintf("(%-20s) tableID:[%6lu] pDb:[%p]", tiu->tableName,tiu->tableID,tiu->pDb); s2.sprintf("Orphaned found using pDb:[%p]",this); - wxMessageBox (s,s2); + wxLogDebug (s.c_str(),s2.c_str()); } pNode = pNode->Next(); } @@ -958,7 +962,7 @@ bool wxDB::DispAllErrors(HENV aHenv, HDBC aHdbc, HSTMT aHstmt) } #ifdef __WXDEBUG__ - wxMessageBox(odbcErrMsg.GetData(),"DEBUG MESSAGE from DispAllErrors()"); + wxLogDebug(odbcErrMsg.GetData(),"DEBUG MESSAGE from DispAllErrors()"); #endif } @@ -1215,7 +1219,7 @@ int wxDB::TranslateSqlState(const char *SQLState) } // wxDB::TranslateSqlState() - + /********** wxDB::Grant() **********/ bool wxDB::Grant(int privileges, const char *tableName, const char *userList) { @@ -1283,7 +1287,7 @@ bool wxDB::CreateView(const char *viewName, const char *colList, const char *pSq // Build the create view statement sqlStmt = "CREATE VIEW "; sqlStmt += viewName; - + if (wxStrlen(colList)) { sqlStmt += " ("; @@ -1557,7 +1561,7 @@ wxColInf *wxDB::GetColumns(char *tableName[], const char *userID) * userID != "" ... UserID set equal to 'userID' * * NOTE: ALL column bindings associated with this wxDB instance are unbound - * by this function. This function should use its own wxDB instance + * by this function. This function should use its own wxDB instance * to avoid undesired unbinding of columns. */ { @@ -1585,7 +1589,7 @@ wxColInf *wxDB::GetColumns(char *tableName[], const char *userID) if (Dbms() == dbmsDBASE) UserID = ""; - // Oracle user names may only be in uppercase, so force + // Oracle user names may only be in uppercase, so force // the name to uppercase if (Dbms() == dbmsORACLE) UserID = UserID.Upper(); @@ -1614,7 +1618,7 @@ wxColInf *wxDB::GetColumns(char *tableName[], const char *userID) for (tbl = 0; tableName[tbl]; tbl++) { TableName = tableName[tbl]; - // Oracle table names are uppercase only, so force + // Oracle table names are uppercase only, so force // the name to uppercase just in case programmer forgot to do this if (Dbms() == dbmsORACLE) TableName = TableName.Upper(); @@ -1670,12 +1674,20 @@ wxColInf *wxDB::GetColumns(char *tableName[], const char *userID) GetData( 9, SQL_C_SSHORT, (UCHAR*) &colInf[colNo].decimalDigits,0, &cb); GetData(10, SQL_C_SSHORT, (UCHAR*) &colInf[colNo].numPrecRadix, 0, &cb); GetData(11, SQL_C_SSHORT, (UCHAR*) &colInf[colNo].nullable, 0, &cb); - GetData(12, SQL_C_CHAR, (UCHAR*) colInf[colNo].remarks, 254+1, &cb); + GetData(12, SQL_C_CHAR, (UCHAR*) colInf[colNo].remarks, 254+1, &cb); // Determine the wxDB data type that is used to represent the native data type of this data source colInf[colNo].dbDataType = 0; if (!wxStricmp(typeInfVarchar.TypeName,colInf[colNo].typeName)) + { + if (colInf[colNo].columnSize < 1) + { + // IODBC does not return a correct columnSize, so we set + // columnSize = bufferLength if no column size was returned + colInf[colNo].columnSize = colInf[colNo].bufferLength; + } colInf[colNo].dbDataType = DB_DATA_TYPE_VARCHAR; + } else if (!wxStricmp(typeInfInteger.TypeName,colInf[colNo].typeName)) colInf[colNo].dbDataType = DB_DATA_TYPE_INTEGER; else if (!wxStricmp(typeInfFloat.TypeName,colInf[colNo].typeName)) @@ -1717,7 +1729,7 @@ wxColInf *wxDB::GetColumns(char *tableName, int *numCols, const char *userID) * userID != "" ... UserID set equal to 'userID' * * NOTE: ALL column bindings associated with this wxDB instance are unbound - * by this function. This function should use its own wxDB instance + * by this function. This function should use its own wxDB instance * to avoid undesired unbinding of columns. */ { @@ -1745,7 +1757,7 @@ wxColInf *wxDB::GetColumns(char *tableName, int *numCols, const char *userID) if (Dbms() == dbmsDBASE) UserID = ""; - // Oracle user names may only be in uppercase, so force + // Oracle user names may only be in uppercase, so force // the name to uppercase if (Dbms() == dbmsORACLE) UserID = UserID.Upper(); @@ -1771,7 +1783,7 @@ wxColInf *wxDB::GetColumns(char *tableName, int *numCols, const char *userID) } TableName = tableName; - // Oracle table names are uppercase only, so force + // Oracle table names are uppercase only, so force // the name to uppercase just in case programmer forgot to do this if (Dbms() == dbmsORACLE) TableName = TableName.Upper(); @@ -1826,7 +1838,7 @@ wxColInf *wxDB::GetColumns(char *tableName, int *numCols, const char *userID) GetData( 6, SQL_C_CHAR, (UCHAR*) colInf[colNo].typeName, 128+1, &cb); GetData( 7, SQL_C_SLONG, (UCHAR*) &colInf[colNo].columnSize, 0, &cb); // BJO 991214 : SQL_C_SSHORT instead of SQL_C_SLONG, otherwise fails on Sparc (probably all 64 bit architectures) - GetData( 8, SQL_C_SSHORT, (UCHAR*) &colInf[colNo].bufferLength, 0, &cb); + GetData( 8, SQL_C_SSHORT, (UCHAR*) &colInf[colNo].bufferLength, 0, &cb); GetData( 9, SQL_C_SSHORT, (UCHAR*) &colInf[colNo].decimalDigits,0, &cb); GetData(10, SQL_C_SSHORT, (UCHAR*) &colInf[colNo].numPrecRadix, 0, &cb); GetData(11, SQL_C_SSHORT, (UCHAR*) &colInf[colNo].nullable, 0, &cb); @@ -1840,7 +1852,15 @@ wxColInf *wxDB::GetColumns(char *tableName, int *numCols, const char *userID) // Determine the wxDB data type that is used to represent the native data type of this data source colInf[colNo].dbDataType = 0; if (!wxStricmp(typeInfVarchar.TypeName,colInf[colNo].typeName)) + { + if (colInf[colNo].columnSize < 1) + { + // IODBC does not return a correct columnSize, so we set + // columnSize = bufferLength if no column size was returned + colInf[colNo].columnSize = colInf[colNo].bufferLength; + } colInf[colNo].dbDataType = DB_DATA_TYPE_VARCHAR; + } else if (!wxStricmp(typeInfInteger.TypeName,colInf[colNo].typeName)) colInf[colNo].dbDataType = DB_DATA_TYPE_INTEGER; else if (!wxStricmp(typeInfFloat.TypeName,colInf[colNo].typeName)) @@ -1889,7 +1909,7 @@ int wxDB::GetColumnCount(char *tableName, const char *userID) * userID != "" ... UserID set equal to 'userID' * * NOTE: ALL column bindings associated with this wxDB instance are unbound - * by this function. This function should use its own wxDB instance + * by this function. This function should use its own wxDB instance * to avoid undesired unbinding of columns. */ { @@ -1914,7 +1934,7 @@ int wxDB::GetColumnCount(char *tableName, const char *userID) if (Dbms() == dbmsDBASE) UserID = ""; - // Oracle user names may only be in uppercase, so force + // Oracle user names may only be in uppercase, so force // the name to uppercase if (Dbms() == dbmsORACLE) UserID = UserID.Upper(); @@ -1923,7 +1943,7 @@ int wxDB::GetColumnCount(char *tableName, const char *userID) // Loop through each table name { TableName = tableName; - // Oracle table names are uppercase only, so force + // Oracle table names are uppercase only, so force // the name to uppercase just in case programmer forgot to do this if (Dbms() == dbmsORACLE) TableName = TableName.Upper(); @@ -1996,7 +2016,7 @@ wxDbInf *wxDB::GetCatalog(char *userID) * userID != "" ... UserID set equal to 'userID' * * NOTE: ALL column bindings associated with this wxDB instance are unbound - * by this function. This function should use its own wxDB instance + * by this function. This function should use its own wxDB instance * to avoid undesired unbinding of columns. */ { @@ -2024,7 +2044,7 @@ wxDbInf *wxDB::GetCatalog(char *userID) if (Dbms() == dbmsDBASE) UserID = ""; - // Oracle user names may only be in uppercase, so force + // Oracle user names may only be in uppercase, so force // the name to uppercase if (Dbms() == dbmsORACLE) UserID = UserID.Upper(); @@ -2129,7 +2149,7 @@ bool wxDB::Catalog(const char *userID, const char *fileName) * userID != "" ... UserID set equal to 'userID' * * NOTE: ALL column bindings associated with this wxDB instance are unbound - * by this function. This function should use its own wxDB instance + * by this function. This function should use its own wxDB instance * to avoid undesired unbinding of columns. */ { @@ -2166,7 +2186,7 @@ bool wxDB::Catalog(const char *userID, const char *fileName) if (Dbms() == dbmsDBASE) UserID = ""; - // Oracle user names may only be in uppercase, so force + // Oracle user names may only be in uppercase, so force // the name to uppercase if (Dbms() == dbmsORACLE) UserID = UserID.Upper(); @@ -2292,13 +2312,13 @@ bool wxDB::TableExists(const char *tableName, const char *userID, const char *ta else UserID = ""; - // Oracle user names may only be in uppercase, so force + // Oracle user names may only be in uppercase, so force // the name to uppercase if (Dbms() == dbmsORACLE) UserID = UserID.Upper(); TableName = tableName; - // Oracle table names are uppercase only, so force + // Oracle table names are uppercase only, so force // the name to uppercase just in case programmer forgot to do this if (Dbms() == dbmsORACLE) TableName = TableName.Upper(); @@ -2431,7 +2451,7 @@ DBMS wxDB::Dbms(void) * - Cannot support selecting for update [::CanSelectForUpdate()]. Always returns FALSE * * POSTGRES - * - Does not support the keywords 'ASC' or 'DESC' as of release v6.5.0 + * - Does not support the keywords 'ASC' or 'DESC' as of release v6.5.0 * * */ @@ -2441,7 +2461,7 @@ DBMS wxDB::Dbms(void) wxStrncpy(baseName,dbInf.dbmsName,25); if (!wxStricmp(dbInf.dbmsName,"Adaptive Server Anywhere")) return(dbmsSYBASE_ASA); - if (!wxStricmp(dbInf.dbmsName,"SQL Server")) // Sybase Adaptive Server + if (!wxStricmp(dbInf.dbmsName,"SQL Server")) // Sybase Adaptive Server return(dbmsSYBASE_ASE); if (!wxStricmp(dbInf.dbmsName,"Microsoft SQL Server")) return(dbmsMS_SQL_SERVER); @@ -2556,7 +2576,7 @@ bool WXDLLEXPORT FreeDbConnection(wxDB *pDb) void WXDLLEXPORT CloseDbConnections(void) { DbList *pList, *pNext; - + // Traverse the linked list closing database connections and freeing memory as I go. for (pList = PtrBegDbList; pList; pList = pNext) { @@ -2632,4 +2652,3 @@ bool GetDataSource(HENV henv, char *Dsn, SWORD DsnMax, char *DsDesc, SWORD DsDes #endif // wxUSE_ODBC -