From: George Tasker Date: Thu, 1 Feb 2001 20:21:52 +0000 (+0000) Subject: All char, char *, and char arrays changed to use wxChar or wxString. 99% backward... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/4fdae9972d39fbe62adaa1c1d721ba1762cd8950 All char, char *, and char arrays changed to use wxChar or wxString. 99% backward compatability maintained Cleaned up code to remove duplicate blocks from multiple functions Added better handling of failed creation of wxDbTable/wxDb objects Moved code out of class constructors to a private function called from within the constructor Moved destructor code to a cleanup() function so it could be called from within the constructor if the constructor failed. Added wxDb::ModifyColumn() function. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@9255 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/db.h b/include/wx/db.h index 5848ef0b63..6df0e249f4 100644 --- a/include/wx/db.h +++ b/include/wx/db.h @@ -118,8 +118,8 @@ enum enumDummy {enumDum1}; const int wxDB_PATH_MAX = 254; -extern char const *SQL_LOG_FILENAME; -extern char const *SQL_CATALOG_FILENAME; +extern wxChar const *SQL_LOG_FILENAME; +extern wxChar const *SQL_CATALOG_FILENAME; // Database Globals @@ -258,25 +258,25 @@ enum wxODBC_ERRORS struct wxDbConnectInf { HENV Henv; - char Dsn[SQL_MAX_DSN_LENGTH+1]; // Data Source Name - char Uid[20+1]; // User ID - char AuthStr[20+1]; // Authorization string (password) + wxString Dsn; // Data Source Name + wxString Uid; // User ID + wxString AuthStr; // Authorization string (password) - char description[SQL_MAX_DSN_LENGTH+1]; // Not sure what the max length is - char fileType[SQL_MAX_DSN_LENGTH+1]; // Not sure what the max length is + wxString description; // Not sure what the max length is + wxString fileType; // Not sure what the max length is // Optionals needed for some databases like dBase - char defaultDir[wxDB_PATH_MAX]; // Directory that db file resides in + wxString defaultDir; // Directory that db file resides in }; struct wxDbSqlTypeInfo { - char TypeName[DB_TYPE_NAME_LEN]; - int FsqlType; - long Precision; - short CaseSensitive; -// short MinimumScale; - short MaximumScale; + wxString TypeName; + int FsqlType; + long Precision; + short CaseSensitive; +// short MinimumScale; + short MaximumScale; }; @@ -301,24 +301,24 @@ public: class WXDLLEXPORT wxDbColInf { public: - char catalog[128+1]; - char schema[128+1]; - char tableName[DB_MAX_TABLE_NAME_LEN+1]; - char colName[DB_MAX_COLUMN_NAME_LEN+1]; + wxChar catalog[128+1]; + wxChar schema[128+1]; + wxChar tableName[DB_MAX_TABLE_NAME_LEN+1]; + wxChar colName[DB_MAX_COLUMN_NAME_LEN+1]; SWORD sqlDataType; - char typeName[128+1]; + wxChar typeName[128+1]; SWORD columnSize; SWORD bufferLength; short decimalDigits; short numPrecRadix; short nullable; - char remarks[254+1]; + wxChar remarks[254+1]; int dbDataType; // conversion of the 'sqlDataType' to the generic data type used by these classes // mj10777.19991224 : new int PkCol; // Primary key column 0=No; 1= First Key, 2 = Second Key etc. - char PkTableName[DB_MAX_TABLE_NAME_LEN+1]; // Tables that use this PKey as a FKey + wxChar PkTableName[DB_MAX_TABLE_NAME_LEN+1]; // Tables that use this PKey as a FKey int FkCol; // Foreign key column 0=No; 1= First Key, 2 = Second Key etc. - char FkTableName[DB_MAX_TABLE_NAME_LEN+1]; // Foreign key table name + wxChar FkTableName[DB_MAX_TABLE_NAME_LEN+1]; // Foreign key table name wxDbColFor *pColFor; // How should this columns be formatted wxDbColInf(); @@ -331,9 +331,9 @@ public: class WXDLLEXPORT wxDbTableInf // Description of a Table { public: - char tableName[DB_MAX_TABLE_NAME_LEN+1]; - char tableType[254+1]; // "TABLE" or "SYSTEM TABLE" etc. - char tableRemarks[254+1]; + wxChar tableName[DB_MAX_TABLE_NAME_LEN+1]; + wxChar tableType[254+1]; // "TABLE" or "SYSTEM TABLE" etc. + wxChar tableRemarks[254+1]; int numCols; // How many Columns does this Table have: GetColumnCount(..); wxDbColInf *pColInf; // pColInf = NULL ; User can later call GetColumns(..); wxDbTableInf(); @@ -344,8 +344,8 @@ public: class WXDLLEXPORT wxDbInf // Description of a Database { public: - char catalog[128+1]; - char schema[128+1]; + wxChar catalog[128+1]; + wxChar schema[128+1]; int numTables; // How many tables does this database have wxDbTableInf *pTableInf; // pTableInf = new wxDbTableInf[numTables]; @@ -388,16 +388,16 @@ enum wxDBMS // why the connection failed. Note: as each wxDb object is closed, it // will overwrite the errors of the previously destroyed wxDb object in // this variable. -extern char DBerrorList[DB_MAX_ERROR_HISTORY][DB_MAX_ERROR_MSG_LEN]; +extern wxChar DBerrorList[DB_MAX_ERROR_HISTORY][DB_MAX_ERROR_MSG_LEN]; class WXDLLEXPORT wxDb { private: bool dbIsOpen; - char *dsn; // Data source name - char *uid; // User ID - char *authStr; // Authorization string (password) + wxString dsn; // Data source name + wxString uid; // User ID + wxString authStr; // Authorization string (password) FILE *fpSqlLog; // Sql Log file pointer wxDbSqlLogState sqlLogState; // On or Off bool fwdOnlyCursors; @@ -407,8 +407,10 @@ private: bool getDbInfo(void); bool getDataTypeInfo(SWORD fSqlType, wxDbSqlTypeInfo &structSQLTypeInfo); bool setConnectionOptions(void); - void logError(const char *errMsg, const char *SQLState); + void logError(const wxString &errMsg, const wxString &SQLState); void initialize(); + const wxChar *convertUserID(const wxChar *userID, wxString &UserID); + #if !wxODBC_BACKWARD_COMPATABILITY // ODBC handles HENV henv; // ODBC Environment handle @@ -451,17 +453,17 @@ public: // datasource when the datasource is first opened. struct { - char dbmsName[40]; // Name of the dbms product - char dbmsVer[64]; // Version # of the dbms product - char driverName[40]; // Driver name - char odbcVer[60]; // ODBC version of the driver - char drvMgrOdbcVer[60]; // ODBC version of the driver manager - char driverVer[60]; // Driver version - char serverName[80]; // Server Name, typically a connect string - char databaseName[128]; // Database filename - char outerJoins[2]; // Indicates whether the data source supports outer joins - char procedureSupport[2]; // Indicates whether the data source supports stored procedures - char accessibleTables[2]; // Indicates whether the data source only reports accessible tables in SQLTables. + wxChar dbmsName[40]; // Name of the dbms product + wxChar dbmsVer[64]; // Version # of the dbms product + wxChar driverName[40]; // Driver name + wxChar odbcVer[60]; // ODBC version of the driver + wxChar drvMgrOdbcVer[60]; // ODBC version of the driver manager + wxChar driverVer[60]; // Driver version + wxChar serverName[80]; // Server Name, typically a connect string + wxChar databaseName[128]; // Database filename + wxChar outerJoins[2]; // Indicates whether the data source supports outer joins + wxChar procedureSupport[2]; // Indicates whether the data source supports stored procedures + wxChar accessibleTables[2]; // Indicates whether the data source only reports accessible tables in SQLTables. UWORD maxConnections; // Maximum # of connections the data source supports UWORD maxStmts; // Maximum # of HSTMTs per HDBC UWORD apiConfLvl; // ODBC API conformance level @@ -470,7 +472,7 @@ public: UWORD cursorCommitBehavior; // Indicates how cursors are affected by a db commit UWORD cursorRollbackBehavior; // Indicates how cursors are affected by a db rollback UWORD supportNotNullClause; // Indicates if data source supports NOT NULL clause - char supportIEF[2]; // Integrity Enhancement Facility (Referential Integrity) + wxChar supportIEF[2]; // Integrity Enhancement Facility (Referential Integrity) UDWORD txnIsolation; // Default transaction isolation level supported by the driver UDWORD txnIsolationOptions; // Transaction isolation level options available UDWORD fetchDirections; // Fetch directions supported @@ -507,7 +509,7 @@ public: // Public member functions wxDb(HENV &aHenv, bool FwdOnlyCursors=(bool)wxODBC_FWD_ONLY_CURSORS); - bool Open(char *Dsn, char *Uid, char *AuthStr); // Data Source Name, User ID, Password + bool Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthStr); // Data Source Name, User ID, Password bool Open(wxDb *copyDb); // pointer to a wxDb whose connection info should be copied rather than re-queried void Close(void); bool CommitTrans(void); @@ -515,26 +517,26 @@ public: bool DispAllErrors(HENV aHenv, HDBC aHdbc = SQL_NULL_HDBC, HSTMT aHstmt = SQL_NULL_HSTMT); bool GetNextError(HENV aHenv, HDBC aHdbc = SQL_NULL_HDBC, HSTMT aHstmt = SQL_NULL_HSTMT); void DispNextError(void); - bool CreateView(const char *viewName, const char *colList, const char *pSqlStmt, bool attemptDrop=TRUE); - bool DropView(const char *viewName); - bool ExecSql(const char *pSqlStmt); + bool CreateView(const wxString &viewName, const wxString &colList, const wxString &pSqlStmt, bool attemptDrop=TRUE); + bool DropView(const wxString &viewName); + bool ExecSql(const wxString &pSqlStmt); bool GetNext(void); bool GetData(UWORD colNo, SWORD cType, PTR pData, SDWORD maxLen, SDWORD FAR *cbReturned); - bool Grant(int privileges, const char *tableName, const char *userList = "PUBLIC"); - int TranslateSqlState(const wxChar *SQLState); - wxDbInf *GetCatalog(char *userID); - bool Catalog(const char *userID=NULL, const char *fileName = SQL_CATALOG_FILENAME); - int GetKeyFields(char *tableName, wxDbColInf* colInf, int nocols); - - wxDbColInf *GetColumns(char *tableName[], const char *userID=NULL); - wxDbColInf *GetColumns(char *tableName, int *numCols, const char *userID=NULL); - - int GetColumnCount(char *tableName, const char *userID=NULL); - const char *GetDatabaseName(void) {return dbInf.dbmsName;} - const char *GetDataSource(void) {return (const char *)dsn;} - const char *GetDatasourceName(void){return (const char *)dsn;} - const char *GetUsername(void) {return (const char *)uid;} - const char *GetPassword(void) {return (const char *)authStr;} + bool Grant(int privileges, const wxString &tableName, const wxString &userList = wxT("PUBLIC")); + int TranslateSqlState(const wxString &SQLState); + wxDbInf *GetCatalog(const wxChar *userID=NULL); + bool Catalog(const wxChar *userID=NULL, const wxString &fileName=SQL_CATALOG_FILENAME); + int GetKeyFields(const wxString &tableName, wxDbColInf* colInf, int nocols); + + wxDbColInf *GetColumns(wxChar *tableName[], const wxChar *userID=NULL); + wxDbColInf *GetColumns(const wxString &tableName, int *numCols, const wxChar *userID=NULL); + + int GetColumnCount(const wxString &tableName, const wxChar *userID=NULL); + const wxChar *GetDatabaseName(void) {return dbInf.dbmsName;} + const wxString &GetDataSource(void) {return dsn;} + const wxString &GetDatasourceName(void){return dsn;} + const wxString &GetUsername(void) {return uid;} + const wxString &GetPassword(void) {return authStr;} bool IsOpen(void) {return dbIsOpen;} HENV GetHENV(void) {return henv;} HDBC GetHDBC(void) {return hdbc;} @@ -545,13 +547,17 @@ public: wxDbSqlTypeInfo GetTypeInfFloat() {return typeInfFloat;} wxDbSqlTypeInfo GetTypeInfDate() {return typeInfDate;} - bool TableExists(const char *tableName, const char *userID=NULL, const char *path=NULL); // Table name can refer to a table, view, alias or synonym - bool TablePrivileges(const char *tableName, const char* priv, const char *userID="", const char *schema=NULL, const char *path=""); // Table name can refer to a table, view, alias or synonym - void LogError(const char *errMsg, const char *SQLState = NULL) {logError(errMsg, SQLState);} + bool TableExists(const wxString &tableName, const wxChar *userID=NULL, const wxString &tablePath=wxT("")); // tableName can refer to a table, view, alias or synonym + bool TablePrivileges(const wxString &tableName, const wxString &priv, const wxChar *userID=NULL, const wxChar *schema=NULL, const wxString &path=wxT("")); // tableName can refer to a table, view, alias or synonym + void LogError(const wxString &errMsg, const wxString &SQLState = wxT("")) { logError(errMsg, SQLState); } void SetDebugErrorMessages(bool state) { silent = !state; } - bool SetSqlLogging(wxDbSqlLogState state, const wxChar *filename = SQL_LOG_FILENAME, bool append = FALSE); - bool WriteSqlLog(const wxChar *logMsg); + bool SetSqlLogging(wxDbSqlLogState state, const wxString &filename = SQL_LOG_FILENAME, bool append = FALSE); + bool WriteSqlLog(const wxString &logMsg); wxDBMS Dbms(void); + bool ModifyColumn(const wxString &tableName, const wxString &columnName, + int dataType, ULONG columnLength=0, + const wxString &optionalParam=""); + bool FwdOnlyCursors(void) {return fwdOnlyCursors;} // These two functions are provided strictly for use by wxDbTable. @@ -568,13 +574,13 @@ public: // or for multiple database support. struct wxDbList { - wxDbList *PtrPrev; // Pointer to previous item in the list - wxChar Dsn[SQL_MAX_DSN_LENGTH+1]; // Data Source Name - wxChar Uid[20+1]; // User ID - wxChar AuthStr[20+1]; // Authorization string (password) - wxDb *PtrDb; // Pointer to the wxDb object - bool Free; // Is item free or in use? - wxDbList *PtrNext; // Pointer to next item in the list + wxDbList *PtrPrev; // Pointer to previous item in the list + wxString Dsn; // Data Source Name + wxString Uid; // User ID + wxString AuthStr; // Authorization string (password) + wxDb *PtrDb; // Pointer to the wxDb object + bool Free; // Is item free or in use? + wxDbList *PtrNext; // Pointer to next item in the list }; #ifdef __WXDEBUG__ @@ -582,7 +588,7 @@ struct wxDbList class wxTablesInUse : public wxObject { public: - const char *tableName; + const wxChar *tableName; ULONG tableID; class wxDb *pDb; }; // wxTablesInUse @@ -604,16 +610,16 @@ bool wxDbSqlLog(wxDbSqlLogState state, const wxChar *filename = SQL_LOG_FILENAME #if 0 // MSW/VC6 ONLY!!! Experimental -int WXDLLEXPORT wxDbCreateDataSource(const char *driverName, const char *dsn, const char *description="", - bool sysDSN=FALSE, const char *defDir="", wxWindow *parent=NULL); +int WXDLLEXPORT wxDbCreateDataSource(const wxString &driverName, const wxString &dsn, const wxString &description=wxT(""), + bool sysDSN=FALSE, const wxString &defDir=wxT(""), wxWindow *parent=NULL); #endif // This routine allows you to query a driver manager // for a list of available datasources. Call this routine // the first time using SQL_FETCH_FIRST. Continue to call it // using SQL_FETCH_NEXT until you've exhausted the list. -bool WXDLLEXPORT wxDbGetDataSource(HENV henv, char *Dsn, SWORD DsnMax, char *DsDesc, SWORD DsDescMax, - UWORD direction = SQL_FETCH_NEXT); +bool WXDLLEXPORT wxDbGetDataSource(HENV henv, wxChar *Dsn, SWORD DsnMax, wxChar *DsDesc, + SWORD DsDescMax, UWORD direction = SQL_FETCH_NEXT); // Change this to 0 to remove use of all deprecated functions @@ -649,7 +655,7 @@ bool WXDLLEXPORT FreeDbConnection(wxDB *pDb); void WXDLLEXPORT CloseDbConnections(void); int WXDLLEXPORT NumberDbConnectionsInUse(void); -bool SqlLog(sqlLog state, const wxChar *filename = SQL_LOG_FILENAME); +bool SqlLog(sqlLog state, const char *filename = SQL_LOG_FILENAME); bool WXDLLEXPORT GetDataSource(HENV henv, char *Dsn, SWORD DsnMax, char *DsDesc, SWORD DsDescMax, UWORD direction = SQL_FETCH_NEXT); diff --git a/include/wx/dbtable.h b/include/wx/dbtable.h index 21f633e92d..56f3106236 100644 --- a/include/wx/dbtable.h +++ b/include/wx/dbtable.h @@ -9,7 +9,7 @@ // RCS-ID: $Id$ // Copyright: (c) 1996 Remstar International, Inc. // Licence: wxWindows licence, plus: -// Notice: This class library and its intellectual design are free of charge for use, +// 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 @@ -65,7 +65,7 @@ const int wxDB_NO_MORE_COLUMN_NUMBERS = -1; class WXDLLEXPORT wxDbColDef { public: - char ColName[DB_MAX_COLUMN_NAME_LEN+1]; // Column Name + wxChar ColName[DB_MAX_COLUMN_NAME_LEN+1]; // Column Name int DbDataType; // Logical Data Type; e.g. DB_DATA_TYPE_INTEGER int SqlCtype; // C data type; e.g. SQL_C_LONG void *PtrDataObj; // Address of the data object @@ -92,8 +92,8 @@ public: class WXDLLEXPORT wxDbIdxDef { public: - char ColName[DB_MAX_COLUMN_NAME_LEN+1]; - bool Ascending; + wxChar ColName[DB_MAX_COLUMN_NAME_LEN+1]; + bool Ascending; }; // wxDbIdxDef @@ -107,13 +107,19 @@ private: bool insertable; // Private member functions + bool initialize(wxDb *pwxDb, const wxString &tblName, const int nCols, + const wxString &qryTblName, bool qryOnly, const wxString &tblPath); + void cleanup(); + + bool bindParams(bool forUpdate); // called by the other 'bind' functions bool bindInsertParams(void); bool bindUpdateParams(void); + bool bindCols(HSTMT cursor); bool getRec(UWORD fetchType); - bool execDelete(const char *pSqlStmt); - bool execUpdate(const char *pSqlStmt); - bool query(int queryType, bool forUpdate, bool distinct, const char *pSqlStmt = NULL); + bool execDelete(const wxString &pSqlStmt); + bool execUpdate(const wxString &pSqlStmt); + bool query(int queryType, bool forUpdate, bool distinct, const wxString &pSqlStmt=wxT("")); #if !wxODBC_BACKWARD_COMPATABILITY // these were public @@ -140,9 +146,9 @@ private: wxDb *pDb; // Table Inf. - char tablePath[wxDB_PATH_MAX]; // needed for dBase tables - char tableName[DB_MAX_TABLE_NAME_LEN+1]; // Table name - char queryTableName[DB_MAX_TABLE_NAME_LEN+1]; // Query Table Name + wxString tablePath; // needed for dBase tables + wxString tableName; // Table name + wxString queryTableName; // Query Table Name int noCols; // # of columns in the table bool queryOnly; // Query Only, no inserts, updates or deletes @@ -184,15 +190,20 @@ public: wxDbColDef *colDefs; // Array of wxDbColDef structures #endif // Public member functions - wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, - const char *qryTblName = NULL, bool qryOnly = !wxDB_QUERY_ONLY, const char *tblPath=""); + wxDbTable(wxDb *pwxDb, const wxString &tblName, const int nCols, + const wxString &qryTblName = "", bool qryOnly = !wxDB_QUERY_ONLY, const wxString &tblPath=""); + + // DEPRECATED + wxDbTable(wxDb *pwxDb, const wxString &tblName, const int nCols, + const wxChar *qryTblName = "", bool qryOnly = !wxDB_QUERY_ONLY, const wxString &tblPath=""); + virtual ~wxDbTable(); bool Open(bool checkPrivileges=FALSE); bool CreateTable(bool attemptDrop=TRUE); bool DropTable(void); - bool CreateIndex(const char * idxName, bool unique, int noIdxCols, wxDbIdxDef *pIdxDefs, bool attemptDrop=TRUE); - bool DropIndex(const char * idxName); + bool CreateIndex(const wxString &idxName, bool unique, int noIdxCols, wxDbIdxDef *pIdxDefs, bool attemptDrop=TRUE); + bool DropIndex(const wxString &idxName); // Accessors @@ -200,16 +211,16 @@ public: // set when the wxDbTable instance is createand cannot be // changed, hence there is no corresponding SetXxxx function wxDb *GetDb() { return pDb; } - const char *GetTableName() { return tableName; } - const char *GetQueryTableName() { return queryTableName; } - const char *GetTablePath() { return tablePath; } + const wxString &GetTableName() { return tableName; } + const wxString &GetQueryTableName() { return queryTableName; } + const wxString &GetTablePath() { return tablePath; } int GetNumberOfColumns() { return noCols; } // number of "defined" columns for this wxDbTable instance - const char *GetFromClause() { return from; } - const char *GetOrderByClause() { return orderBy; } - const char *GetWhereClause() { return where; } + const wxString &GetFromClause() { return from; } + const wxString &GetOrderByClause() { return orderBy; } + const wxString &GetWhereClause() { return where; } bool IsQueryOnly() { return queryOnly; } #if wxODBC_BACKWARD_COMPATABILITY @@ -224,19 +235,19 @@ public: void From(const wxString& From) { from = From; } void OrderBy(const wxString& OrderBy) { orderBy = OrderBy; } void Where(const wxString& Where) { where = Where; } - const char * Where() { return (const char *)where.c_str(); } - const char * OrderBy() { return (const char *)orderBy.c_str(); } - const char * From() { return (const char *)from.c_str(); } + const wxString &Where() { return where; } + const wxString &OrderBy() { return orderBy; } + const wxString &From() { return from; } #endif int Insert(void); bool Update(void); - bool Update(const char *pSqlStmt); - bool UpdateWhere(const char *pWhereClause); + bool Update(const wxString &pSqlStmt); + bool UpdateWhere(const wxString &pWhereClause); bool Delete(void); - bool DeleteWhere(const char *pWhereClause); + bool DeleteWhere(const wxString &pWhereClause); bool DeleteMatching(void); virtual bool Query(bool forUpdate = FALSE, bool distinct = FALSE); - bool QueryBySqlStmt(const char *pSqlStmt); + bool QueryBySqlStmt(const wxString &pSqlStmt); bool QueryMatching(bool forUpdate = FALSE, bool distinct = FALSE); bool QueryOnKeyFields(bool forUpdate = FALSE, bool distinct = FALSE); bool Refresh(void); @@ -253,10 +264,18 @@ public: bool IsCursorClosedOnCommit(void); UWORD GetRowNum(void); - void BuildSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct); - void BuildDeleteStmt(char *pSqlStmt, int typeOfDel, const char *pWhereClause = NULL); - void BuildUpdateStmt(char *pSqlStmt, int typeOfUpd, const char *pWhereClause = NULL); - void BuildWhereClause(char *pWhereClause, int typeOfWhere, const char *qualTableName = NULL, bool useLikeComparison=FALSE); + void BuildSelectStmt(wxString &pSqlStmt, int typeOfSelect, bool distinct); + void BuildSelectStmt(wxChar *pSqlStmt, int typeOfSelect, bool distinct); + + void BuildDeleteStmt(wxString &pSqlStmt, int typeOfDel, const wxString &pWhereClause=""); + void BuildDeleteStmt(wxChar *pSqlStmt, int typeOfDel, const wxString &pWhereClause=""); + + void BuildUpdateStmt(wxString &pSqlStmt, int typeOfUpd, const wxString &pWhereClause=""); + void BuildUpdateStmt(wxChar *pSqlStmt, int typeOfUpd, const wxString &pWhereClause=""); + + void BuildWhereClause(wxString &pWhereClause, int typeOfWhere, const wxString &qualTableName="", bool useLikeComparison=FALSE); + void BuildWhereClause(wxChar *pWhereClause, int typeOfWhere, const wxString &qualTableName="", bool useLikeComparison=FALSE); + #if wxODBC_BACKWARD_COMPATABILITY // The following member functions are deprecated. You should use the BuildXxxxxStmt functions (above) void GetSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct) @@ -276,7 +295,7 @@ public: bool SetQueryTimeout(UDWORD nSeconds); wxDbColDef *GetColDefs() { return colDefs; } - void SetColDefs(int index, const char *fieldName, int dataType, void *pData, int cType, + void SetColDefs(int index, const wxString &fieldName, int dataType, void *pData, int cType, int size, bool keyField = FALSE, bool upd = TRUE, bool insAllow = TRUE, bool derivedCol = FALSE); wxDbColDataPtr *SetColDefs(wxDbColInf *colInfs, ULONG numCols); @@ -291,12 +310,12 @@ public: HSTMT *NewCursor(bool setCursor = FALSE, bool bindColumns = TRUE) { return GetNewCursor(setCursor,bindColumns); } #endif - ULONG Count(const char *args="*"); + ULONG Count(const wxString &args="*"); int DB_STATUS(void) { return(pDb->DB_STATUS); } bool IsColNull(int colNo); bool SetColNull(int colNo, bool set=TRUE); - bool SetColNull(const char *colName, bool set=TRUE); + bool SetColNull(const wxString &colName, bool set=TRUE); #if wxODBC_BACKWARD_COMPATABILITY // The following member functions are deprecated. You should use the SetColNull() bool SetNull(int colNo, bool set=TRUE) { return (SetNull(colNo,set)); } diff --git a/src/common/db.cpp b/src/common/db.cpp index 71f0176226..21c1313c12 100644 --- a/src/common/db.cpp +++ b/src/common/db.cpp @@ -99,8 +99,8 @@ WXDLLEXPORT_DATA(wxDbList*) PtrBegDbList = 0; -char const *SQL_LOG_FILENAME = "sqllog.txt"; -char const *SQL_CATALOG_FILENAME = "catalog.txt"; +wxChar const *SQL_LOG_FILENAME = wxT("sqllog.txt"); +wxChar const *SQL_CATALOG_FILENAME = wxT("catalog.txt"); #ifdef __WXDEBUG__ extern wxList TablesInUse; @@ -109,8 +109,6 @@ char const *SQL_CATALOG_FILENAME = "catalog.txt"; // SQL Log defaults to be used by GetDbConnection wxDbSqlLogState SQLLOGstate = sqlLogOFF; -//char SQLLOGfn[wxDB_PATH_MAX+1] = SQL_LOG_FILENAME; -//wxChar *SQLLOGfn = (wxChar*) SQL_LOG_FILENAME; static wxString SQLLOGfn = SQL_LOG_FILENAME; // The wxDb::errorList is copied to this variable when the wxDb object @@ -121,7 +119,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 -char DBerrorList[DB_MAX_ERROR_HISTORY][DB_MAX_ERROR_MSG_LEN]; +wxChar DBerrorList[DB_MAX_ERROR_HISTORY][DB_MAX_ERROR_MSG_LEN]; // This type defines the return row-struct form // SQLTablePrivileges, and is used by wxDB::TablePrivileges. @@ -140,12 +138,12 @@ typedef struct /********** wxDbColFor Constructor **********/ wxDbColFor::wxDbColFor() { - s_Field = ""; + s_Field.Empty(); int i; - for (i=0;i<7;i++) + for (i=0; i<7; i++) { - s_Format[i] = ""; - s_Amount[i] = ""; + s_Format[i].Empty(); + s_Amount[i].Empty(); i_Amount[i] = 0; } i_Nation = 0; // 0=EU, 1=UK, 2=International, 3=US @@ -231,10 +229,8 @@ wxDbInf::~wxDbInf() } // wxDbInf::~wxDbInf() -/*************************************************/ - - -int wxDbColFor::Format(int Nation,int dbDataType,SWORD sqlDataType,short columnSize,short decimalDigits) +int wxDbColFor::Format(int Nation, int dbDataType, SWORD sqlDataType, + short columnSize, short decimalDigits) { // ---------------------------------------------------------------------------------------- // -- 19991224 : mj10777 : Create @@ -248,11 +244,12 @@ int wxDbColFor::Format(int Nation,int dbDataType,SWORD sqlDataType,short columnS // ---------------------------------------------------------------------------------------- // There should also be a function to scan in a string to fill the variable // ---------------------------------------------------------------------------------------- - wxString Temp0; + wxString tempStr; i_Nation = Nation; // 0 = timestamp , 1=EU, 2=UK, 3=International, 4=US i_dbDataType = dbDataType; i_sqlDataType = sqlDataType; s_Field.Printf(wxT("%s%d"),s_Amount[1].c_str(),i_Amount[1]); // OK for VARCHAR, INTEGER and FLOAT + if (i_dbDataType == 0) // Filter unsupported dbDataTypes { if ((i_sqlDataType == SQL_VARCHAR) || (i_sqlDataType == SQL_LONGVARCHAR)) @@ -266,45 +263,47 @@ int wxDbColFor::Format(int Nation,int dbDataType,SWORD sqlDataType,short columnS if (i_sqlDataType == SQL_REAL) i_dbDataType = DB_DATA_TYPE_FLOAT; } + if ((i_dbDataType == DB_DATA_TYPE_INTEGER) && (i_sqlDataType == SQL_C_DOUBLE)) { // DBASE Numeric i_dbDataType = DB_DATA_TYPE_FLOAT; } - switch(i_dbDataType) // -A-> Still a lot of proper formatting to do + + switch(i_dbDataType) // TBD: Still a lot of proper formatting to do { case DB_DATA_TYPE_VARCHAR: - s_Field = "%s"; + s_Field = wxT("%s"); break; case DB_DATA_TYPE_INTEGER: - s_Field = "%d"; + s_Field = wxT("%d"); break; case DB_DATA_TYPE_FLOAT: if (decimalDigits == 0) decimalDigits = 2; - Temp0 = "%"; - Temp0.Printf(wxT("%s%d.%d"),Temp0.c_str(),columnSize,decimalDigits); - s_Field.Printf(wxT("%sf"),Temp0.c_str()); + tempStr = wxT("%"); + tempStr.Printf(wxT("%s%d.%d"),tempStr.c_str(),columnSize,decimalDigits); + s_Field.Printf(wxT("%sf"),tempStr.c_str()); break; case DB_DATA_TYPE_DATE: if (i_Nation == 0) // timestamp YYYY-MM-DD HH:MM:SS.SSS (tested for SYBASE) { - s_Field = "%04d-%02d-%02d %02d:%02d:%02d.%03d"; + s_Field = wxT("%04d-%02d-%02d %02d:%02d:%02d.%03d"); } if (i_Nation == 1) // European DD.MM.YYYY HH:MM:SS.SSS { - s_Field = "%02d.%02d.%04d %02d:%02d:%02d.%03d"; + s_Field = wxT("%02d.%02d.%04d %02d:%02d:%02d.%03d"); } if (i_Nation == 2) // UK DD/MM/YYYY HH:MM:SS.SSS { - s_Field = "%02d/%02d/%04d %02d:%02d:%02d.%03d"; + s_Field = wxT("%02d/%02d/%04d %02d:%02d:%02d.%03d"); } if (i_Nation == 3) // International YYYY-MM-DD HH:MM:SS.SSS { - s_Field = "%04d-%02d-%02d %02d:%02d:%02d.%03d"; + s_Field = wxT("%04d-%02d-%02d %02d:%02d:%02d.%03d"); } if (i_Nation == 4) // US MM/DD/YYYY HH:MM:SS.SSS { - s_Field = "%02d/%02d/%04d %02d:%02d:%02d.%03d"; + s_Field = wxT("%02d/%02d/%04d %02d:%02d:%02d.%03d"); } break; default: @@ -325,6 +324,7 @@ wxDb::wxDb(HENV &aHenv, bool FwdOnlyCursors) } // wxDb::wxDb() +/********** PRIVATE! wxDb::initialize PRIVATE! **********/ void wxDb::initialize() /* * Private member function that sets all wxDb member variables to @@ -345,25 +345,25 @@ void wxDb::initialize() wxStrcpy(errorList[i], wxT("")); // Init typeInf structures - wxStrcpy(typeInfVarchar.TypeName,wxT("")); + typeInfVarchar.TypeName.Empty(); typeInfVarchar.FsqlType = 0; typeInfVarchar.Precision = 0; typeInfVarchar.CaseSensitive = 0; typeInfVarchar.MaximumScale = 0; - wxStrcpy(typeInfInteger.TypeName,wxT("")); + typeInfInteger.TypeName.Empty(); typeInfInteger.FsqlType = 0; typeInfInteger.Precision = 0; typeInfInteger.CaseSensitive = 0; typeInfInteger.MaximumScale = 0; - wxStrcpy(typeInfFloat.TypeName,wxT("")); + typeInfFloat.TypeName.Empty(); typeInfFloat.FsqlType = 0; typeInfFloat.Precision = 0; typeInfFloat.CaseSensitive = 0; typeInfFloat.MaximumScale = 0; - wxStrcpy(typeInfDate.TypeName,wxT("")); + typeInfDate.TypeName.Empty(); typeInfDate.FsqlType = 0; typeInfDate.Precision = 0; typeInfDate.CaseSensitive = 0; @@ -384,10 +384,41 @@ void wxDb::initialize() } // wxDb::initialize() +/********** PRIVATE! wxDb::initialize PRIVATE! **********/ +// +// NOTE: Return value from this function MUST be copied +// immediately, as the value is not good after +// this function has left scope. +// +const wxChar *wxDb::convertUserID(const wxChar *userID, wxString &UserID) +{ + if (userID) + { + if (!wxStrlen(userID)) + UserID = uid; + else + UserID = userID; + } + else + UserID.Empty(); + + // dBase does not use user names, and some drivers fail if you try to pass one + if (Dbms() == dbmsDBASE) + UserID.Empty(); + + // Oracle user names may only be in uppercase, so force + // the name to uppercase + if (Dbms() == dbmsORACLE) + UserID = UserID.Upper(); + + return UserID.c_str(); +} // wxDb::convertUserID() + + /********** wxDb::Open() **********/ -bool wxDb::Open(char *Dsn, char *Uid, char *AuthStr) +bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthStr) { - assert(Dsn && wxStrlen(Dsn)); + wxASSERT(Dsn.Length()); dsn = Dsn; uid = Uid; authStr = AuthStr; @@ -402,16 +433,16 @@ bool wxDb::Open(char *Dsn, char *Uid, char *AuthStr) #ifdef DBDEBUG_CONSOLE if (retcode == SQL_SUCCESS) - cout << "SQLSetConnectOption(CURSOR_LIB) successful" << endl; + cout << wxT("SQLSetConnectOption(CURSOR_LIB) successful") << endl; else - cout << "SQLSetConnectOption(CURSOR_LIB) failed" << endl; + cout << wxT("SQLSetConnectOption(CURSOR_LIB) failed") << endl; #endif } // Connect to the data source - retcode = SQLConnect(hdbc, (UCHAR FAR *) dsn, SQL_NTS, - (UCHAR FAR *) uid, SQL_NTS, - (UCHAR FAR *) authStr,SQL_NTS); + 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) @@ -430,8 +461,8 @@ bool wxDb::Open(char *Dsn, char *Uid, char *AuthStr) If using Intersolv branded ODBC drivers, this is the place where you would substitute your branded driver license information - SQLSetConnectOption(hdbc, 1041, (UDWORD) ""); - SQLSetConnectOption(hdbc, 1042, (UDWORD) ""); + SQLSetConnectOption(hdbc, 1041, (UDWORD) wxT("")); + SQLSetConnectOption(hdbc, 1042, (UDWORD) wxT("")); */ // Mark database as open @@ -548,10 +579,10 @@ bool wxDb::Open(char *Dsn, char *Uid, char *AuthStr) } #ifdef DBDEBUG_CONSOLE - cout << "VARCHAR DATA TYPE: " << typeInfVarchar.TypeName << endl; - cout << "INTEGER DATA TYPE: " << typeInfInteger.TypeName << endl; - cout << "FLOAT DATA TYPE: " << typeInfFloat.TypeName << endl; - cout << "DATE DATA TYPE: " << typeInfDate.TypeName << endl; + 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 << endl; #endif @@ -563,9 +594,9 @@ bool wxDb::Open(char *Dsn, char *Uid, char *AuthStr) bool wxDb::Open(wxDb *copyDb) { - dsn = (char *)copyDb->GetDatasourceName(); - uid = (char *)copyDb->GetUsername(); - authStr = (char *)copyDb->GetPassword(); + dsn = copyDb->GetDatasourceName(); + uid = copyDb->GetUsername(); + authStr = copyDb->GetPassword(); RETCODE retcode; @@ -577,16 +608,16 @@ bool wxDb::Open(wxDb *copyDb) #ifdef DBDEBUG_CONSOLE if (retcode == SQL_SUCCESS) - cout << "SQLSetConnectOption(CURSOR_LIB) successful" << endl; + cout << wxT("SQLSetConnectOption(CURSOR_LIB) successful") << endl; else - cout << "SQLSetConnectOption(CURSOR_LIB) failed" << endl; + cout << wxT("SQLSetConnectOption(CURSOR_LIB) failed") << endl; #endif } // Connect to the data source - retcode = SQLConnect(hdbc, (UCHAR FAR *) dsn, SQL_NTS, - (UCHAR FAR *) uid, SQL_NTS, - (UCHAR FAR *) authStr, SQL_NTS); + 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_ERROR) return(DispAllErrors(henv, hdbc)); @@ -595,8 +626,8 @@ bool wxDb::Open(wxDb *copyDb) If using Intersolv branded ODBC drivers, this is the place where you would substitute your branded driver license information - SQLSetConnectOption(hdbc, 1041, (UDWORD) ""); - SQLSetConnectOption(hdbc, 1042, (UDWORD) ""); + SQLSetConnectOption(hdbc, 1041, (UDWORD) wxT("")); + SQLSetConnectOption(hdbc, 1042, (UDWORD) wxT("")); */ // Mark database as open @@ -645,38 +676,38 @@ bool wxDb::Open(wxDb *copyDb) dbInf.loginTimeout = copyDb->dbInf.loginTimeout; // VARCHAR = Variable length character string - typeInfVarchar.FsqlType = copyDb->typeInfVarchar.FsqlType; - wxStrcpy(typeInfVarchar.TypeName, copyDb->typeInfVarchar.TypeName); + typeInfVarchar.FsqlType = copyDb->typeInfVarchar.FsqlType; + typeInfVarchar.TypeName = copyDb->typeInfVarchar.TypeName; typeInfVarchar.Precision = copyDb->typeInfVarchar.Precision; typeInfVarchar.CaseSensitive = copyDb->typeInfVarchar.CaseSensitive; typeInfVarchar.MaximumScale = copyDb->typeInfVarchar.MaximumScale; // Float - typeInfFloat.FsqlType = copyDb->typeInfFloat.FsqlType; - wxStrcpy(typeInfFloat.TypeName, copyDb->typeInfFloat.TypeName); + typeInfFloat.FsqlType = copyDb->typeInfFloat.FsqlType; + typeInfFloat.TypeName = copyDb->typeInfFloat.TypeName; typeInfFloat.Precision = copyDb->typeInfFloat.Precision; typeInfFloat.CaseSensitive = copyDb->typeInfFloat.CaseSensitive; typeInfFloat.MaximumScale = copyDb->typeInfFloat.MaximumScale; // Integer - typeInfInteger.FsqlType = copyDb->typeInfInteger.FsqlType; - wxStrcpy(typeInfInteger.TypeName, copyDb->typeInfInteger.TypeName); + typeInfInteger.FsqlType = copyDb->typeInfInteger.FsqlType; + typeInfInteger.TypeName = copyDb->typeInfInteger.TypeName; typeInfInteger.Precision = copyDb->typeInfInteger.Precision; typeInfInteger.CaseSensitive = copyDb->typeInfInteger.CaseSensitive; typeInfInteger.MaximumScale = copyDb->typeInfInteger.MaximumScale; // Date/Time - typeInfDate.FsqlType = copyDb->typeInfDate.FsqlType; - wxStrcpy(typeInfDate.TypeName, copyDb->typeInfDate.TypeName); + typeInfDate.FsqlType = copyDb->typeInfDate.FsqlType; + typeInfDate.TypeName = copyDb->typeInfDate.TypeName; typeInfDate.Precision = copyDb->typeInfDate.Precision; typeInfDate.CaseSensitive = copyDb->typeInfDate.CaseSensitive; typeInfDate.MaximumScale = copyDb->typeInfDate.MaximumScale; #ifdef DBDEBUG_CONSOLE - cout << "VARCHAR DATA TYPE: " << typeInfVarchar.TypeName << endl; - cout << "INTEGER DATA TYPE: " << typeInfInteger.TypeName << endl; - cout << "FLOAT DATA TYPE: " << typeInfFloat.TypeName << endl; - cout << "DATE DATA TYPE: " << typeInfDate.TypeName << endl; + 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 << endl; #endif @@ -717,32 +748,32 @@ bool wxDb::setConnectionOptions(void) // Display the connection options to verify them #ifdef DBDEBUG_CONSOLE long l; - cout << "****** CONNECTION OPTIONS ******" << endl; + cout << wxT("****** CONNECTION OPTIONS ******") << endl; if (SQLGetConnectOption(hdbc, SQL_AUTOCOMMIT, &l) != SQL_SUCCESS) return(DispAllErrors(henv, hdbc)); - cout << "AUTOCOMMIT: " << (l == SQL_AUTOCOMMIT_OFF ? "OFF" : "ON") << endl; + cout << wxT("AUTOCOMMIT: ") << (l == SQL_AUTOCOMMIT_OFF ? "OFF" : "ON") << endl; if (SQLGetConnectOption(hdbc, SQL_ODBC_CURSORS, &l) != SQL_SUCCESS) return(DispAllErrors(henv, hdbc)); - cout << "ODBC CURSORS: "; + cout << wxT("ODBC CURSORS: "); switch(l) { case(SQL_CUR_USE_IF_NEEDED): - cout << "SQL_CUR_USE_IF_NEEDED"; + cout << wxT("SQL_CUR_USE_IF_NEEDED"); break; case(SQL_CUR_USE_ODBC): - cout << "SQL_CUR_USE_ODBC"; + cout << wxT("SQL_CUR_USE_ODBC"); break; case(SQL_CUR_USE_DRIVER): - cout << "SQL_CUR_USE_DRIVER"; + cout << wxT("SQL_CUR_USE_DRIVER"); 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; + cout << wxT("TRACING: ") << (l == SQL_OPT_TRACE_OFF ? wxT("OFF") : wxT("ON")) << endl; cout << endl; #endif @@ -863,194 +894,194 @@ bool wxDb::getDbInfo(void) return(DispAllErrors(henv, hdbc)); #ifdef DBDEBUG_CONSOLE - 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; + cout << wxT("***** DATA SOURCE INFORMATION *****") << endl; + cout << wxT(wxT("SERVER Name: ") << dbInf.serverName << endl; + cout << wxT("DBMS Name: ") << dbInf.dbmsName << wxT("; DBMS Version: ") << dbInf.dbmsVer << endl; + cout << wxT("ODBC Version: ") << dbInf.odbcVer << wxT("; Driver Version: ") << dbInf.driverVer << endl; - cout << "API Conf. Level: "; + cout << wxT("API Conf. Level: "); switch(dbInf.apiConfLvl) { - case SQL_OAC_NONE: cout << "None"; break; - case SQL_OAC_LEVEL1: cout << "Level 1"; break; - case SQL_OAC_LEVEL2: cout << "Level 2"; break; + case SQL_OAC_NONE: cout << wxT("None"); break; + case SQL_OAC_LEVEL1: cout << wxT("Level 1"); break; + case SQL_OAC_LEVEL2: cout << wxT("Level 2"); break; } cout << endl; - cout << "SAG CLI Conf. Level: "; + cout << wxT("SAG CLI Conf. Level: "); switch(dbInf.cliConfLvl) { - case SQL_OSCC_NOT_COMPLIANT: cout << "Not Compliant"; break; - case SQL_OSCC_COMPLIANT: cout << "Compliant"; break; + case SQL_OSCC_NOT_COMPLIANT: cout << wxT("Not Compliant"); break; + case SQL_OSCC_COMPLIANT: cout << wxT("Compliant"); break; } cout << endl; - cout << "SQL Conf. Level: "; + cout << wxT("SQL Conf. Level: "); switch(dbInf.sqlConfLvl) { - case SQL_OSC_MINIMUM: cout << "Minimum Grammar"; break; - case SQL_OSC_CORE: cout << "Core Grammar"; break; - case SQL_OSC_EXTENDED: cout << "Extended Grammar"; break; + case SQL_OSC_MINIMUM: cout << wxT("Minimum Grammar"); break; + case SQL_OSC_CORE: cout << wxT("Core Grammar"); break; + case SQL_OSC_EXTENDED: cout << wxT("Extended Grammar"); break; } cout << endl; - cout << "Max. Connections: " << dbInf.maxConnections << endl; - cout << "Outer Joins: " << dbInf.outerJoins << endl; - cout << "Support for Procedures: " << dbInf.procedureSupport << endl; - cout << "All tables accessible : " << dbInf.accessibleTables << endl; - cout << "Cursor COMMIT Behavior: "; + cout << wxT("Max. Connections: ") << dbInf.maxConnections << endl; + cout << wxT("Outer Joins: ") << dbInf.outerJoins << endl; + cout << wxT("Support for Procedures: ") << dbInf.procedureSupport << endl; + cout << wxT("All tables accessible : ") << dbInf.accessibleTables << endl; + cout << wxT("Cursor COMMIT Behavior: "); switch(dbInf.cursorCommitBehavior) { - case SQL_CB_DELETE: cout << "Delete cursors"; break; - case SQL_CB_CLOSE: cout << "Close cursors"; break; - case SQL_CB_PRESERVE: cout << "Preserve cursors"; break; + case SQL_CB_DELETE: cout << wxT("Delete cursors"); break; + case SQL_CB_CLOSE: cout << wxT("Close cursors"); break; + case SQL_CB_PRESERVE: cout << wxT("Preserve cursors"); break; } cout << endl; - cout << "Cursor ROLLBACK Behavior: "; + cout << wxT("Cursor ROLLBACK Behavior: "); switch(dbInf.cursorRollbackBehavior) { - case SQL_CB_DELETE: cout << "Delete cursors"; break; - case SQL_CB_CLOSE: cout << "Close cursors"; break; - case SQL_CB_PRESERVE: cout << "Preserve cursors"; break; + case SQL_CB_DELETE: cout << wxT("Delete cursors"); break; + case SQL_CB_CLOSE: cout << wxT("Close cursors"); break; + case SQL_CB_PRESERVE: cout << wxT("Preserve cursors"); break; } cout << endl; - cout << "Support NOT NULL clause: "; + cout << wxT("Support NOT NULL clause: "); switch(dbInf.supportNotNullClause) { - case SQL_NNC_NULL: cout << "No"; break; - case SQL_NNC_NON_NULL: cout << "Yes"; break; + case SQL_NNC_NULL: cout << wxT("No"); break; + case SQL_NNC_NON_NULL: cout << wxT("Yes"); break; } cout << endl; - cout << "Support IEF (Ref. Integrity): " << dbInf.supportIEF << endl; - cout << "Login Timeout: " << dbInf.loginTimeout << endl; + cout << wxT("Support IEF (Ref. Integrity): ") << dbInf.supportIEF << endl; + cout << wxT("Login Timeout: ") << dbInf.loginTimeout << endl; - cout << endl << endl << "more ..." << endl; + cout << endl << endl << wxT("more ...") << endl; getchar(); - cout << "Default Transaction Isolation: "; + cout << wxT("Default Transaction Isolation: "; switch(dbInf.txnIsolation) { - case SQL_TXN_READ_UNCOMMITTED: cout << "Read Uncommitted"; break; - case SQL_TXN_READ_COMMITTED: cout << "Read Committed"; break; - case SQL_TXN_REPEATABLE_READ: cout << "Repeatable Read"; break; - case SQL_TXN_SERIALIZABLE: cout << "Serializable"; break; + case SQL_TXN_READ_UNCOMMITTED: cout << wxT("Read Uncommitted"); break; + case SQL_TXN_READ_COMMITTED: cout << wxT("Read Committed"); break; + case SQL_TXN_REPEATABLE_READ: cout << wxT("Repeatable Read"); break; + case SQL_TXN_SERIALIZABLE: cout << wxT("Serializable"); break; #ifdef ODBC_V20 - case SQL_TXN_VERSIONING: cout << "Versioning"; break; + case SQL_TXN_VERSIONING: cout << wxT("Versioning"); break; #endif } cout << endl; - cout << "Transaction Isolation Options: "; + cout << wxT("Transaction Isolation Options: "); if (dbInf.txnIsolationOptions & SQL_TXN_READ_UNCOMMITTED) - cout << "Read Uncommitted, "; + cout << wxT("Read Uncommitted, "); if (dbInf.txnIsolationOptions & SQL_TXN_READ_COMMITTED) - cout << "Read Committed, "; + cout << wxT("Read Committed, "); if (dbInf.txnIsolationOptions & SQL_TXN_REPEATABLE_READ) - cout << "Repeatable Read, "; + cout << wxT("Repeatable Read, "); if (dbInf.txnIsolationOptions & SQL_TXN_SERIALIZABLE) - cout << "Serializable, "; + cout << wxT("Serializable, "); #ifdef ODBC_V20 if (dbInf.txnIsolationOptions & SQL_TXN_VERSIONING) - cout << "Versioning"; + cout << wxT("Versioning"); #endif cout << endl; - cout << "Fetch Directions Supported:" << endl << " "; + cout << wxT("Fetch Directions Supported:") << endl << wxT(" "); if (dbInf.fetchDirections & SQL_FD_FETCH_NEXT) - cout << "Next, "; + cout << wxT("Next, "); if (dbInf.fetchDirections & SQL_FD_FETCH_PRIOR) - cout << "Prev, "; + cout << wxT("Prev, "); if (dbInf.fetchDirections & SQL_FD_FETCH_FIRST) - cout << "First, "; + cout << wxT("First, "); if (dbInf.fetchDirections & SQL_FD_FETCH_LAST) - cout << "Last, "; + cout << wxT("Last, "); if (dbInf.fetchDirections & SQL_FD_FETCH_ABSOLUTE) - cout << "Absolute, "; + cout << wxT("Absolute, "); if (dbInf.fetchDirections & SQL_FD_FETCH_RELATIVE) - cout << "Relative, "; + cout << wxT("Relative, "); #ifdef ODBC_V20 if (dbInf.fetchDirections & SQL_FD_FETCH_RESUME) - cout << "Resume, "; + cout << wxT("Resume, "); #endif if (dbInf.fetchDirections & SQL_FD_FETCH_BOOKMARK) - cout << "Bookmark"; + cout << wxT("Bookmark"); cout << endl; - cout << "Lock Types Supported (SQLSetPos): "; + cout << wxT("Lock Types Supported (SQLSetPos): "); if (dbInf.lockTypes & SQL_LCK_NO_CHANGE) - cout << "No Change, "; + cout << wxT("No Change, "); if (dbInf.lockTypes & SQL_LCK_EXCLUSIVE) - cout << "Exclusive, "; + cout << wxT("Exclusive, "); if (dbInf.lockTypes & SQL_LCK_UNLOCK) - cout << "UnLock"; + cout << wxT("UnLock"); cout << endl; - cout << "Position Operations Supported (SQLSetPos): "; + cout << wxT("Position Operations Supported (SQLSetPos): "); if (dbInf.posOperations & SQL_POS_POSITION) - cout << "Position, "; + cout << wxT("Position, "); if (dbInf.posOperations & SQL_POS_REFRESH) - cout << "Refresh, "; + cout << wxT("Refresh, "); if (dbInf.posOperations & SQL_POS_UPDATE) - cout << "Upd, "; + cout << wxT("Upd, ")); if (dbInf.posOperations & SQL_POS_DELETE) - cout << "Del, "; + cout << wxT("Del, "); if (dbInf.posOperations & SQL_POS_ADD) - cout << "Add"; + cout << wxT("Add"); cout << endl; - cout << "Positioned Statements Supported: "; + cout << wxT("Positioned Statements Supported: "); if (dbInf.posStmts & SQL_PS_POSITIONED_DELETE) - cout << "Pos delete, "; + cout << wxT("Pos delete, "); if (dbInf.posStmts & SQL_PS_POSITIONED_UPDATE) - cout << "Pos update, "; + cout << wxT("Pos update, "); if (dbInf.posStmts & SQL_PS_SELECT_FOR_UPDATE) - cout << "Select for update"; + cout << wxT("Select for update"); cout << endl; - cout << "Scroll Concurrency: "; + cout << wxT("Scroll Concurrency: "); if (dbInf.scrollConcurrency & SQL_SCCO_READ_ONLY) - cout << "Read Only, "; + cout << wxT("Read Only, "); if (dbInf.scrollConcurrency & SQL_SCCO_LOCK) - cout << "Lock, "; + cout << wxT("Lock, "); if (dbInf.scrollConcurrency & SQL_SCCO_OPT_ROWVER) - cout << "Opt. Rowver, "; + cout << wxT("Opt. Rowver, "); if (dbInf.scrollConcurrency & SQL_SCCO_OPT_VALUES) - cout << "Opt. Values"; + cout << wxT("Opt. Values"); cout << endl; - cout << "Scroll Options: "; + cout << wxT("Scroll Options: "); if (dbInf.scrollOptions & SQL_SO_FORWARD_ONLY) - cout << "Fwd Only, "; + cout << wxT("Fwd Only, "); if (dbInf.scrollOptions & SQL_SO_STATIC) - cout << "Static, "; + cout << wxT("Static, "); if (dbInf.scrollOptions & SQL_SO_KEYSET_DRIVEN) - cout << "Keyset Driven, "; + cout << wxT("Keyset Driven, "); if (dbInf.scrollOptions & SQL_SO_DYNAMIC) - cout << "Dynamic, "; + cout << wxT("Dynamic, "); if (dbInf.scrollOptions & SQL_SO_MIXED) - cout << "Mixed"; + cout << wxT("Mixed"); cout << endl; - cout << "Static Sensitivity: "; + cout << wxT("Static Sensitivity: "); if (dbInf.staticSensitivity & SQL_SS_ADDITIONS) - cout << "Additions, "; + cout << wxT("Additions, "); if (dbInf.staticSensitivity & SQL_SS_DELETIONS) - cout << "Deletions, "; + cout << wxT("Deletions, "); if (dbInf.staticSensitivity & SQL_SS_UPDATES) - cout << "Updates"; + cout << wxT("Updates"); cout << endl; - cout << "Transaction Capable?: "; + cout << wxT("Transaction Capable?: "); switch(dbInf.txnCapable) { - case SQL_TC_NONE: cout << "No"; break; - case SQL_TC_DML: cout << "DML Only"; break; - case SQL_TC_DDL_COMMIT: cout << "DDL Commit"; break; - case SQL_TC_DDL_IGNORE: cout << "DDL Ignore"; break; - case SQL_TC_ALL: cout << "DDL & DML"; break; + case SQL_TC_NONE: cout << wxT("No"); break; + case SQL_TC_DML: cout << wxT("DML Only"); break; + case SQL_TC_DDL_COMMIT: cout << wxT("DDL Commit"); break; + case SQL_TC_DDL_IGNORE: cout << wxT("DDL Ignore"); break; + case SQL_TC_ALL: cout << wxT("DDL & DML"); break; } cout << endl; @@ -1083,35 +1114,45 @@ bool wxDb::getDataTypeInfo(SWORD fSqlType, wxDbSqlTypeInfo &structSQLTypeInfo) { #ifdef DBDEBUG_CONSOLE if (retcode == SQL_NO_DATA_FOUND) - cout << "SQL_NO_DATA_FOUND fetching inf. about data type." << endl; + cout << wxT("SQL_NO_DATA_FOUND fetching inf. about data type.") << endl; #endif DispAllErrors(henv, hdbc, hstmt); SQLFreeStmt(hstmt, SQL_CLOSE); return(FALSE); } + + wxChar typeName[DB_TYPE_NAME_LEN+1]; // Obtain columns from the record - if (SQLGetData(hstmt, 1, SQL_C_CHAR, (UCHAR*) structSQLTypeInfo.TypeName, DB_TYPE_NAME_LEN, &cbRet) != SQL_SUCCESS) + if (SQLGetData(hstmt, 1, SQL_C_CHAR, (UCHAR*) typeName, DB_TYPE_NAME_LEN, &cbRet) != SQL_SUCCESS) return(DispAllErrors(henv, hdbc, hstmt)); + structSQLTypeInfo.TypeName = typeName; + // BJO 20000503: no more needed with new GetColumns... #if OLD_GETCOLUMNS // BJO 991209 if (Dbms() == dbmsMY_SQL) { - if (!wxStrcmp(structSQLTypeInfo.TypeName, "middleint")) wxStrcpy(structSQLTypeInfo.TypeName, "mediumint"); - if (!wxStrcmp(structSQLTypeInfo.TypeName, "middleint unsigned")) wxStrcpy(structSQLTypeInfo.TypeName, "mediumint unsigned"); - if (!wxStrcmp(structSQLTypeInfo.TypeName, "integer")) wxStrcpy(structSQLTypeInfo.TypeName, "int"); - if (!wxStrcmp(structSQLTypeInfo.TypeName, "integer unsigned")) wxStrcpy(structSQLTypeInfo.TypeName, "int unsigned"); - if (!wxStrcmp(structSQLTypeInfo.TypeName, "middleint")) wxStrcpy(structSQLTypeInfo.TypeName, "mediumint"); - if (!wxStrcmp(structSQLTypeInfo.TypeName, "varchar")) wxStrcpy(structSQLTypeInfo.TypeName, "char"); + if (structSQLTypeInfo.TypeName == wxT("middleint")) + structSQLTypeInfo.TypeName = wxT("mediumint"); + else if (structSQLTypeInfo.TypeName == wxT("middleint unsigned")) + structSQLTypeInfo.TypeName = wxT("mediumint unsigned"); + else if (structSQLTypeInfo.TypeName == wxT("integer")) + structSQLTypeInfo.TypeName = wxT("int"); + else if (structSQLTypeInfo.TypeName == wxT("integer unsigned")) + structSQLTypeInfo.TypeName = wxT("int unsigned"); + else if (structSQLTypeInfo.TypeName == wxT("middleint")) + structSQLTypeInfo.TypeName = wxT("mediumint"); + else if (structSQLTypeInfo.TypeName == wxT("varchar")) + structSQLTypeInfo.TypeName = wxT("char"); } // BJO 20000427 : OpenLink driver - if (!wxStrncmp(dbInf.driverName, "oplodbc", 7) || - !wxStrncmp(dbInf.driverName, "OLOD", 4)) + if (!wxStrncmp(dbInf.driverName, wxT("oplodbc"), 7) || + !wxStrncmp(dbInf.driverName, wxT("OLOD"), 4)) { - if (!wxStrcmp(structSQLTypeInfo.TypeName, "double precision")) - wxStrcpy(structSQLTypeInfo.TypeName, "real"); + if (structSQLTypeInfo.TypeName == wxT("double precision")) + structSQLTypeInfo.TypeName = wxT("real"); } #endif @@ -1164,7 +1205,7 @@ void wxDb::Close(void) DispAllErrors(henv, hdbc); // There should be zero Ctable objects still connected to this db object - assert(nTables == 0); + wxASSERT(nTables == 0); #ifdef __WXDEBUG__ wxTablesInUse *tiu; @@ -1176,9 +1217,9 @@ void wxDb::Close(void) tiu = (wxTablesInUse *)pNode->Data(); if (tiu->pDb == this) { - s.sprintf(wxT("(%-20s) tableID:[%6lu] pDb:[%p]"), tiu->tableName,tiu->tableID,tiu->pDb); - s2.sprintf(wxT("Orphaned found using pDb:[%p]"),this); - wxLogDebug (s.c_str(),s2.c_str()); + 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,s2); } pNode = pNode->Next(); } @@ -1232,7 +1273,7 @@ bool wxDb::DispAllErrors(HENV aHenv, HDBC aHdbc, HSTMT aHstmt) * actual error(s) that just occured on the previous request of the datasource. * * The function will retrieve each error condition from the datasource and - * sprintf the codes/text values into a string which it then logs via logError(). + * 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. * @@ -1245,19 +1286,19 @@ bool wxDb::DispAllErrors(HENV aHenv, HDBC aHdbc, HSTMT aHstmt) while (SQLError(aHenv, aHdbc, aHstmt, (UCHAR FAR *) sqlState, &nativeError, (UCHAR FAR *) errorMsg, SQL_MAX_MESSAGE_LENGTH - 1, &cbErrorMsg) == SQL_SUCCESS) { - odbcErrMsg.sprintf("SQL State = %s\nNative Error Code = %li\nError Message = %s\n", sqlState, nativeError, errorMsg); - logError(odbcErrMsg.c_str(), sqlState); + odbcErrMsg.Printf(wxT("SQL State = %s\nNative Error Code = %li\nError Message = %s\n"), sqlState, nativeError, errorMsg); + logError(odbcErrMsg, sqlState); if (!silent) { #ifdef DBDEBUG_CONSOLE // When run in console mode, use standard out to display errors. cout << odbcErrMsg.c_str() << endl; - cout << "Press any key to continue..." << endl; + cout << wxT("Press any key to continue...") << endl; getchar(); #endif #ifdef __WXDEBUG__ - wxLogDebug(odbcErrMsg.c_str(),wxT("ODBC DEBUG MESSAGE from DispAllErrors()")); + wxLogDebug(odbcErrMsg,wxT("ODBC DEBUG MESSAGE from DispAllErrors()")); #endif } } @@ -1283,8 +1324,8 @@ void wxDb::DispNextError(void) { wxString odbcErrMsg; - odbcErrMsg.sprintf("SQL State = %s\nNative Error Code = %li\nError Message = %s\n", sqlState, nativeError, errorMsg); - logError(odbcErrMsg.c_str(), sqlState); + odbcErrMsg.Printf(wxT("SQL State = %s\nNative Error Code = %li\nError Message = %s\n"), sqlState, nativeError, errorMsg); + logError(odbcErrMsg, sqlState); if (silent) return; @@ -1292,7 +1333,7 @@ void wxDb::DispNextError(void) #ifdef DBDEBUG_CONSOLE // When run in console mode, use standard out to display errors. cout << odbcErrMsg.c_str() << endl; - cout << "Press any key to continue..." << endl; + cout << wxT("Press any key to continue...") << endl; getchar(); #endif @@ -1304,9 +1345,9 @@ void wxDb::DispNextError(void) /********** wxDb::logError() **********/ -void wxDb::logError(const char *errMsg, const char *SQLState) +void wxDb::logError(const wxString &errMsg, const wxString &SQLState) { - assert(errMsg && wxStrlen(errMsg)); + wxASSERT(errMsg.Length()); static int pLast = -1; int dbStatus; @@ -1321,7 +1362,7 @@ void wxDb::logError(const char *errMsg, const char *SQLState) wxStrcpy(errorList[pLast], errMsg); - if (SQLState && wxStrlen(SQLState)) + if (SQLState.Length()) if ((dbStatus = TranslateSqlState(SQLState)) != DB_ERR_FUNCTION_SEQUENCE_ERROR) DB_STATUS = dbStatus; @@ -1332,7 +1373,7 @@ void wxDb::logError(const char *errMsg, const char *SQLState) /**********wxDb::TranslateSqlState() **********/ -int wxDb::TranslateSqlState(const wxChar *SQLState) +int wxDb::TranslateSqlState(const wxString &SQLState) { if (!wxStrcmp(SQLState, wxT("01000"))) return(DB_ERR_GENERAL_WARNING); @@ -1520,60 +1561,61 @@ int wxDb::TranslateSqlState(const wxChar *SQLState) /********** wxDb::Grant() **********/ -bool wxDb::Grant(int privileges, const char *tableName, const char *userList) +bool wxDb::Grant(int privileges, const wxString &tableName, const wxString &userList) { wxString sqlStmt; // Build the grant statement - sqlStmt = "GRANT "; + sqlStmt = wxT("GRANT "); if (privileges == DB_GRANT_ALL) - sqlStmt += "ALL"; + sqlStmt += wxT("ALL"); else { int c = 0; if (privileges & DB_GRANT_SELECT) { - sqlStmt += "SELECT"; + sqlStmt += wxT("SELECT"); c++; } if (privileges & DB_GRANT_INSERT) { if (c++) - sqlStmt += ", "; - sqlStmt += "INSERT"; + sqlStmt += wxT(", "); + sqlStmt += wxT("INSERT"); } if (privileges & DB_GRANT_UPDATE) { if (c++) - sqlStmt += ", "; - sqlStmt += "UPDATE"; + sqlStmt += wxT(", "); + sqlStmt += wxT("UPDATE"); } if (privileges & DB_GRANT_DELETE) { if (c++) - sqlStmt += ", "; - sqlStmt += "DELETE"; + sqlStmt += wxT(", "); + sqlStmt += wxT("DELETE"); } } - sqlStmt += " ON "; + sqlStmt += wxT(" ON "); sqlStmt += tableName; - sqlStmt += " TO "; + sqlStmt += wxT(" TO "); sqlStmt += userList; #ifdef DBDEBUG_CONSOLE cout << endl << sqlStmt.c_str() << endl; #endif - WriteSqlLog(sqlStmt.c_str()); + WriteSqlLog(sqlStmt); - return(ExecSql(sqlStmt.c_str())); + return(ExecSql(sqlStmt)); } // wxDb::Grant() /********** wxDb::CreateView() **********/ -bool wxDb::CreateView(const char *viewName, const char *colList, const char *pSqlStmt, bool attemptDrop) +bool wxDb::CreateView(const wxString &viewName, const wxString &colList, + const wxString &pSqlStmt, bool attemptDrop) { wxString sqlStmt; @@ -1582,32 +1624,32 @@ bool wxDb::CreateView(const char *viewName, const char *colList, const char *pSq return FALSE; // Build the create view statement - sqlStmt = "CREATE VIEW "; + sqlStmt = wxT("CREATE VIEW "); sqlStmt += viewName; - if (wxStrlen(colList)) + if (colList.Length()) { - sqlStmt += " ("; + sqlStmt += wxT(" ("); sqlStmt += colList; - sqlStmt += ")"; + sqlStmt += wxT(")"); } - sqlStmt += " AS "; + sqlStmt += wxT(" AS "); sqlStmt += pSqlStmt; - WriteSqlLog(sqlStmt.c_str()); + WriteSqlLog(sqlStmt); #ifdef DBDEBUG_CONSOLE cout << sqlStmt.c_str() << endl; #endif - return(ExecSql(sqlStmt.c_str())); + return(ExecSql(sqlStmt)); } // wxDb::CreateView() /********** wxDb::DropView() **********/ -bool wxDb::DropView(const char *viewName) +bool wxDb::DropView(const wxString &viewName) { /* * NOTE: This function returns TRUE if the View does not exist, but @@ -1615,12 +1657,11 @@ bool wxDb::DropView(const char *viewName) * below for any other databases when those databases are defined * to handle this situation consistently */ -// char sqlStmt[DB_MAX_STATEMENT_LEN]; wxString sqlStmt; - sqlStmt.sprintf("DROP VIEW %s", viewName); + sqlStmt.Printf(wxT("DROP VIEW %s"), viewName); - WriteSqlLog(sqlStmt.c_str()); + WriteSqlLog(sqlStmt); #ifdef DBDEBUG_CONSOLE cout << endl << sqlStmt.c_str() << endl; @@ -1653,10 +1694,10 @@ bool wxDb::DropView(const char *viewName) /********** wxDb::ExecSql() **********/ -bool wxDb::ExecSql(const char *pSqlStmt) +bool wxDb::ExecSql(const wxString &pSqlStmt) { SQLFreeStmt(hstmt, SQL_CLOSE); - if (SQLExecDirect(hstmt, (UCHAR FAR *) pSqlStmt, SQL_NTS) == SQL_SUCCESS) + if (SQLExecDirect(hstmt, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS) == SQL_SUCCESS) return(TRUE); else { @@ -1684,8 +1725,8 @@ bool wxDb::GetNext(void) /********** wxDb::GetData() **********/ bool wxDb::GetData(UWORD colNo, SWORD cType, PTR pData, SDWORD maxLen, SDWORD FAR *cbReturned) { - assert(pData); - assert(cbReturned); + wxASSERT(pData); + wxASSERT(cbReturned); if (SQLGetData(hstmt, colNo, cType, pData, maxLen, cbReturned) == SQL_SUCCESS) return(TRUE); @@ -1699,38 +1740,38 @@ bool wxDb::GetData(UWORD colNo, SWORD cType, PTR pData, SDWORD maxLen, SDWORD FA /********** wxDb::GetKeyFields() **********/ -int wxDb::GetKeyFields(char *tableName, wxDbColInf* colInf, int noCols) +int wxDb::GetKeyFields(const wxString &tableName, wxDbColInf* colInf, int noCols) { - char szPkTable[DB_MAX_TABLE_NAME_LEN+1]; /* Primary key table name */ - char szFkTable[DB_MAX_TABLE_NAME_LEN+1]; /* Foreign key table name */ + wxChar szPkTable[DB_MAX_TABLE_NAME_LEN+1]; /* Primary key table name */ + wxChar szFkTable[DB_MAX_TABLE_NAME_LEN+1]; /* Foreign key table name */ short iKeySeq; // SQLSMALLINT iKeySeq; - char szPkCol[DB_MAX_COLUMN_NAME_LEN+1]; /* Primary key column */ - char szFkCol[DB_MAX_COLUMN_NAME_LEN+1]; /* Foreign key column */ + 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; int i; - wxString Temp0; + wxString tempStr; /* - * --------------------------------------------------------------------- - * -- 19991224 : mj10777 : Create ------ - * -- : Three things are done and stored here : ------ - * -- : 1) which Column(s) is/are Primary Key(s) ------ - * -- : 2) which tables use this Key as a Foreign Key ------ - * -- : 3) which columns are Foreign Key and the name ------ - * -- : of the Table where the Key is the Primary Key ----- - * -- : Called from GetColumns(char *tableName, ------ - * -- int *numCols,const char *userID ) ------ - * --------------------------------------------------------------------- + * ----------------------------------------------------------------------- + * -- 19991224 : mj10777 : Create ------ + * -- : Three things are done and stored here : ------ + * -- : 1) which Column(s) is/are Primary Key(s) ------ + * -- : 2) which tables use this Key as a Foreign Key ------ + * -- : 3) which columns are Foreign Key and the name ------ + * -- : of the Table where the Key is the Primary Key ----- + * -- : Called from GetColumns(const wxString &tableName, ------ + * -- int *numCols,const wxChar *userID ) ------ + * ----------------------------------------------------------------------- */ /*---------------------------------------------------------------------*/ /* Get the names of the columns in the primary key. */ /*---------------------------------------------------------------------*/ retcode = SQLPrimaryKeys(hstmt, - NULL, 0, /* Catalog name */ - NULL, 0, /* Schema name */ - (UCHAR *) tableName, SQL_NTS); /* Table name */ + NULL, 0, /* Catalog name */ + NULL, 0, /* Schema name */ + (UCHAR FAR *) tableName.c_str(), SQL_NTS); /* Table name */ /*---------------------------------------------------------------------*/ /* Fetch and display the result set. This will be a list of the */ @@ -1755,18 +1796,18 @@ int wxDb::GetKeyFields(char *tableName, wxDbColInf* colInf, int noCols) /* Get all the foreign keys that refer to tableName primary key. */ /*---------------------------------------------------------------------*/ retcode = SQLForeignKeys(hstmt, - NULL, 0, /* Primary catalog */ - NULL, 0, /* Primary schema */ - (UCHAR *)tableName, SQL_NTS, /* Primary table */ - NULL, 0, /* Foreign catalog */ - NULL, 0, /* Foreign schema */ - NULL, 0); /* Foreign table */ + NULL, 0, /* Primary catalog */ + NULL, 0, /* Primary schema */ + (UCHAR FAR *)tableName.c_str(), SQL_NTS,/* Primary table */ + NULL, 0, /* Foreign catalog */ + NULL, 0, /* Foreign schema */ + NULL, 0); /* Foreign table */ /*---------------------------------------------------------------------*/ /* Fetch and display the result set. This will be all of the foreign */ /* keys in other tables that refer to the tableName primary key. */ /*---------------------------------------------------------------------*/ - Temp0.Empty(); + tempStr.Empty(); szPkCol[0] = 0; while ((retcode == SQL_SUCCESS) || (retcode == SQL_SUCCESS_WITH_INFO)) { @@ -1778,30 +1819,32 @@ int wxDb::GetKeyFields(char *tableName, wxDbColInf* colInf, int noCols) GetData( 5, SQL_C_SSHORT, &iKeySeq, 0, &cb); GetData( 7, SQL_C_CHAR, szFkTable, DB_MAX_TABLE_NAME_LEN+1, &cb); GetData( 8, SQL_C_CHAR, szFkCol, DB_MAX_COLUMN_NAME_LEN+1, &cb); - Temp0.Printf(wxT("%s[%s] "),Temp0.c_str(),szFkTable); // [ ] in case there is a blank in the Table name + tempStr.Printf(wxT("%s[%s] "),tempStr.c_str(),szFkTable); // [ ] in case there is a blank in the Table name } // if } // while - Temp0.Trim(); // Get rid of any unneeded blanks - if (Temp0 != wxT("")) + + tempStr.Trim(); // Get rid of any unneeded blanks + if (!tempStr.IsEmpty()) { - for (i=0;i 0) || + dataType != DB_DATA_TYPE_VARCHAR); + + // Must specify a columnLength if modifying a VARCHAR type column + if (dataType == DB_DATA_TYPE_VARCHAR && !columnLength) + return FALSE; + + wxString dataTypeName; + wxString sqlStmt; + wxString alterSlashModify; + + switch(dataType) + { + case DB_DATA_TYPE_VARCHAR : + dataTypeName = typeInfVarchar.TypeName; + break; + case DB_DATA_TYPE_INTEGER : + dataTypeName = typeInfInteger.TypeName; + break; + case DB_DATA_TYPE_FLOAT : + dataTypeName = typeInfFloat.TypeName; + break; + case DB_DATA_TYPE_DATE : + dataTypeName = typeInfDate.TypeName; + break; + default: + return FALSE; + } + + // Set the modify or alter syntax depending on the type of database connected to + switch (Dbms()) + { + case dbmsORACLE : + alterSlashModify = "MODIFY"; + break; + case dbmsMS_SQL_SERVER : + alterSlashModify = "ALTER COLUMN"; + break; + case dbmsUNIDENTIFIED : + return FALSE; + case dbmsSYBASE_ASA : + case dbmsSYBASE_ASE : + case dbmsMY_SQL : + case dbmsPOSTGRES : + case dbmsACCESS : + case dbmsDBASE : + default : + alterSlashModify = "MODIFY"; + break; + } + + // create the SQL statement + sqlStmt.Printf(wxT("ALTER TABLE %s %s %s %s"), tableName, alterSlashModify, + columnName, dataTypeName); + + // For varchars only, append the size of the column + if (dataType == DB_DATA_TYPE_VARCHAR) + { + wxString s; + s.Printf(wxT("(%d)"), columnLength); + sqlStmt += s; + } + + // for passing things like "NOT NULL" + if (optionalParam.Length()) + { + sqlStmt += wxT(" "); + sqlStmt += optionalParam; + } + + return ExecSql(sqlStmt); + +} // wxDb::ModifyColumn() + + /********** wxDbGetConnection() **********/ wxDb WXDLLEXPORT *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCursors) { @@ -3377,11 +3369,11 @@ wxDb WXDLLEXPORT *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCurso } // Initialize new node in the linked list - pList->PtrNext = 0; - pList->Free = FALSE; - wxStrcpy(pList->Dsn, pDbConfig->Dsn); - wxStrcpy(pList->Uid, pDbConfig->Uid); - wxStrcpy(pList->AuthStr, pDbConfig->AuthStr); + pList->PtrNext = 0; + pList->Free = FALSE; + pList->Dsn = pDbConfig->Dsn; + pList->Uid = pDbConfig->Uid; + pList->AuthStr = pDbConfig->AuthStr; pList->PtrDb = new wxDb(pDbConfig->Henv,FwdOnlyCursors); @@ -3494,8 +3486,8 @@ bool wxDbSqlLog(wxDbSqlLogState state, const wxChar *filename) #if 0 /********** wxDbCreateDataSource() **********/ -int wxDbCreateDataSource(const char *driverName, const char *dsn, const char *description, - bool sysDSN, const char *defDir, wxWindow *parent) +int wxDbCreateDataSource(const wxString &driverName, const wxString &dsn, const wxString &description, + bool sysDSN, const wxString &defDir, wxWindow *parent) /* * !!!! ONLY FUNCTIONAL UNDER MSW with VC6 !!!! * Very rudimentary creation of an ODBC data source. @@ -3518,7 +3510,7 @@ int wxDbCreateDataSource(const char *driverName, const char *dsn, const char *de // NOTE: The decimal 2 is an invalid character in all keyword pairs // so that is why I used it, as wxString does not deal well with // embedded nulls in strings - setupStr.sprintf("DSN=%s%cDescription=%s%cDefaultDir=%s%c",dsn,2,description,2,defDir,2); + 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 // by the SQLConfigDataSource() function @@ -3527,7 +3519,7 @@ int wxDbCreateDataSource(const char *driverName, const char *dsn, const char *de { k = setupStr.Find((wxChar)2,TRUE); if (k != wxNOT_FOUND) - setupStr[(UINT)k] = '\0'; + setupStr[(UINT)k] = wxT('\0'); } while (k != wxNOT_FOUND); @@ -3540,7 +3532,7 @@ int wxDbCreateDataSource(const char *driverName, const char *dsn, const char *de DWORD retcode = 0; WORD cb; wxChar errMsg[SQL_MAX_MESSAGE_LENGTH]; - errMsg[0] = '\0'; + errMsg[0] = wxT('\0'); // This function is only supported in ODBC drivers v3.0 compliant and above SQLInstallerError(1,&retcode,errMsg,SQL_MAX_MESSAGE_LENGTH-1,&cb); @@ -3564,7 +3556,7 @@ int wxDbCreateDataSource(const char *driverName, const char *dsn, const char *de // Using iODBC/unixODBC or some other compiler which does not support the APIs // necessary to use this function, so this function is not supported #ifdef __WXDEBUG__ - wxLogDebug("wxDbCreateDataSource() not available except under VC++/MSW",wxT("ODBC DEBUG MESSAGE")); + wxLogDebug(wxT("wxDbCreateDataSource() not available except under VC++/MSW"),wxT("ODBC DEBUG MESSAGE")); #endif result = FALSE; #endif // __VISUALC__ @@ -3576,8 +3568,8 @@ int wxDbCreateDataSource(const char *driverName, const char *dsn, const char *de /********** wxDbGetDataSource() **********/ -bool wxDbGetDataSource(HENV henv, char *Dsn, SWORD DsnMax, char *DsDesc, SWORD DsDescMax, - UWORD direction) +bool wxDbGetDataSource(HENV henv, wxChar *Dsn, SWORD DsnMax, wxChar *DsDesc, + SWORD DsDescMax, UWORD direction) /* * Dsn and DsDesc will contain the data source name and data source * description upon return diff --git a/src/common/dbtable.cpp b/src/common/dbtable.cpp index de3b913141..f85c5904f7 100644 --- a/src/common/dbtable.cpp +++ b/src/common/dbtable.cpp @@ -75,7 +75,7 @@ #include #include #include -#include +//#include #if wxMAJOR_VERSION == 1 #include "table.h" @@ -103,9 +103,36 @@ ULONG lastTableID = 0; /********** wxDbTable::wxDbTable() **********/ -wxDbTable::wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, - const char *qryTblName, bool qryOnly, const char *tblPath) +wxDbTable::wxDbTable(wxDb *pwxDb, const wxString &tblName, const int nCols, + const wxString &qryTblName, bool qryOnly, const wxString &tblPath) { + if (!initialize(pwxDb, tblName, nCols, qryTblName, qryOnly, tblPath)) + cleanup(); +} // wxDbTable::wxDbTable() + + +/***** DEPRECATED: use wxDbTable::wxDbTable() format above *****/ +wxDbTable::wxDbTable(wxDb *pwxDb, const wxString &tblName, const int nCols, + const wxChar *qryTblName, bool qryOnly, const wxString &tblPath) +{ + wxString tempQryTblName; + tempQryTblName = qryTblName; + if (!initialize(pwxDb, tblName, nCols, tempQryTblName, qryOnly, tblPath)) + cleanup(); +} // wxDbTable::wxDbTable() + + +/********** wxDbTable::~wxDbTable() **********/ +wxDbTable::~wxDbTable() +{ + this->cleanup(); +} // wxDbTable::~wxDbTable() + + +bool wxDbTable::initialize(wxDb *pwxDb, const wxString &tblName, const int nCols, + const wxString &qryTblName, bool qryOnly, const wxString &tblPath) +{ + // Initializing member variables pDb = pwxDb; // Pointer to the wxDb object henv = 0; hdbc = 0; @@ -119,37 +146,38 @@ wxDbTable::wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, colDefs = 0; tableID = 0; noCols = nCols; // No. of cols in the table - where = ""; // Where clause - orderBy = ""; // Order By clause - from = ""; // From clause + where.Empty(); // Where clause + orderBy.Empty(); // Order By clause + from.Empty(); // From clause selectForUpdate = FALSE; // SELECT ... FOR UPDATE; Indicates whether to include the FOR UPDATE phrase queryOnly = qryOnly; insertable = TRUE; - wxStrcpy(tablePath,""); - wxStrcpy(tableName,""); - wxStrcpy(queryTableName,""); + tablePath.Empty(); + tableName.Empty(); + queryTableName.Empty(); - assert (tblName); + wxASSERT(tblName.Length()); + wxASSERT(pDb); - wxStrcpy(tableName, tblName); // Table Name - if (tblPath) - wxStrcpy(tablePath, tblPath); // Table Path - used for dBase files + if (!pDb) + return FALSE; + + tableName = tblName; // Table Name + if (tblPath.Length()) + tablePath = tblPath; // Table Path - used for dBase files else - tablePath[0] = 0; + tablePath.Empty(); - if (qryTblName) // Name of the table/view to query - wxStrcpy(queryTableName, qryTblName); + if (qryTblName.Length()) // Name of the table/view to query + queryTableName = qryTblName; else - wxStrcpy(queryTableName, tblName); - - if (!pDb) - return; + queryTableName = tblName; pDb->incrementTableCount(); wxString s; tableID = ++lastTableID; - s.sprintf("wxDbTable constructor (%-20s) tableID:[%6lu] pDb:[%p]", tblName,tableID,pDb); + s.Printf(wxT("wxDbTable constructor (%-20s) tableID:[%6lu] pDb:[%p]"), tblName,tableID,pDb); #ifdef __WXDEBUG__ wxTablesInUse *tableInUse; @@ -160,7 +188,7 @@ wxDbTable::wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, TablesInUse.Append(tableInUse); #endif - pDb->WriteSqlLog(s.c_str()); + pDb->WriteSqlLog(s); // Grab the HENV and HDBC from the wxDb object henv = pDb->GetHENV(); @@ -168,7 +196,7 @@ wxDbTable::wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, // Allocate space for column definitions if (noCols) - colDefs = new wxDbColDef[noCols]; // Points to the first column defintion + colDefs = new wxDbColDef[noCols]; // Points to the first column definition // Allocate statement handles for the table if (!queryOnly) @@ -194,7 +222,7 @@ wxDbTable::wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, { // Check to see if cursor type is supported pDb->GetNextError(henv, hdbc, hstmtInternal); - if (! wxStrcmp(pDb->sqlState, "01S02")) // Option Value Changed + if (! wxStrcmp(pDb->sqlState, wxT("01S02"))) // Option Value Changed { // Datasource does not support static cursors. Driver // will substitute a cursor type. Call SQLGetStmtOption() @@ -202,20 +230,20 @@ wxDbTable::wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, if (SQLGetStmtOption(hstmtInternal, SQL_CURSOR_TYPE, &cursorType) != SQL_SUCCESS) pDb->DispAllErrors(henv, hdbc, hstmtInternal); #ifdef DBDEBUG_CONSOLE - cout << "Static cursor changed to: "; + cout << wxT("Static cursor changed to: "); switch(cursorType) { case SQL_CURSOR_FORWARD_ONLY: - cout << "Forward Only"; + cout << wxT("Forward Only"); break; case SQL_CURSOR_STATIC: - cout << "Static"; + cout << wxT("Static"); break; case SQL_CURSOR_KEYSET_DRIVEN: - cout << "Keyset Driven"; + cout << wxT("Keyset Driven"); break; case SQL_CURSOR_DYNAMIC: - cout << "Dynamic"; + cout << wxT("Dynamic"); break; } cout << endl << endl; @@ -229,7 +257,7 @@ wxDbTable::wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, { // Should never happen pDb->GetNextError(henv, hdbc, hstmtInternal); - return; + return FALSE; } } } @@ -241,7 +269,7 @@ wxDbTable::wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, } #ifdef DBDEBUG_CONSOLE else - cout << "Cursor Type set to STATIC" << endl << endl; + cout << wxT("Cursor Type set to STATIC") << endl << endl; #endif if (!queryOnly) @@ -259,20 +287,21 @@ wxDbTable::wxDbTable(wxDb *pwxDb, const char *tblName, const int nCols, // Make the default cursor the active cursor hstmtDefault = GetNewCursor(FALSE,FALSE); - assert(hstmtDefault); + wxASSERT(hstmtDefault); hstmt = *hstmtDefault; - -} // wxDbTable::wxDbTable() + return TRUE; -/********** wxDbTable::~wxDbTable() **********/ -wxDbTable::~wxDbTable() +} // wxDbTable::initialize() + + +void wxDbTable::cleanup() { wxString s; if (pDb) { - s.sprintf("wxDbTable destructor (%-20s) tableID:[%6lu] pDb:[%p]", tableName,tableID,pDb); - pDb->WriteSqlLog(s.c_str()); + s.Printf(wxT("wxDbTable destructor (%-20s) tableID:[%6lu] pDb:[%p]"), tableName,tableID,pDb); + pDb->WriteSqlLog(s); } #ifdef __WXDEBUG__ @@ -289,7 +318,7 @@ wxDbTable::~wxDbTable() { found = TRUE; if (!TablesInUse.DeleteNode(pNode)) - wxLogDebug (s.c_str(),wxT("Unable to delete node!")); + wxLogDebug (s,wxT("Unable to delete node!")); } else pNode = pNode->Next(); @@ -297,8 +326,8 @@ wxDbTable::~wxDbTable() if (!found) { wxString msg; - msg.sprintf(wxT("Unable to find the tableID in the linked\nlist of tables in use.\n\n%s"),s.c_str()); - wxLogDebug (msg.c_str(),wxT("NOTICE...")); + msg.Printf(wxT("Unable to find the tableID in the linked\nlist of tables in use.\n\n%s"),s); + wxLogDebug (msg,wxT("NOTICE...")); } } #endif @@ -336,115 +365,39 @@ wxDbTable::~wxDbTable() if (hstmtCount) DeleteCursor(hstmtCount); - -} // wxDbTable::~wxDbTable() - +} // wxDbTable::cleanup() /***************************** PRIVATE FUNCTIONS *****************************/ - -/********** wxDbTable::bindInsertParams() **********/ -bool wxDbTable::bindInsertParams(void) +/********** wxDbTable::bindUpdateParams() **********/ +bool wxDbTable::bindParams(bool forUpdate) { - assert(!queryOnly); + wxASSERT(!queryOnly); if (queryOnly) return(FALSE); - + SWORD fSqlType = 0; UDWORD precision = 0; SWORD scale = 0; - - // Bind each column (that can be inserted) of the table to a parameter marker + + // Bind each column of the table that should be bound + // to a parameter marker int i,colNo; for (i = 0, colNo = 1; i < noCols; i++) { - if (! colDefs[i].InsertAllowed) - continue; - switch(colDefs[i].DbDataType) + if (forUpdate) { - case DB_DATA_TYPE_VARCHAR: - fSqlType = pDb->GetTypeInfVarchar().FsqlType; - precision = colDefs[i].SzDataObj; - scale = 0; - if (colDefs[i].Null) - colDefs[i].CbValue = SQL_NULL_DATA; - else - colDefs[i].CbValue = SQL_NTS; - break; - case DB_DATA_TYPE_INTEGER: - fSqlType = pDb->GetTypeInfInteger().FsqlType; - precision = pDb->GetTypeInfInteger().Precision; - scale = 0; - if (colDefs[i].Null) - colDefs[i].CbValue = SQL_NULL_DATA; - else - colDefs[i].CbValue = 0; - break; - case DB_DATA_TYPE_FLOAT: - fSqlType = pDb->GetTypeInfFloat().FsqlType; - precision = pDb->GetTypeInfFloat().Precision; - scale = pDb->GetTypeInfFloat().MaximumScale; - // SQL Sybase Anywhere v5.5 returned a negative number for the - // MaxScale. This caused ODBC to kick out an error on ibscale. - // I check for this here and set the scale = precision. - //if (scale < 0) - // scale = (short) precision; - if (colDefs[i].Null) - colDefs[i].CbValue = SQL_NULL_DATA; - else - colDefs[i].CbValue = 0; - break; - case DB_DATA_TYPE_DATE: - fSqlType = pDb->GetTypeInfDate().FsqlType; - precision = pDb->GetTypeInfDate().Precision; - scale = 0; - if (colDefs[i].Null) - colDefs[i].CbValue = SQL_NULL_DATA; - else - colDefs[i].CbValue = 0; - break; + if (! colDefs[i].Updateable) + continue; } - // Null values -//RG-NULL -//RG-NULL if (colDefs[i].Null) -//RG-NULL { -//RG-NULL colDefs[i].CbValue = SQL_NULL_DATA; -//RG-NULL colDefs[i].Null = FALSE; -//RG-NULL } - - if (SQLBindParameter(hstmtInsert, colNo++, SQL_PARAM_INPUT, colDefs[i].SqlCtype, - fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, - precision+1,&colDefs[i].CbValue) != SQL_SUCCESS) + else { - return(pDb->DispAllErrors(henv, hdbc, hstmtInsert)); + if (! colDefs[i].InsertAllowed) + continue; } - } - - // Completed successfully - return(TRUE); -} // wxDbTable::bindInsertParams() - - -/********** wxDbTable::bindUpdateParams() **********/ -bool wxDbTable::bindUpdateParams(void) -{ - assert(!queryOnly); - if (queryOnly) - return(FALSE); - - SWORD fSqlType = 0; - UDWORD precision = 0; - SWORD scale = 0; - - // Bind each UPDATEABLE column of the table to a parameter marker - int i,colNo; - for (i = 0, colNo = 1; i < noCols; i++) - { - if (! colDefs[i].Updateable) - continue; switch(colDefs[i].DbDataType) { case DB_DATA_TYPE_VARCHAR: @@ -489,18 +442,43 @@ bool wxDbTable::bindUpdateParams(void) colDefs[i].CbValue = 0; break; } - - if (SQLBindParameter(hstmtUpdate, colNo++, SQL_PARAM_INPUT, colDefs[i].SqlCtype, - fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, - precision+1, &colDefs[i].CbValue) != SQL_SUCCESS) + if (forUpdate) + { + if (SQLBindParameter(hstmtUpdate, colNo++, SQL_PARAM_INPUT, colDefs[i].SqlCtype, + fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, + precision+1, &colDefs[i].CbValue) != SQL_SUCCESS) + { + return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate)); + } + } + else { - return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate)); + if (SQLBindParameter(hstmtInsert, colNo++, SQL_PARAM_INPUT, colDefs[i].SqlCtype, + fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, + precision+1,&colDefs[i].CbValue) != SQL_SUCCESS) + { + return(pDb->DispAllErrors(henv, hdbc, hstmtInsert)); + } } } // Completed successfully return(TRUE); +} // wxDbTable::bindParams() + + +/********** wxDbTable::bindInsertParams() **********/ +bool wxDbTable::bindInsertParams(void) +{ + return bindParams(FALSE); +} // wxDbTable::bindInsertParams() + + +/********** wxDbTable::bindUpdateParams() **********/ +bool wxDbTable::bindUpdateParams(void) +{ + return bindParams(TRUE); } // wxDbTable::bindUpdateParams() @@ -583,10 +561,10 @@ bool wxDbTable::getRec(UWORD fetchType) /********** wxDbTable::execDelete() **********/ -bool wxDbTable::execDelete(const char *pSqlStmt) +bool wxDbTable::execDelete(const wxString &pSqlStmt) { // Execute the DELETE statement - if (SQLExecDirect(hstmtDelete, (UCHAR FAR *) pSqlStmt, SQL_NTS) != SQL_SUCCESS) + if (SQLExecDirect(hstmtDelete, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) return(pDb->DispAllErrors(henv, hdbc, hstmtDelete)); // Record deleted successfully @@ -596,10 +574,10 @@ bool wxDbTable::execDelete(const char *pSqlStmt) /********** wxDbTable::execUpdate() **********/ -bool wxDbTable::execUpdate(const char *pSqlStmt) +bool wxDbTable::execUpdate(const wxString &pSqlStmt) { // Execute the UPDATE statement - if (SQLExecDirect(hstmtUpdate, (UCHAR FAR *) pSqlStmt, SQL_NTS) != SQL_SUCCESS) + if (SQLExecDirect(hstmtUpdate, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate)); // Record deleted successfully @@ -609,9 +587,9 @@ bool wxDbTable::execUpdate(const char *pSqlStmt) /********** wxDbTable::query() **********/ -bool wxDbTable::query(int queryType, bool forUpdate, bool distinct, const char *pSqlStmt) +bool wxDbTable::query(int queryType, bool forUpdate, bool distinct, const wxString &pSqlStmt) { - char sqlStmt[DB_MAX_STATEMENT_LEN]; + wxString sqlStmt; if (forUpdate) // The user may wish to select for update, but the DBMS may not be capable @@ -647,7 +625,7 @@ bool wxDbTable::query(int queryType, bool forUpdate, bool distinct, const char * // Execute the SQL SELECT statement int retcode; - retcode = SQLExecDirect(hstmt, (UCHAR FAR *) (queryType == DB_SELECT_STATEMENT ? pSqlStmt : sqlStmt), SQL_NTS); + retcode = SQLExecDirect(hstmt, (UCHAR FAR *) (queryType == DB_SELECT_STATEMENT ? pSqlStmt.c_str() : sqlStmt.c_str()), SQL_NTS); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) return(pDb->DispAllErrors(henv, hdbc, hstmt)); @@ -670,15 +648,15 @@ bool wxDbTable::Open(bool checkPrivileges) wxString sqlStmt; wxString s; - s = ""; + s.Empty(); // Verify that the table exists in the database if (!pDb->TableExists(tableName,/*pDb->GetUsername()*/NULL,tablePath)) { - s = "Table/view does not exist in the database"; - if ( *(pDb->dbInf.accessibleTables) == 'Y') - s += ", or you have no permissions.\n"; + s = wxT("Table/view does not exist in the database"); + if ( *(pDb->dbInf.accessibleTables) == wxT('Y')) + s += wxT(", or you have no permissions.\n"); else - s += ".\n"; + s += wxT(".\n"); } else if (checkPrivileges) { @@ -689,18 +667,18 @@ bool wxDbTable::Open(bool checkPrivileges) // Unfortunately this optimization doesn't seem to be // reliable! if (// *(pDb->dbInf.accessibleTables) == 'N' && - !pDb->TablePrivileges(tableName,"SELECT",NULL,pDb->GetUsername(),tablePath)) - s = "Current logged in user does not have sufficient privileges to access this table.\n"; + !pDb->TablePrivileges(tableName,wxT("SELECT"),NULL,pDb->GetUsername(),tablePath)) + s = wxT("Current logged in user does not have sufficient privileges to access this table.\n"); } if (!s.IsEmpty()) { wxString p; - if (wxStrcmp(tablePath,"")) - p.sprintf("Error opening '%s/%s'.\n",tablePath,tableName); + if (!tablePath.IsEmpty()) + p.Printf(wxT("Error opening '%s/%s'.\n"),tablePath,tableName); else - p.sprintf("Error opening '%s'.\n", tableName); + p.Printf(wxT("Error opening '%s'.\n"), tableName); p += s; pDb->LogError(p.GetData()); @@ -733,18 +711,18 @@ bool wxDbTable::Open(bool checkPrivileges) if (!queryOnly && noCols > 0) { bool needComma = FALSE; - sqlStmt.sprintf("INSERT INTO %s (", tableName); + sqlStmt.Printf(wxT("INSERT INTO %s ("), tableName); for (i = 0; i < noCols; i++) { if (! colDefs[i].InsertAllowed) continue; if (needComma) - sqlStmt += ","; + sqlStmt += wxT(","); sqlStmt += colDefs[i].ColName; needComma = TRUE; } needComma = FALSE; - sqlStmt += ") VALUES ("; + sqlStmt += wxT(") VALUES ("); int insertableCount = 0; @@ -753,12 +731,12 @@ bool wxDbTable::Open(bool checkPrivileges) if (! colDefs[i].InsertAllowed) continue; if (needComma) - sqlStmt += ","; - sqlStmt += "?"; + sqlStmt += wxT(","); + sqlStmt += wxT("?"); needComma = TRUE; insertableCount++; } - sqlStmt += ")"; + sqlStmt += wxT(")"); // Prepare the insert statement for execution if (insertableCount) @@ -786,7 +764,7 @@ bool wxDbTable::Query(bool forUpdate, bool distinct) /********** wxDbTable::QueryBySqlStmt() **********/ -bool wxDbTable::QueryBySqlStmt(const char *pSqlStmt) +bool wxDbTable::QueryBySqlStmt(const wxString &pSqlStmt) { pDb->WriteSqlLog(pSqlStmt); @@ -869,19 +847,88 @@ bool wxDbTable::GetLast(void) } // wxDbTable::GetLast() -/********** wxDbTable::BuildSelectStmt() **********/ -void wxDbTable::BuildSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct) +/********** wxDbTable::BuildDeleteStmt() **********/ +void wxDbTable::BuildDeleteStmt(wxString &pSqlStmt, int typeOfDel, const wxString &pWhereClause) { - char whereClause[DB_MAX_WHERE_CLAUSE_LEN]; + wxASSERT(!queryOnly); + if (queryOnly) + return; + + wxString whereClause; - whereClause[0] = 0; + whereClause.Empty(); + + // Handle the case of DeleteWhere() and the where clause is blank. It should + // delete all records from the database in this case. + if (typeOfDel == DB_DEL_WHERE && (pWhereClause.Length() == 0)) + { + pSqlStmt.Printf(wxT("DELETE FROM %s"), tableName); + return; + } + + pSqlStmt.Printf(wxT("DELETE FROM %s WHERE "), tableName); + + // Append the WHERE clause to the SQL DELETE statement + switch(typeOfDel) + { + case DB_DEL_KEYFIELDS: + // If the datasource supports the ROWID column, build + // the where on ROWID for efficiency purposes. + // e.g. DELETE FROM PARTS WHERE ROWID = '111.222.333' + if (CanUpdByROWID()) + { + SDWORD cb; + wxChar rowid[wxDB_ROWID_LEN+1]; + + // Get the ROWID value. If not successful retreiving the ROWID, + // simply fall down through the code and build the WHERE clause + // based on the key fields. + if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS) + { + pSqlStmt += wxT("ROWID = '"); + pSqlStmt += rowid; + pSqlStmt += wxT("'"); + break; + } + } + // Unable to delete by ROWID, so build a WHERE + // clause based on the keyfields. + BuildWhereClause(whereClause, DB_WHERE_KEYFIELDS); + pSqlStmt += whereClause; + break; + case DB_DEL_WHERE: + pSqlStmt += pWhereClause; + break; + case DB_DEL_MATCHING: + BuildWhereClause(whereClause, DB_WHERE_MATCHING); + pSqlStmt += whereClause; + break; + } + +} // BuildDeleteStmt() + + +/***** DEPRECATED: use wxDbTable::BuildDeleteStmt(wxString &....) form *****/ +void wxDbTable::BuildDeleteStmt(wxChar *pSqlStmt, int typeOfDel, const wxString &pWhereClause) +{ + wxString tempSqlStmt; + BuildDeleteStmt(tempSqlStmt, typeOfDel, pWhereClause); + wxStrcpy(pSqlStmt, tempSqlStmt); +} // wxDbTable::BuildDeleteStmt() + + +/********** wxDbTable::BuildSelectStmt() **********/ +void wxDbTable::BuildSelectStmt(wxString &pSqlStmt, int typeOfSelect, bool distinct) +{ + wxString whereClause; + whereClause.Empty(); // Build a select statement to query the database - wxStrcpy(pSqlStmt, "SELECT "); + pSqlStmt = wxT("SELECT "); // SELECT DISTINCT values only? if (distinct) - wxStrcat(pSqlStmt, "DISTINCT "); + pSqlStmt += wxT("DISTINCT "); // Was a FROM clause specified to join tables to the base table? // Available for ::Query() only!!! @@ -901,12 +948,12 @@ void wxDbTable::BuildSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct) // If joining tables, the base table column names must be qualified to avoid ambiguity if (appendFromClause) { - wxStrcat(pSqlStmt, queryTableName); - wxStrcat(pSqlStmt, "."); + pSqlStmt += queryTableName; + pSqlStmt += wxT("."); } - wxStrcat(pSqlStmt, colDefs[i].ColName); + pSqlStmt += colDefs[i].ColName; if (i + 1 < noCols) - wxStrcat(pSqlStmt, ","); + pSqlStmt += wxT(","); } // If the datasource supports ROWID, get this column as well. Exception: Don't retrieve @@ -916,17 +963,17 @@ void wxDbTable::BuildSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct) // If joining tables, the base table column names must be qualified to avoid ambiguity if (appendFromClause) { - wxStrcat(pSqlStmt, ","); - wxStrcat(pSqlStmt, queryTableName); - wxStrcat(pSqlStmt, ".ROWID"); + pSqlStmt += wxT(","); + pSqlStmt += queryTableName; + pSqlStmt += wxT(".ROWID"); } else - wxStrcat(pSqlStmt, ",ROWID"); + pSqlStmt += wxT(",ROWID"); } // Append the FROM tablename portion - wxStrcat(pSqlStmt, " FROM "); - wxStrcat(pSqlStmt, queryTableName); + pSqlStmt += wxT(" FROM "); + pSqlStmt += queryTableName; // Sybase uses the HOLDLOCK keyword to lock a record during query. // The HOLDLOCK keyword follows the table name in the from clause. @@ -934,10 +981,10 @@ void wxDbTable::BuildSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct) // NOHOLDLOCK (the default). Note: The "FOR UPDATE" clause // is parsed but ignored in SYBASE Transact-SQL. if (selectForUpdate && (pDb->Dbms() == dbmsSYBASE_ASA || pDb->Dbms() == dbmsSYBASE_ASE)) - wxStrcat(pSqlStmt, " HOLDLOCK"); + pSqlStmt += wxT(" HOLDLOCK"); if (appendFromClause) - wxStrcat(pSqlStmt, from); + pSqlStmt += from; // Append the WHERE clause. Either append the where clause for the class // or build a where clause. The typeOfSelect determines this. @@ -950,24 +997,24 @@ void wxDbTable::BuildSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct) if (where.Length()) // May not want a where clause!!! #endif { - wxStrcat(pSqlStmt, " WHERE "); - wxStrcat(pSqlStmt, where); + pSqlStmt += wxT(" WHERE "); + pSqlStmt += where; } break; case DB_SELECT_KEYFIELDS: BuildWhereClause(whereClause, DB_WHERE_KEYFIELDS); - if (wxStrlen(whereClause)) + if (whereClause.Length()) { - wxStrcat(pSqlStmt, " WHERE "); - wxStrcat(pSqlStmt, whereClause); + pSqlStmt += wxT(" WHERE "); + pSqlStmt += whereClause; } break; case DB_SELECT_MATCHING: BuildWhereClause(whereClause, DB_WHERE_MATCHING); - if (wxStrlen(whereClause)) + if (whereClause.Length()) { - wxStrcat(pSqlStmt, " WHERE "); - wxStrcat(pSqlStmt, whereClause); + pSqlStmt += wxT(" WHERE "); + pSqlStmt += whereClause; } break; } @@ -979,19 +1026,181 @@ void wxDbTable::BuildSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct) if (orderBy.Length()) #endif { - wxStrcat(pSqlStmt, " ORDER BY "); - wxStrcat(pSqlStmt, orderBy); + pSqlStmt += wxT(" ORDER BY "); + pSqlStmt += orderBy; } // SELECT FOR UPDATE if told to do so and the datasource is capable. Sybase // parses the FOR UPDATE clause but ignores it. See the comment above on the // HOLDLOCK for Sybase. if (selectForUpdate && CanSelectForUpdate()) - wxStrcat(pSqlStmt, " FOR UPDATE"); + pSqlStmt += wxT(" FOR UPDATE"); + +} // wxDbTable::BuildSelectStmt() + +/***** DEPRECATED: use wxDbTable::BuildSelectStmt(wxString &....) form *****/ +void wxDbTable::BuildSelectStmt(wxChar *pSqlStmt, int typeOfSelect, bool distinct) +{ + wxString tempSqlStmt; + BuildSelectStmt(tempSqlStmt, typeOfSelect, distinct); + wxStrcpy(pSqlStmt, tempSqlStmt); } // wxDbTable::BuildSelectStmt() +/********** wxDbTable::BuildUpdateStmt() **********/ +void wxDbTable::BuildUpdateStmt(wxString &pSqlStmt, int typeOfUpd, const wxString &pWhereClause) +{ + wxASSERT(!queryOnly); + if (queryOnly) + return; + + wxString whereClause; + whereClause.Empty(); + + bool firstColumn = TRUE; + + pSqlStmt.Printf(wxT("UPDATE %s SET "), tableName); + + // Append a list of columns to be updated + int i; + for (i = 0; i < noCols; i++) + { + // Only append Updateable columns + if (colDefs[i].Updateable) + { + if (! firstColumn) + pSqlStmt += wxT(","); + else + firstColumn = FALSE; + pSqlStmt += colDefs[i].ColName; + pSqlStmt += wxT(" = ?"); + } + } + + // Append the WHERE clause to the SQL UPDATE statement + pSqlStmt += wxT(" WHERE "); + switch(typeOfUpd) + { + case DB_UPD_KEYFIELDS: + // If the datasource supports the ROWID column, build + // the where on ROWID for efficiency purposes. + // e.g. UPDATE PARTS SET Col1 = ?, Col2 = ? WHERE ROWID = '111.222.333' + if (CanUpdByROWID()) + { + SDWORD cb; + wxChar rowid[wxDB_ROWID_LEN+1]; + + // Get the ROWID value. If not successful retreiving the ROWID, + // simply fall down through the code and build the WHERE clause + // based on the key fields. + if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS) + { + pSqlStmt += wxT("ROWID = '"); + pSqlStmt += rowid; + pSqlStmt += wxT("'"); + break; + } + } + // Unable to delete by ROWID, so build a WHERE + // clause based on the keyfields. + BuildWhereClause(whereClause, DB_WHERE_KEYFIELDS); + pSqlStmt += whereClause; + break; + case DB_UPD_WHERE: + pSqlStmt += pWhereClause; + break; + } +} // BuildUpdateStmt() + + +/***** DEPRECATED: use wxDbTable::BuildUpdateStmt(wxString &....) form *****/ +void wxDbTable::BuildUpdateStmt(wxChar *pSqlStmt, int typeOfUpd, const wxString &pWhereClause) +{ + wxString tempSqlStmt; + BuildUpdateStmt(tempSqlStmt, typeOfUpd, pWhereClause); + wxStrcpy(pSqlStmt, tempSqlStmt); +} // BuildUpdateStmt() + + +/********** wxDbTable::BuildWhereClause() **********/ +void wxDbTable::BuildWhereClause(wxString &pWhereClause, int typeOfWhere, + const wxString &qualTableName, bool useLikeComparison) +/* + * Note: BuildWhereClause() currently ignores timestamp columns. + * They are not included as part of the where clause. + */ +{ + bool moreThanOneColumn = FALSE; + wxString colValue; + + // Loop through the columns building a where clause as you go + int i; + for (i = 0; i < noCols; i++) + { + // Determine if this column should be included in the WHERE clause + if ((typeOfWhere == DB_WHERE_KEYFIELDS && colDefs[i].KeyField) || + (typeOfWhere == DB_WHERE_MATCHING && (!IsColNull(i)))) + { + // Skip over timestamp columns + if (colDefs[i].SqlCtype == SQL_C_TIMESTAMP) + continue; + // If there is more than 1 column, join them with the keyword "AND" + if (moreThanOneColumn) + pWhereClause += wxT(" AND "); + else + moreThanOneColumn = TRUE; + // Concatenate where phrase for the column + if (qualTableName.Length()) + { + pWhereClause += qualTableName; + pWhereClause += wxT("."); + } + pWhereClause += colDefs[i].ColName; + if (useLikeComparison && (colDefs[i].SqlCtype == SQL_C_CHAR)) + pWhereClause += wxT(" LIKE "); + else + pWhereClause += wxT(" = "); + switch(colDefs[i].SqlCtype) + { + case SQL_C_CHAR: + colValue.Printf(wxT("'%s'"), (UCHAR FAR *) colDefs[i].PtrDataObj); + break; + case SQL_C_SSHORT: + colValue.Printf(wxT("%hi"), *((SWORD *) colDefs[i].PtrDataObj)); + break; + case SQL_C_USHORT: + colValue.Printf(wxT("%hu"), *((UWORD *) colDefs[i].PtrDataObj)); + break; + case SQL_C_SLONG: + colValue.Printf(wxT("%li"), *((SDWORD *) colDefs[i].PtrDataObj)); + break; + case SQL_C_ULONG: + colValue.Printf(wxT("%lu"), *((UDWORD *) colDefs[i].PtrDataObj)); + break; + case SQL_C_FLOAT: + colValue.Printf(wxT("%.6f"), *((SFLOAT *) colDefs[i].PtrDataObj)); + break; + case SQL_C_DOUBLE: + colValue.Printf(wxT("%.6f"), *((SDOUBLE *) colDefs[i].PtrDataObj)); + break; + } + pWhereClause += colValue; + } + } +} // wxDbTable::BuildWhereClause() + + +/***** DEPRECATED: use wxDbTable::BuildWhereClause(wxString &....) form *****/ +void wxDbTable::BuildWhereClause(wxChar *pWhereClause, int typeOfWhere, + const wxString &qualTableName, bool useLikeComparison) +{ + wxString tempSqlStmt; + BuildWhereClause(tempSqlStmt, typeOfWhere, qualTableName, useLikeComparison); + wxStrcpy(pWhereClause, tempSqlStmt); +} // wxDbTable::BuildWhereClause() + + /********** wxDbTable::GetRowNum() **********/ UWORD wxDbTable::GetRowNum(void) { @@ -1031,7 +1240,7 @@ bool wxDbTable::CreateTable(bool attemptDrop) wxString sqlStmt; #ifdef DBDEBUG_CONSOLE - cout << "Creating Table " << tableName << "..." << endl; + cout << wxT("Creating Table ") << tableName << wxT("...") << endl; #endif // Drop table first @@ -1045,11 +1254,11 @@ bool wxDbTable::CreateTable(bool attemptDrop) // Exclude derived columns since they are NOT part of the base table if (colDefs[i].DerivedCol) continue; - cout << i + 1 << ": " << colDefs[i].ColName << "; "; + cout << i + 1 << wxT(": ") << colDefs[i].ColName << wxT("; "); switch(colDefs[i].DbDataType) { case DB_DATA_TYPE_VARCHAR: - cout << pDb->typeInfVarchar.TypeName << "(" << colDefs[i].SzDataObj << ")"; + cout << pDb->typeInfVarchar.TypeName << wxT("(") << colDefs[i].SzDataObj << wxT(")"); break; case DB_DATA_TYPE_INTEGER: cout << pDb->typeInfInteger.TypeName; @@ -1067,7 +1276,7 @@ bool wxDbTable::CreateTable(bool attemptDrop) // Build a CREATE TABLE string from the colDefs structure. bool needComma = FALSE; - sqlStmt.sprintf("CREATE TABLE %s (", tableName); + sqlStmt.Printf(wxT("CREATE TABLE %s ("), tableName); for (i = 0; i < noCols; i++) { @@ -1076,10 +1285,10 @@ bool wxDbTable::CreateTable(bool attemptDrop) continue; // Comma Delimiter if (needComma) - sqlStmt += ","; + sqlStmt += wxT(","); // Column Name sqlStmt += colDefs[i].ColName; - sqlStmt += " "; + sqlStmt += wxT(" "); // Column Type switch(colDefs[i].DbDataType) { @@ -1100,11 +1309,8 @@ bool wxDbTable::CreateTable(bool attemptDrop) if (colDefs[i].DbDataType == DB_DATA_TYPE_VARCHAR) { wxString s; - // wxStrcat(sqlStmt, "("); - // wxStrcat(sqlStmt, itoa(colDefs[i].SzDataObj, s, 10)); - // wxStrcat(sqlStmt, ")"); - s.sprintf("(%d)", colDefs[i].SzDataObj); - sqlStmt += s.c_str(); + s.Printf(wxT("(%d)"), colDefs[i].SzDataObj); + sqlStmt += s; } if (pDb->Dbms() == dbmsDB2 || @@ -1114,7 +1320,7 @@ bool wxDbTable::CreateTable(bool attemptDrop) { if (colDefs[i].KeyField) { - sqlStmt += " NOT NULL"; + sqlStmt += wxT(" NOT NULL"); } } @@ -1133,14 +1339,14 @@ bool wxDbTable::CreateTable(bool attemptDrop) { if (pDb->Dbms() != dbmsMY_SQL) { - sqlStmt += ",CONSTRAINT "; + sqlStmt += wxT(",CONSTRAINT "); sqlStmt += tableName; - sqlStmt += "_PIDX PRIMARY KEY ("; + sqlStmt += wxT("_PIDX PRIMARY KEY ("); } else { /* MySQL goes out on this one. We also declare the relevant key NON NULL above */ - sqlStmt += ", PRIMARY KEY ("; + sqlStmt += wxT(", PRIMARY KEY ("); } // List column name(s) of column(s) comprising the primary key @@ -1149,16 +1355,16 @@ bool wxDbTable::CreateTable(bool attemptDrop) if (colDefs[i].KeyField) { if (j++) // Multi part key, comma separate names - sqlStmt += ","; + sqlStmt += wxT(","); sqlStmt += colDefs[i].ColName; } } - sqlStmt += ")"; + sqlStmt += wxT(")"); } // Append the closing parentheses for the create table statement - sqlStmt += ")"; + sqlStmt += wxT(")"); - pDb->WriteSqlLog(sqlStmt.c_str()); + pDb->WriteSqlLog(sqlStmt); #ifdef DBDEBUG_CONSOLE cout << endl << sqlStmt.c_str() << endl; @@ -1196,9 +1402,9 @@ bool wxDbTable::DropTable() wxString sqlStmt; - sqlStmt.sprintf("DROP TABLE %s", tableName); + sqlStmt.Printf(wxT("DROP TABLE %s"), tableName); - pDb->WriteSqlLog(sqlStmt.c_str()); + pDb->WriteSqlLog(sqlStmt); #ifdef DBDEBUG_CONSOLE cout << endl << sqlStmt.c_str() << endl; @@ -1208,12 +1414,13 @@ bool wxDbTable::DropTable() { // Check for "Base table not found" error and ignore pDb->GetNextError(henv, hdbc, hstmt); - if (wxStrcmp(pDb->sqlState,"S0002") && wxStrcmp(pDb->sqlState, "S1000")) // "Base table not found" + if (wxStrcmp(pDb->sqlState, wxT("S0002")) && + wxStrcmp(pDb->sqlState, wxT("S1000"))) // "Base table not found" { // Check for product specific error codes - if (!((pDb->Dbms() == dbmsSYBASE_ASA && !wxStrcmp(pDb->sqlState,"42000")) || // 5.x (and lower?) - (pDb->Dbms() == dbmsSYBASE_ASE && !wxStrcmp(pDb->sqlState,"37000")) || - (pDb->Dbms() == dbmsPOSTGRES && !wxStrcmp(pDb->sqlState,"08S01")))) + if (!((pDb->Dbms() == dbmsSYBASE_ASA && !wxStrcmp(pDb->sqlState,wxT("42000"))) || // 5.x (and lower?) + (pDb->Dbms() == dbmsSYBASE_ASE && !wxStrcmp(pDb->sqlState,wxT("37000"))) || + (pDb->Dbms() == dbmsPOSTGRES && !wxStrcmp(pDb->sqlState,wxT("08S01"))))) { pDb->DispNextError(); pDb->DispAllErrors(henv, hdbc, hstmt); @@ -1235,7 +1442,7 @@ bool wxDbTable::DropTable() /********** wxDbTable::CreateIndex() **********/ -bool wxDbTable::CreateIndex(const char * idxName, bool unique, int noIdxCols, wxDbIdxDef *pIdxDefs, bool attemptDrop) +bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, int noIdxCols, wxDbIdxDef *pIdxDefs, bool attemptDrop) { wxString sqlStmt; @@ -1274,35 +1481,10 @@ bool wxDbTable::CreateIndex(const char * idxName, bool unique, int noIdxCols, wx if (found) { - wxString typeNameAndSize; - - switch(colDefs[j].DbDataType) - { - case DB_DATA_TYPE_VARCHAR: - typeNameAndSize = pDb->GetTypeInfVarchar().TypeName; - break; - case DB_DATA_TYPE_INTEGER: - typeNameAndSize = pDb->GetTypeInfInteger().TypeName; - break; - case DB_DATA_TYPE_FLOAT: - typeNameAndSize = pDb->GetTypeInfFloat().TypeName; - break; - case DB_DATA_TYPE_DATE: - typeNameAndSize = pDb->GetTypeInfDate().TypeName; - break; - } - - // For varchars, append the size of the string - if (colDefs[j].DbDataType == DB_DATA_TYPE_VARCHAR) - { - wxString s; - s.sprintf("(%d)", colDefs[i].SzDataObj); - typeNameAndSize += s.c_str(); - } - - sqlStmt.sprintf("ALTER TABLE %s MODIFY %s %s NOT NULL",tableName,pIdxDefs[i].ColName,typeNameAndSize.c_str()); - ok = pDb->ExecSql(sqlStmt.c_str()); - + ok = pDb->ModifyColumn(tableName, pIdxDefs[i].ColName, + colDefs[j].DbDataType, colDefs[j].SzDataObj, + wxT("NOT NULL")); + if (!ok) { wxODBC_ERRORS retcode; @@ -1325,15 +1507,15 @@ bool wxDbTable::CreateIndex(const char * idxName, bool unique, int noIdxCols, wx } // Build a CREATE INDEX statement - sqlStmt = "CREATE "; + sqlStmt = wxT("CREATE "); if (unique) - sqlStmt += "UNIQUE "; + sqlStmt += wxT("UNIQUE "); - sqlStmt += "INDEX "; + sqlStmt += wxT("INDEX "); sqlStmt += idxName; - sqlStmt += " ON "; + sqlStmt += wxT(" ON "); sqlStmt += tableName; - sqlStmt += " ("; + sqlStmt += wxT(" ("); // Append list of columns making up index int i; @@ -1344,19 +1526,19 @@ bool wxDbTable::CreateIndex(const char * idxName, bool unique, int noIdxCols, wx if (pDb->Dbms() != dbmsPOSTGRES) { if (pIdxDefs[i].Ascending) - sqlStmt += " ASC"; + sqlStmt += wxT(" ASC"); else - sqlStmt += " DESC"; + sqlStmt += wxT(" DESC"); } if ((i + 1) < noIdxCols) - sqlStmt += ","; + sqlStmt += wxT(","); } // Append closing parentheses - sqlStmt += ")"; + sqlStmt += wxT(")"); - pDb->WriteSqlLog(sqlStmt.c_str()); + pDb->WriteSqlLog(sqlStmt); #ifdef DBDEBUG_CONSOLE cout << endl << sqlStmt.c_str() << endl << endl; @@ -1384,7 +1566,7 @@ bool wxDbTable::CreateIndex(const char * idxName, bool unique, int noIdxCols, wx /********** wxDbTable::DropIndex() **********/ -bool wxDbTable::DropIndex(const char * idxName) +bool wxDbTable::DropIndex(const wxString &idxName) { // NOTE: This function returns TRUE if the Index does not exist, but // only for identified databases. Code will need to be added @@ -1394,14 +1576,14 @@ bool wxDbTable::DropIndex(const char * idxName) wxString sqlStmt; if (pDb->Dbms() == dbmsACCESS || pDb->Dbms() == dbmsMY_SQL) - sqlStmt.sprintf("DROP INDEX %s ON %s",idxName,tableName); + sqlStmt.Printf(wxT("DROP INDEX %s ON %s"),idxName,tableName); else if ((pDb->Dbms() == dbmsMS_SQL_SERVER) || (pDb->Dbms() == dbmsSYBASE_ASE)) - sqlStmt.sprintf("DROP INDEX %s.%s",tableName,idxName); + sqlStmt.Printf(wxT("DROP INDEX %s.%s"),tableName,idxName); else - sqlStmt.sprintf("DROP INDEX %s",idxName); + sqlStmt.Printf(wxT("DROP INDEX %s"),idxName); - pDb->WriteSqlLog(sqlStmt.c_str()); + pDb->WriteSqlLog(sqlStmt); #ifdef DBDEBUG_CONSOLE cout << endl << sqlStmt.c_str() << endl; @@ -1411,15 +1593,15 @@ bool wxDbTable::DropIndex(const char * idxName) { // Check for "Index not found" error and ignore pDb->GetNextError(henv, hdbc, hstmt); - if (wxStrcmp(pDb->sqlState,"S0012")) // "Index not found" + if (wxStrcmp(pDb->sqlState,wxT("S0012"))) // "Index not found" { // Check for product specific error codes - if (!((pDb->Dbms() == dbmsSYBASE_ASA && !wxStrcmp(pDb->sqlState,"42000")) || // v5.x (and lower?) - (pDb->Dbms() == dbmsSYBASE_ASE && !wxStrcmp(pDb->sqlState,"37000")) || - (pDb->Dbms() == dbmsMS_SQL_SERVER && !wxStrcmp(pDb->sqlState,"S1000")) || - (pDb->Dbms() == dbmsSYBASE_ASE && !wxStrcmp(pDb->sqlState,"S0002")) || // Base table not found - (pDb->Dbms() == dbmsMY_SQL && !wxStrcmp(pDb->sqlState,"42S12")) || // tested by Christopher Ludwik Marino-Cebulski using v3.23.21beta - (pDb->Dbms() == dbmsPOSTGRES && !wxStrcmp(pDb->sqlState,"08S01")) + if (!((pDb->Dbms() == dbmsSYBASE_ASA && !wxStrcmp(pDb->sqlState,wxT("42000"))) || // v5.x (and lower?) + (pDb->Dbms() == dbmsSYBASE_ASE && !wxStrcmp(pDb->sqlState,wxT("37000"))) || + (pDb->Dbms() == dbmsMS_SQL_SERVER && !wxStrcmp(pDb->sqlState,wxT("S1000"))) || + (pDb->Dbms() == dbmsSYBASE_ASE && !wxStrcmp(pDb->sqlState,wxT("S0002"))) || // Base table not found + (pDb->Dbms() == dbmsMY_SQL && !wxStrcmp(pDb->sqlState,wxT("42S12"))) || // tested by Christopher Ludwik Marino-Cebulski using v3.23.21beta + (pDb->Dbms() == dbmsPOSTGRES && !wxStrcmp(pDb->sqlState,wxT("08S01"))) )) { pDb->DispNextError(); @@ -1464,14 +1646,14 @@ bool wxDbTable::SetOrderByColNums(int first, ... ) } if (colNo != first) - tempStr += ","; + tempStr += wxT(","); tempStr += colDefs[colNo].ColName; colNo = va_arg (argptr, int); } va_end (argptr); /* Reset variable arguments. */ - SetOrderByClause(tempStr.c_str()); + SetOrderByClause(tempStr); return (!abort); } // wxDbTable::SetOrderByColNums() @@ -1480,7 +1662,7 @@ bool wxDbTable::SetOrderByColNums(int first, ... ) /********** wxDbTable::Insert() **********/ int wxDbTable::Insert(void) { - assert(!queryOnly); + wxASSERT(!queryOnly); if (queryOnly || !insertable) return(DB_FAILURE); @@ -1493,7 +1675,7 @@ int wxDbTable::Insert(void) { // Check to see if integrity constraint was violated pDb->GetNextError(henv, hdbc, hstmtInsert); - if (! wxStrcmp(pDb->sqlState, "23000")) // Integrity constraint violated + if (! wxStrcmp(pDb->sqlState, wxT("23000"))) // Integrity constraint violated return(DB_ERR_INTEGRITY_CONSTRAINT_VIOL); else { @@ -1512,11 +1694,11 @@ int wxDbTable::Insert(void) /********** wxDbTable::Update() **********/ bool wxDbTable::Update(void) { - assert(!queryOnly); + wxASSERT(!queryOnly); if (queryOnly) return(FALSE); - char sqlStmt[DB_MAX_STATEMENT_LEN]; + wxString sqlStmt; // Build the SQL UPDATE statement BuildUpdateStmt(sqlStmt, DB_UPD_KEYFIELDS); @@ -1524,7 +1706,7 @@ bool wxDbTable::Update(void) pDb->WriteSqlLog(sqlStmt); #ifdef DBDEBUG_CONSOLE - cout << endl << sqlStmt << endl << endl; + cout << endl << sqlStmt.c_str() << endl << endl; #endif // Execute the SQL UPDATE statement @@ -1534,9 +1716,9 @@ bool wxDbTable::Update(void) /********** wxDbTable::Update(pSqlStmt) **********/ -bool wxDbTable::Update(const char *pSqlStmt) +bool wxDbTable::Update(const wxString &pSqlStmt) { - assert(!queryOnly); + wxASSERT(!queryOnly); if (queryOnly) return(FALSE); @@ -1548,13 +1730,13 @@ bool wxDbTable::Update(const char *pSqlStmt) /********** wxDbTable::UpdateWhere() **********/ -bool wxDbTable::UpdateWhere(const char *pWhereClause) +bool wxDbTable::UpdateWhere(const wxString &pWhereClause) { - assert(!queryOnly); + wxASSERT(!queryOnly); if (queryOnly) return(FALSE); - char sqlStmt[DB_MAX_STATEMENT_LEN]; + wxString sqlStmt; // Build the SQL UPDATE statement BuildUpdateStmt(sqlStmt, DB_UPD_WHERE, pWhereClause); @@ -1562,7 +1744,7 @@ bool wxDbTable::UpdateWhere(const char *pWhereClause) pDb->WriteSqlLog(sqlStmt); #ifdef DBDEBUG_CONSOLE - cout << endl << sqlStmt << endl << endl; + cout << endl << sqlStmt.c_str() << endl << endl; #endif // Execute the SQL UPDATE statement @@ -1574,11 +1756,12 @@ bool wxDbTable::UpdateWhere(const char *pWhereClause) /********** wxDbTable::Delete() **********/ bool wxDbTable::Delete(void) { - assert(!queryOnly); + wxASSERT(!queryOnly); if (queryOnly) return(FALSE); - char sqlStmt[DB_MAX_STATEMENT_LEN]; + wxString sqlStmt; + sqlStmt.Empty(); // Build the SQL DELETE statement BuildDeleteStmt(sqlStmt, DB_DEL_KEYFIELDS); @@ -1592,13 +1775,14 @@ bool wxDbTable::Delete(void) /********** wxDbTable::DeleteWhere() **********/ -bool wxDbTable::DeleteWhere(const char *pWhereClause) +bool wxDbTable::DeleteWhere(const wxString &pWhereClause) { - assert(!queryOnly); + wxASSERT(!queryOnly); if (queryOnly) return(FALSE); - char sqlStmt[DB_MAX_STATEMENT_LEN]; + wxString sqlStmt; + sqlStmt.Empty(); // Build the SQL DELETE statement BuildDeleteStmt(sqlStmt, DB_DEL_WHERE, pWhereClause); @@ -1614,11 +1798,12 @@ bool wxDbTable::DeleteWhere(const char *pWhereClause) /********** wxDbTable::DeleteMatching() **********/ bool wxDbTable::DeleteMatching(void) { - assert(!queryOnly); + wxASSERT(!queryOnly); if (queryOnly) return(FALSE); - char sqlStmt[DB_MAX_STATEMENT_LEN]; + wxString sqlStmt; + sqlStmt.Empty(); // Build the SQL DELETE statement BuildDeleteStmt(sqlStmt, DB_DEL_MATCHING); @@ -1631,200 +1816,6 @@ bool wxDbTable::DeleteMatching(void) } // wxDbTable::DeleteMatching() -/********** wxDbTable::BuildUpdateStmt() **********/ -void wxDbTable::BuildUpdateStmt(char *pSqlStmt, int typeOfUpd, const char *pWhereClause) -{ - assert(!queryOnly); - if (queryOnly) - return; - - char whereClause[DB_MAX_WHERE_CLAUSE_LEN]; - bool firstColumn = TRUE; - - whereClause[0] = 0; - sprintf(pSqlStmt, "UPDATE %s SET ", tableName); - - // Append a list of columns to be updated - int i; - for (i = 0; i < noCols; i++) - { - // Only append Updateable columns - if (colDefs[i].Updateable) - { - if (! firstColumn) - wxStrcat(pSqlStmt, ","); - else - firstColumn = FALSE; - wxStrcat(pSqlStmt, colDefs[i].ColName); - wxStrcat(pSqlStmt, " = ?"); - } - } - - // Append the WHERE clause to the SQL UPDATE statement - wxStrcat(pSqlStmt, " WHERE "); - switch(typeOfUpd) - { - case DB_UPD_KEYFIELDS: - // If the datasource supports the ROWID column, build - // the where on ROWID for efficiency purposes. - // e.g. UPDATE PARTS SET Col1 = ?, Col2 = ? WHERE ROWID = '111.222.333' - if (CanUpdByROWID()) - { - SDWORD cb; - char rowid[wxDB_ROWID_LEN]; - - // Get the ROWID value. If not successful retreiving the ROWID, - // simply fall down through the code and build the WHERE clause - // based on the key fields. - if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS) - { - wxStrcat(pSqlStmt, "ROWID = '"); - wxStrcat(pSqlStmt, rowid); - wxStrcat(pSqlStmt, "'"); - break; - } - } - // Unable to delete by ROWID, so build a WHERE - // clause based on the keyfields. - BuildWhereClause(whereClause, DB_WHERE_KEYFIELDS); - wxStrcat(pSqlStmt, whereClause); - break; - case DB_UPD_WHERE: - wxStrcat(pSqlStmt, pWhereClause); - break; - } -} // BuildUpdateStmt() - - -/********** wxDbTable::BuildDeleteStmt() **********/ -void wxDbTable::BuildDeleteStmt(char *pSqlStmt, int typeOfDel, const char *pWhereClause) -{ - assert(!queryOnly); - if (queryOnly) - return; - - char whereClause[DB_MAX_WHERE_CLAUSE_LEN]; - - whereClause[0] = 0; - - // Handle the case of DeleteWhere() and the where clause is blank. It should - // delete all records from the database in this case. - if (typeOfDel == DB_DEL_WHERE && (pWhereClause == 0 || wxStrlen(pWhereClause) == 0)) - { - sprintf(pSqlStmt, "DELETE FROM %s", tableName); - return; - } - - sprintf(pSqlStmt, "DELETE FROM %s WHERE ", tableName); - - // Append the WHERE clause to the SQL DELETE statement - switch(typeOfDel) - { - case DB_DEL_KEYFIELDS: - // If the datasource supports the ROWID column, build - // the where on ROWID for efficiency purposes. - // e.g. DELETE FROM PARTS WHERE ROWID = '111.222.333' - if (CanUpdByROWID()) - { - SDWORD cb; - char rowid[wxDB_ROWID_LEN]; - - // Get the ROWID value. If not successful retreiving the ROWID, - // simply fall down through the code and build the WHERE clause - // based on the key fields. - if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS) - { - wxStrcat(pSqlStmt, "ROWID = '"); - wxStrcat(pSqlStmt, rowid); - wxStrcat(pSqlStmt, "'"); - break; - } - } - // Unable to delete by ROWID, so build a WHERE - // clause based on the keyfields. - BuildWhereClause(whereClause, DB_WHERE_KEYFIELDS); - wxStrcat(pSqlStmt, whereClause); - break; - case DB_DEL_WHERE: - wxStrcat(pSqlStmt, pWhereClause); - break; - case DB_DEL_MATCHING: - BuildWhereClause(whereClause, DB_WHERE_MATCHING); - wxStrcat(pSqlStmt, whereClause); - break; - } - -} // BuildDeleteStmt() - - -/********** wxDbTable::BuildWhereClause() **********/ -void wxDbTable::BuildWhereClause(char *pWhereClause, int typeOfWhere, - const char *qualTableName, bool useLikeComparison) -/* - * Note: BuildWhereClause() currently ignores timestamp columns. - * They are not included as part of the where clause. - */ -{ - bool moreThanOneColumn = FALSE; - char colValue[255]; - - // Loop through the columns building a where clause as you go - int i; - for (i = 0; i < noCols; i++) - { - // Determine if this column should be included in the WHERE clause - if ((typeOfWhere == DB_WHERE_KEYFIELDS && colDefs[i].KeyField) || - (typeOfWhere == DB_WHERE_MATCHING && (!IsColNull(i)))) - { - // Skip over timestamp columns - if (colDefs[i].SqlCtype == SQL_C_TIMESTAMP) - continue; - // If there is more than 1 column, join them with the keyword "AND" - if (moreThanOneColumn) - wxStrcat(pWhereClause, " AND "); - else - moreThanOneColumn = TRUE; - // Concatenate where phrase for the column - if (qualTableName && wxStrlen(qualTableName)) - { - wxStrcat(pWhereClause, qualTableName); - wxStrcat(pWhereClause, "."); - } - wxStrcat(pWhereClause, colDefs[i].ColName); - if (useLikeComparison && (colDefs[i].SqlCtype == SQL_C_CHAR)) - wxStrcat(pWhereClause, " LIKE "); - else - wxStrcat(pWhereClause, " = "); - switch(colDefs[i].SqlCtype) - { - case SQL_C_CHAR: - sprintf(colValue, "'%s'", (UCHAR FAR *) colDefs[i].PtrDataObj); - break; - case SQL_C_SSHORT: - sprintf(colValue, "%hi", *((SWORD *) colDefs[i].PtrDataObj)); - break; - case SQL_C_USHORT: - sprintf(colValue, "%hu", *((UWORD *) colDefs[i].PtrDataObj)); - break; - case SQL_C_SLONG: - sprintf(colValue, "%li", *((SDWORD *) colDefs[i].PtrDataObj)); - break; - case SQL_C_ULONG: - sprintf(colValue, "%lu", *((UDWORD *) colDefs[i].PtrDataObj)); - break; - case SQL_C_FLOAT: - sprintf(colValue, "%.6f", *((SFLOAT *) colDefs[i].PtrDataObj)); - break; - case SQL_C_DOUBLE: - sprintf(colValue, "%.6f", *((SDOUBLE *) colDefs[i].PtrDataObj)); - break; - } - wxStrcat(pWhereClause, colValue); - } - } -} // wxDbTable::BuildWhereClause() - - /********** wxDbTable::IsColNull() **********/ bool wxDbTable::IsColNull(int colNo) { @@ -1913,7 +1904,7 @@ bool wxDbTable::IsCursorClosedOnCommit(void) /********** wxDbTable::ClearMemberVar() **********/ void wxDbTable::ClearMemberVar(int colNo, bool setToNull) { - assert(colNo < noCols); + wxASSERT(colNo < noCols); switch(colDefs[colNo].SqlCtype) { @@ -1987,14 +1978,14 @@ bool wxDbTable::SetQueryTimeout(UDWORD nSeconds) /********** wxDbTable::SetColDefs() **********/ -void wxDbTable::SetColDefs(int index, const char *fieldName, int dataType, void *pData, +void wxDbTable::SetColDefs(int index, const wxString &fieldName, int dataType, void *pData, int cType, int size, bool keyField, bool upd, bool insAllow, bool derivedCol) { if (!colDefs) // May happen if the database connection fails return; - if (wxStrlen(fieldName) > (unsigned int) DB_MAX_COLUMN_NAME_LEN) + if (fieldName.Length() > (unsigned int) DB_MAX_COLUMN_NAME_LEN) { wxStrncpy (colDefs[index].ColName, fieldName, DB_MAX_COLUMN_NAME_LEN); colDefs[index].ColName[DB_MAX_COLUMN_NAME_LEN] = 0; @@ -2028,7 +2019,7 @@ void wxDbTable::SetColDefs(int index, const char *fieldName, int dataType, void /********** wxDbTable::SetColDefs() **********/ wxDbColDataPtr* wxDbTable::SetColDefs(wxDbColInf *pColInfs, ULONG numCols) { - assert(pColInfs); + wxASSERT(pColInfs); wxDbColDataPtr *pColDataPtrs = NULL; if (pColInfs) @@ -2043,7 +2034,7 @@ wxDbColDataPtr* wxDbTable::SetColDefs(wxDbColInf *pColInfs, ULONG numCols) switch (pColInfs[index].dbDataType) { case DB_DATA_TYPE_VARCHAR: - pColDataPtrs[index].PtrDataObj = new char[pColInfs[index].bufferLength+1]; + pColDataPtrs[index].PtrDataObj = new wxChar[pColInfs[index].bufferLength+1]; pColDataPtrs[index].SzDataObj = pColInfs[index].columnSize; pColDataPtrs[index].SqlCtype = SQL_C_CHAR; break; @@ -2103,17 +2094,17 @@ void wxDbTable::SetCursor(HSTMT *hstmtActivate) } // wxDbTable::SetCursor() -/********** wxDbTable::Count(const char *) **********/ -ULONG wxDbTable::Count(const char *args) +/********** wxDbTable::Count(const wxString &) **********/ +ULONG wxDbTable::Count(const wxString &args) { ULONG count; wxString sqlStmt; SDWORD cb; // Build a "SELECT COUNT(*) FROM queryTableName [WHERE whereClause]" SQL Statement - sqlStmt = "SELECT COUNT("; + sqlStmt = wxT("SELECT COUNT("); sqlStmt += args; - sqlStmt += ") FROM "; + sqlStmt += wxT(") FROM "); sqlStmt += queryTableName; #if wxODBC_BACKWARD_COMPATABILITY if (from && wxStrlen(from)) @@ -2129,17 +2120,17 @@ ULONG wxDbTable::Count(const char *args) if (where.Length()) #endif { - sqlStmt += " WHERE "; + sqlStmt += wxT(" WHERE "); sqlStmt += where; } - pDb->WriteSqlLog(sqlStmt.c_str()); + pDb->WriteSqlLog(sqlStmt); // Initialize the Count cursor if it's not already initialized if (!hstmtCount) { hstmtCount = GetNewCursor(FALSE,FALSE); - assert(hstmtCount); + wxASSERT(hstmtCount); if (!hstmtCount) return(0); } @@ -2193,22 +2184,23 @@ bool wxDbTable::Refresh(void) #endif // Build a where clause to refetch the record with. Try and use the // ROWID if it's available, ow use the key fields. - char whereClause[DB_MAX_WHERE_CLAUSE_LEN+1]; - wxStrcpy(whereClause, ""); + wxString whereClause; + whereClause.Empty(); + if (CanUpdByROWID()) { SDWORD cb; - char rowid[wxDB_ROWID_LEN+1]; + wxChar rowid[wxDB_ROWID_LEN+1]; // Get the ROWID value. If not successful retreiving the ROWID, // simply fall down through the code and build the WHERE clause // based on the key fields. if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS) { - wxStrcat(whereClause, queryTableName); - wxStrcat(whereClause, ".ROWID = '"); - wxStrcat(whereClause, rowid); - wxStrcat(whereClause, "'"); + whereClause += queryTableName; + whereClause += wxT(".ROWID = '"); + whereClause += rowid; + whereClause += wxT("'"); } } @@ -2218,7 +2210,7 @@ bool wxDbTable::Refresh(void) // Requery the record where = whereClause; - orderBy = ""; + orderBy.Empty(); if (!Query()) result = FALSE; @@ -2254,11 +2246,11 @@ bool wxDbTable::SetColNull(int colNo, bool set) else return(FALSE); -} // wxDbTable::SetColNull(int colNo) +} // wxDbTable::SetColNull() -/********** wxDbTable::SetColNull(char *colName, bool set) **********/ -bool wxDbTable::SetColNull(const char *colName, bool set) +/********** wxDbTable::SetColNull(const wxString &colName, bool set) **********/ +bool wxDbTable::SetColNull(const wxString &colName, bool set) { int i; for (i = 0; i < noCols; i++) @@ -2277,14 +2269,14 @@ bool wxDbTable::SetColNull(const char *colName, bool set) else return(FALSE); -} // wxDbTable::SetColNull(char *colName) +} // wxDbTable::SetColNull() /********** wxDbTable::GetNewCursor() **********/ HSTMT *wxDbTable::GetNewCursor(bool setCursor, bool bindColumns) { HSTMT *newHSTMT = new HSTMT; - assert(newHSTMT); + wxASSERT(newHSTMT); if (!newHSTMT) return(0);