X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d171743ed3ddbf0178a9d68cf78999a3ca999826..121fa06ab6af9129e776af13949fc251a3cafc49:/src/common/dbtable.cpp diff --git a/src/common/dbtable.cpp b/src/common/dbtable.cpp index c25f9dc853..e56bedcc25 100644 --- a/src/common/dbtable.cpp +++ b/src/common/dbtable.cpp @@ -8,23 +8,15 @@ // Created: 9.96 // 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, -// modification, enhancement, debugging under the following conditions: -// 1) These classes may only be used as part of the implementation of a -// wxWindows-based application -// 2) All enhancements and bug fixes are to be submitted back to the wxWindows -// user groups free of all charges for use with the wxWindows library. -// 3) These classes may not be distributed as part of any other class library, -// DLL, text (written or electronic), other than a complete distribution of -// the wxWindows GUI development toolkit. +// Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// /* // SYNOPSIS START // SYNOPSIS STOP */ -#ifdef __GNUG__ + +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "dbtable.h" #endif @@ -48,9 +40,6 @@ #include "wx/object.h" #include "wx/list.h" #include "wx/utils.h" - #if wxUSE_GUI - #include "wx/msgdlg.h" - #endif #include "wx/log.h" #endif #include "wx/filefn.h" @@ -60,7 +49,6 @@ #include #include #include -//#include #include "wx/dbtable.h" @@ -83,6 +71,16 @@ ULONG lastTableID = 0; #endif +void csstrncpyt(wxChar *target, const wxChar *source, int n) +{ + while ( (*target++ = *source++) != '\0' && --n ) + ; + + *target = '\0'; +} + + + /********** wxDbColDef::wxDbColDef() Constructor **********/ wxDbColDef::wxDbColDef() { @@ -97,14 +95,14 @@ bool wxDbColDef::Initialize() SqlCtype = SQL_C_LONG; PtrDataObj = NULL; SzDataObj = 0; - KeyField = FALSE; - Updateable = FALSE; - InsertAllowed = FALSE; - DerivedCol = FALSE; + KeyField = false; + Updateable = false; + InsertAllowed = false; + DerivedCol = false; CbValue = 0; - Null = FALSE; + Null = false; - return TRUE; + return true; } // wxDbColDef::Initialize() @@ -156,9 +154,9 @@ bool wxDbTable::initialize(wxDb *pwxDb, const wxString &tblName, const UWORD num 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 + selectForUpdate = false; // SELECT ... FOR UPDATE; Indicates whether to include the FOR UPDATE phrase queryOnly = qryOnly; - insertable = TRUE; + insertable = true; tablePath.Empty(); tableName.Empty(); queryTableName.Empty(); @@ -167,7 +165,7 @@ bool wxDbTable::initialize(wxDb *pwxDb, const wxString &tblName, const UWORD num wxASSERT(pDb); if (!pDb) - return FALSE; + return false; tableName = tblName; // Table Name if (tblPath.Length()) @@ -264,7 +262,7 @@ bool wxDbTable::initialize(wxDb *pwxDb, const wxString &tblName, const UWORD num { // Should never happen pDb->GetNextError(henv, hdbc, hstmtInternal); - return FALSE; + return false; } } } @@ -293,11 +291,11 @@ bool wxDbTable::initialize(wxDb *pwxDb, const wxString &tblName, const UWORD num } // Make the default cursor the active cursor - hstmtDefault = GetNewCursor(FALSE,FALSE); + hstmtDefault = GetNewCursor(false,false); wxASSERT(hstmtDefault); hstmt = *hstmtDefault; - return TRUE; + return true; } // wxDbTable::initialize() @@ -314,21 +312,20 @@ void wxDbTable::cleanup() #ifdef __WXDEBUG__ if (tableID) { - TablesInUse.DeleteContents(TRUE); - bool found = FALSE; + bool found = false; - wxNode *pNode; - pNode = TablesInUse.First(); + wxList::compatibility_iterator pNode; + pNode = TablesInUse.GetFirst(); while (pNode && !found) { - if (((wxTablesInUse *)pNode->Data())->tableID == tableID) + if (((wxTablesInUse *)pNode->GetData())->tableID == tableID) { - found = TRUE; - if (!TablesInUse.DeleteNode(pNode)) - wxLogDebug (s,wxT("Unable to delete node!")); + found = true; + delete (wxTablesInUse *)pNode->GetData(); + TablesInUse.Erase(pNode); } else - pNode = pNode->Next(); + pNode = pNode->GetNext(); } if (!found) { @@ -403,12 +400,52 @@ ODBC 3.0 says to use this form /***************************** PRIVATE FUNCTIONS *****************************/ +void wxDbTable::setCbValueForColumn(int columnIndex) +{ + switch(colDefs[columnIndex].DbDataType) + { + case DB_DATA_TYPE_VARCHAR: + if (colDefs[columnIndex].Null) + colDefs[columnIndex].CbValue = SQL_NULL_DATA; + else + colDefs[columnIndex].CbValue = SQL_NTS; + break; + case DB_DATA_TYPE_INTEGER: + if (colDefs[columnIndex].Null) + colDefs[columnIndex].CbValue = SQL_NULL_DATA; + else + colDefs[columnIndex].CbValue = 0; + break; + case DB_DATA_TYPE_FLOAT: + if (colDefs[columnIndex].Null) + colDefs[columnIndex].CbValue = SQL_NULL_DATA; + else + colDefs[columnIndex].CbValue = 0; + break; + case DB_DATA_TYPE_DATE: + if (colDefs[columnIndex].Null) + colDefs[columnIndex].CbValue = SQL_NULL_DATA; + else + colDefs[columnIndex].CbValue = 0; + break; + case DB_DATA_TYPE_BLOB: + if (colDefs[columnIndex].Null) + colDefs[columnIndex].CbValue = SQL_NULL_DATA; + else + if (colDefs[columnIndex].SqlCtype == SQL_C_CHAR) + colDefs[columnIndex].CbValue = SQL_NTS; + else + colDefs[columnIndex].CbValue = SQL_LEN_DATA_AT_EXEC(colDefs[columnIndex].SzDataObj); + break; + } +} + /********** wxDbTable::bindParams() **********/ bool wxDbTable::bindParams(bool forUpdate) { wxASSERT(!queryOnly); if (queryOnly) - return(FALSE); + return false; SWORD fSqlType = 0; SDWORD precision = 0; @@ -438,19 +475,11 @@ bool wxDbTable::bindParams(bool forUpdate) 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; @@ -461,30 +490,21 @@ bool wxDbTable::bindParams(bool forUpdate) // 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; case DB_DATA_TYPE_BLOB: fSqlType = pDb->GetTypeInfBlob().FsqlType; - precision = -1; + precision = colDefs[i].SzDataObj; scale = 0; - if (colDefs[i].Null) - colDefs[i].CbValue = SQL_NULL_DATA; - else - colDefs[i].CbValue = SQL_LEN_DATA_AT_EXEC(colDefs[i].SzDataObj); break; } + + setCbValueForColumn(i); + if (forUpdate) { if (SQLBindParameter(hstmtUpdate, colNo++, SQL_PARAM_INPUT, colDefs[i].SqlCtype, @@ -498,7 +518,7 @@ bool wxDbTable::bindParams(bool forUpdate) { if (SQLBindParameter(hstmtInsert, colNo++, SQL_PARAM_INPUT, colDefs[i].SqlCtype, fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, - precision+1,&colDefs[i].CbValue) != SQL_SUCCESS) + precision+1, &colDefs[i].CbValue) != SQL_SUCCESS) { return(pDb->DispAllErrors(henv, hdbc, hstmtInsert)); } @@ -506,7 +526,7 @@ bool wxDbTable::bindParams(bool forUpdate) } // Completed successfully - return(TRUE); + return true; } // wxDbTable::bindParams() @@ -514,14 +534,14 @@ bool wxDbTable::bindParams(bool forUpdate) /********** wxDbTable::bindInsertParams() **********/ bool wxDbTable::bindInsertParams(void) { - return bindParams(FALSE); + return bindParams(false); } // wxDbTable::bindInsertParams() /********** wxDbTable::bindUpdateParams() **********/ bool wxDbTable::bindUpdateParams(void) { - return bindParams(TRUE); + return bindParams(true); } // wxDbTable::bindUpdateParams() @@ -541,7 +561,7 @@ bool wxDbTable::bindCols(HSTMT cursor) } // Completed successfully - return(TRUE); + return true; } // wxDbTable::bindCols() @@ -561,7 +581,7 @@ bool wxDbTable::getRec(UWORD fetchType) if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { if (retcode == SQL_NO_DATA_FOUND) - return(FALSE); + return false; else return(pDb->DispAllErrors(henv, hdbc, hstmt)); } @@ -581,7 +601,7 @@ bool wxDbTable::getRec(UWORD fetchType) if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { if (retcode == SQL_NO_DATA_FOUND) - return(FALSE); + return false; else return(pDb->DispAllErrors(henv, hdbc, hstmt)); } @@ -596,7 +616,7 @@ bool wxDbTable::getRec(UWORD fetchType) } // Completed successfully - return(TRUE); + return true; } // wxDbTable::getRec() @@ -607,14 +627,14 @@ bool wxDbTable::execDelete(const wxString &pSqlStmt) RETCODE retcode; // Execute the DELETE statement - retcode = SQLExecDirect(hstmtDelete, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS); + retcode = SQLExecDirect(hstmtDelete, (SQLTCHAR FAR *) pSqlStmt.c_str(), SQL_NTS); if (retcode == SQL_SUCCESS || retcode == SQL_NO_DATA_FOUND || retcode == SQL_SUCCESS_WITH_INFO) { // Record deleted successfully - return(TRUE); + return true; } // Problem deleting record @@ -629,19 +649,20 @@ bool wxDbTable::execUpdate(const wxString &pSqlStmt) RETCODE retcode; // Execute the UPDATE statement - retcode = SQLExecDirect(hstmtUpdate, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS); + retcode = SQLExecDirect(hstmtUpdate, (SQLTCHAR FAR *) pSqlStmt.c_str(), SQL_NTS); if (retcode == SQL_SUCCESS || retcode == SQL_NO_DATA_FOUND || retcode == SQL_SUCCESS_WITH_INFO) { // Record updated successfully - return(TRUE); + return true; } else if (retcode == SQL_NEED_DATA) { PTR pParmID; - while ((retcode = SQLParamData(hstmtUpdate, &pParmID) == SQL_NEED_DATA)) + retcode = SQLParamData(hstmtUpdate, &pParmID); + while (retcode == SQL_NEED_DATA) { // Find the parameter int i; @@ -659,13 +680,14 @@ bool wxDbTable::execUpdate(const wxString &pSqlStmt) break; } } + retcode = SQLParamData(hstmtUpdate, &pParmID); } if (retcode == SQL_SUCCESS || retcode == SQL_NO_DATA_FOUND || retcode == SQL_SUCCESS_WITH_INFO) { // Record updated successfully - return(TRUE); + return true; } } @@ -684,7 +706,7 @@ bool wxDbTable::query(int queryType, bool forUpdate, bool distinct, const wxStri // The user may wish to select for update, but the DBMS may not be capable selectForUpdate = CanSelectForUpdate(); else - selectForUpdate = FALSE; + selectForUpdate = false; // Set the SQL SELECT string if (queryType != DB_SELECT_STATEMENT) // A select statement was not passed in, @@ -695,16 +717,16 @@ bool wxDbTable::query(int queryType, bool forUpdate, bool distinct, const wxStri // Make sure the cursor is closed first if (!CloseCursor(hstmt)) - return(FALSE); + return false; // Execute the SQL SELECT statement int retcode; - retcode = SQLExecDirect(hstmt, (UCHAR FAR *) (queryType == DB_SELECT_STATEMENT ? pSqlStmt.c_str() : sqlStmt.c_str()), SQL_NTS); + retcode = SQLExecDirect(hstmt, (SQLTCHAR 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)); // Completed successfully - return(TRUE); + return true; } // wxDbTable::query() @@ -716,7 +738,7 @@ bool wxDbTable::query(int queryType, bool forUpdate, bool distinct, const wxStri bool wxDbTable::Open(bool checkPrivileges, bool checkTableExists) { if (!pDb) - return FALSE; + return false; int i; wxString sqlStmt; @@ -770,7 +792,7 @@ bool wxDbTable::Open(bool checkPrivileges, bool checkTableExists) p += s; pDb->LogError(p.GetData()); - return(FALSE); + return false; } // Bind the member variables for field exchange between @@ -778,17 +800,17 @@ bool wxDbTable::Open(bool checkPrivileges, bool checkTableExists) if (!queryOnly) { if (!bindInsertParams()) // Inserts - return(FALSE); + return false; if (!bindUpdateParams()) // Updates - return(FALSE); + return false; } if (!bindCols(*hstmtDefault)) // Selects - return(FALSE); + return false; if (!bindCols(hstmtInternal)) // Internal use only - return(FALSE); + return false; /* * Do NOT bind the hstmtCount cursor!!! @@ -797,7 +819,7 @@ bool wxDbTable::Open(bool checkPrivileges, bool checkTableExists) // Build an insert statement using parameter markers if (!queryOnly && noCols > 0) { - bool needComma = FALSE; + bool needComma = false; sqlStmt.Printf(wxT("INSERT INTO %s ("), pDb->SQLTableName(tableName.c_str()).c_str()); for (i = 0; i < noCols; i++) @@ -808,9 +830,9 @@ bool wxDbTable::Open(bool checkPrivileges, bool checkTableExists) sqlStmt += wxT(","); sqlStmt += pDb->SQLColumnName(colDefs[i].ColName); // sqlStmt += colDefs[i].ColName; - needComma = TRUE; + needComma = true; } - needComma = FALSE; + needComma = false; sqlStmt += wxT(") VALUES ("); int insertableCount = 0; @@ -822,7 +844,7 @@ bool wxDbTable::Open(bool checkPrivileges, bool checkTableExists) if (needComma) sqlStmt += wxT(","); sqlStmt += wxT("?"); - needComma = TRUE; + needComma = true; insertableCount++; } sqlStmt += wxT(")"); @@ -830,15 +852,15 @@ bool wxDbTable::Open(bool checkPrivileges, bool checkTableExists) // Prepare the insert statement for execution if (insertableCount) { - if (SQLPrepare(hstmtInsert, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) + if (SQLPrepare(hstmtInsert, (SQLTCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) return(pDb->DispAllErrors(henv, hdbc, hstmtInsert)); } else - insertable= FALSE; + insertable = false; } // Completed successfully - return(TRUE); + return true; } // wxDbTable::Open() @@ -857,7 +879,7 @@ bool wxDbTable::QueryBySqlStmt(const wxString &pSqlStmt) { pDb->WriteSqlLog(pSqlStmt); - return(query(DB_SELECT_STATEMENT, FALSE, FALSE, pSqlStmt)); + return(query(DB_SELECT_STATEMENT, false, false, pSqlStmt)); } // wxDbTable::QueryBySqlStmt() @@ -886,7 +908,7 @@ bool wxDbTable::GetPrev(void) if (pDb->FwdOnlyCursors()) { wxFAIL_MSG(wxT("GetPrev()::Backward scrolling cursors are not enabled for this instance of wxDbTable")); - return FALSE; + return false; } else return(getRec(SQL_FETCH_PRIOR)); @@ -900,7 +922,7 @@ bool wxDbTable::operator--(int) if (pDb->FwdOnlyCursors()) { wxFAIL_MSG(wxT("operator--:Backward scrolling cursors are not enabled for this instance of wxDbTable")); - return FALSE; + return false; } else return(getRec(SQL_FETCH_PRIOR)); @@ -914,7 +936,7 @@ bool wxDbTable::GetFirst(void) if (pDb->FwdOnlyCursors()) { wxFAIL_MSG(wxT("GetFirst():Backward scrolling cursors are not enabled for this instance of wxDbTable")); - return FALSE; + return false; } else return(getRec(SQL_FETCH_FIRST)); @@ -928,7 +950,7 @@ bool wxDbTable::GetLast(void) if (pDb->FwdOnlyCursors()) { wxFAIL_MSG(wxT("GetLast()::Backward scrolling cursors are not enabled for this instance of wxDbTable")); - return FALSE; + return false; } else return(getRec(SQL_FETCH_LAST)); @@ -1023,28 +1045,28 @@ void wxDbTable::BuildSelectStmt(wxString &pSqlStmt, int typeOfSelect, bool disti // Was a FROM clause specified to join tables to the base table? // Available for ::Query() only!!! - bool appendFromClause = FALSE; + bool appendFromClause = false; #if wxODBC_BACKWARD_COMPATABILITY if (typeOfSelect == DB_SELECT_WHERE && from && wxStrlen(from)) - appendFromClause = TRUE; + appendFromClause = true; #else if (typeOfSelect == DB_SELECT_WHERE && from.Length()) - appendFromClause = TRUE; + appendFromClause = true; #endif // Add the column list int i; + wxString tStr; for (i = 0; i < noCols; i++) { + tStr = colDefs[i].ColName; // If joining tables, the base table column names must be qualified to avoid ambiguity - if (appendFromClause || pDb->Dbms() == dbmsACCESS) + if ((appendFromClause || pDb->Dbms() == dbmsACCESS) && tStr.Find(wxT('.')) == wxNOT_FOUND) { pSqlStmt += pDb->SQLTableName(queryTableName.c_str()); -// pSqlStmt += queryTableName; pSqlStmt += wxT("."); } pSqlStmt += pDb->SQLColumnName(colDefs[i].ColName); -// pSqlStmt += colDefs[i].ColName; if (i + 1 < noCols) pSqlStmt += wxT(","); } @@ -1153,7 +1175,7 @@ void wxDbTable::BuildUpdateStmt(wxString &pSqlStmt, int typeOfUpd, const wxStrin wxString whereClause; whereClause.Empty(); - bool firstColumn = TRUE; + bool firstColumn = true; pSqlStmt.Printf(wxT("UPDATE %s SET "), pDb->SQLTableName(tableName.c_str()).c_str()); @@ -1168,7 +1190,7 @@ void wxDbTable::BuildUpdateStmt(wxString &pSqlStmt, int typeOfUpd, const wxStrin if (!firstColumn) pSqlStmt += wxT(","); else - firstColumn = FALSE; + firstColumn = false; pSqlStmt += pDb->SQLColumnName(colDefs[i].ColName); // pSqlStmt += colDefs[i].ColName; @@ -1229,60 +1251,73 @@ void wxDbTable::BuildWhereClause(wxString &pWhereClause, int typeOfWhere, * They are not included as part of the where clause. */ { - bool moreThanOneColumn = FALSE; + bool moreThanOneColumn = false; wxString colValue; // Loop through the columns building a where clause as you go - int i; - for (i = 0; i < noCols; i++) + int colNo; + for (colNo = 0; colNo < noCols; colNo++) { // 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)))) + if ((typeOfWhere == DB_WHERE_KEYFIELDS && colDefs[colNo].KeyField) || + (typeOfWhere == DB_WHERE_MATCHING && (!IsColNull(colNo)))) { // Skip over timestamp columns - if (colDefs[i].SqlCtype == SQL_C_TIMESTAMP) + if (colDefs[colNo].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; + moreThanOneColumn = true; + // Concatenate where phrase for the column - if (qualTableName.Length()) + wxString tStr = colDefs[colNo].ColName; + + if (qualTableName.Length() && tStr.Find(wxT('.')) == wxNOT_FOUND) { pWhereClause += pDb->SQLTableName(qualTableName); -// pWhereClause += qualTableName; pWhereClause += wxT("."); } - pWhereClause += pDb->SQLColumnName(colDefs[i].ColName); -// pWhereClause += colDefs[i].ColName; - if (useLikeComparison && (colDefs[i].SqlCtype == SQL_C_CHAR)) + pWhereClause += pDb->SQLColumnName(colDefs[colNo].ColName); + + if (useLikeComparison && (colDefs[colNo].SqlCtype == SQL_C_CHAR)) pWhereClause += wxT(" LIKE "); else pWhereClause += wxT(" = "); - switch(colDefs[i].SqlCtype) + + switch(colDefs[colNo].SqlCtype) { case SQL_C_CHAR: - colValue.Printf(wxT("'%s'"), (UCHAR FAR *) colDefs[i].PtrDataObj); + colValue.Printf(wxT("'%s'"), (UCHAR FAR *) colDefs[colNo].PtrDataObj); break; + case SQL_C_SHORT: case SQL_C_SSHORT: - colValue.Printf(wxT("%hi"), *((SWORD *) colDefs[i].PtrDataObj)); + colValue.Printf(wxT("%hi"), *((SWORD *) colDefs[colNo].PtrDataObj)); break; case SQL_C_USHORT: - colValue.Printf(wxT("%hu"), *((UWORD *) colDefs[i].PtrDataObj)); + colValue.Printf(wxT("%hu"), *((UWORD *) colDefs[colNo].PtrDataObj)); break; + case SQL_C_LONG: case SQL_C_SLONG: - colValue.Printf(wxT("%li"), *((SDWORD *) colDefs[i].PtrDataObj)); + colValue.Printf(wxT("%li"), *((SDWORD *) colDefs[colNo].PtrDataObj)); break; case SQL_C_ULONG: - colValue.Printf(wxT("%lu"), *((UDWORD *) colDefs[i].PtrDataObj)); + colValue.Printf(wxT("%lu"), *((UDWORD *) colDefs[colNo].PtrDataObj)); break; case SQL_C_FLOAT: - colValue.Printf(wxT("%.6f"), *((SFLOAT *) colDefs[i].PtrDataObj)); + colValue.Printf(wxT("%.6f"), *((SFLOAT *) colDefs[colNo].PtrDataObj)); break; case SQL_C_DOUBLE: - colValue.Printf(wxT("%.6f"), *((SDOUBLE *) colDefs[i].PtrDataObj)); + colValue.Printf(wxT("%.6f"), *((SDOUBLE *) colDefs[colNo].PtrDataObj)); + break; + default: + { + wxString strMsg; + strMsg.Printf(wxT("wxDbTable::bindParams(): Unknown column type for colDefs %d colName %s"), + colNo,colDefs[colNo].ColName); + wxFAIL_MSG(strMsg.c_str()); + } break; } pWhereClause += colValue; @@ -1325,7 +1360,7 @@ bool wxDbTable::CloseCursor(HSTMT cursor) return(pDb->DispAllErrors(henv, hdbc, cursor)); // Completed successfully - return(TRUE); + return true; } // wxDbTable::CloseCursor() @@ -1334,7 +1369,7 @@ bool wxDbTable::CloseCursor(HSTMT cursor) bool wxDbTable::CreateTable(bool attemptDrop) { if (!pDb) - return FALSE; + return false; int i, j; wxString sqlStmt; @@ -1345,7 +1380,7 @@ bool wxDbTable::CreateTable(bool attemptDrop) // Drop table first if (attemptDrop && !DropTable()) - return FALSE; + return false; // Create the table #ifdef DBDEBUG_CONSOLE @@ -1378,7 +1413,7 @@ bool wxDbTable::CreateTable(bool attemptDrop) #endif // Build a CREATE TABLE string from the colDefs structure. - bool needComma = FALSE; + bool needComma = false; sqlStmt.Printf(wxT("CREATE TABLE %s ("), pDb->SQLTableName(tableName.c_str()).c_str()); @@ -1416,7 +1451,7 @@ bool wxDbTable::CreateTable(bool attemptDrop) } // For varchars, append the size of the string if (colDefs[i].DbDataType == DB_DATA_TYPE_VARCHAR && - (pDb->Dbms() != dbmsMY_SQL || pDb->GetTypeInfVarchar().TypeName != "text"))// || + (pDb->Dbms() != dbmsMY_SQL || pDb->GetTypeInfVarchar().TypeName != _T("text")))// || // colDefs[i].DbDataType == DB_DATA_TYPE_BLOB) { wxString s; @@ -1436,7 +1471,7 @@ bool wxDbTable::CreateTable(bool attemptDrop) } } - needComma = TRUE; + needComma = true; } // If there is a primary key defined, include it in the create statement for (i = j = 0; i < noCols; i++) @@ -1447,9 +1482,8 @@ bool wxDbTable::CreateTable(bool attemptDrop) break; } } - if (j && (pDb->Dbms() != dbmsDBASE) - && (pDb->Dbms() != dbmsXBASE_SEQUITER) - ) // Found a keyfield + if ( j && (pDb->Dbms() != dbmsDBASE) + && (pDb->Dbms() != dbmsXBASE_SEQUITER) ) // Found a keyfield { switch (pDb->Dbms()) { @@ -1522,23 +1556,23 @@ bool wxDbTable::CreateTable(bool attemptDrop) #endif // Execute the CREATE TABLE statement - RETCODE retcode = SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS); + RETCODE retcode = SQLExecDirect(hstmt, (SQLTCHAR FAR *) sqlStmt.c_str(), SQL_NTS); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { pDb->DispAllErrors(henv, hdbc, hstmt); pDb->RollbackTrans(); CloseCursor(hstmt); - return(FALSE); + return false; } // Commit the transaction and close the cursor if (!pDb->CommitTrans()) - return(FALSE); + return false; if (!CloseCursor(hstmt)) - return(FALSE); + return false; // Database table created successfully - return(TRUE); + return true; } // wxDbTable::CreateTable() @@ -1546,7 +1580,7 @@ bool wxDbTable::CreateTable(bool attemptDrop) /********** wxDbTable::DropTable() **********/ bool wxDbTable::DropTable() { - // NOTE: This function returns TRUE if the Table does not exist, but + // NOTE: This function returns true if the Table does not exist, but // only for identified databases. Code will need to be added // below for any other databases when those databases are defined // to handle this situation consistently @@ -1562,7 +1596,7 @@ bool wxDbTable::DropTable() cout << endl << sqlStmt.c_str() << endl; #endif - RETCODE retcode = SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS); + RETCODE retcode = SQLExecDirect(hstmt, (SQLTCHAR FAR *) sqlStmt.c_str(), SQL_NTS); if (retcode != SQL_SUCCESS) { // Check for "Base table not found" error and ignore @@ -1580,18 +1614,18 @@ bool wxDbTable::DropTable() pDb->DispAllErrors(henv, hdbc, hstmt); pDb->RollbackTrans(); // CloseCursor(hstmt); - return(FALSE); + return false; } } } // Commit the transaction and close the cursor if (! pDb->CommitTrans()) - return(FALSE); + return false; if (! CloseCursor(hstmt)) - return(FALSE); + return false; - return(TRUE); + return true; } // wxDbTable::DropTable() @@ -1603,7 +1637,7 @@ bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, UWORD noIdxCol // Drop the index first if (attemptDrop && !DropIndex(idxName)) - return (FALSE); + return false; // MySQL (and possibly Sybase ASE?? - gt) require that any columns which are used as portions // of an index have the columns defined as "NOT NULL". During initial table creation though, @@ -1617,11 +1651,11 @@ bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, UWORD noIdxCol { wxString sqlStmt; int i; - bool ok = TRUE; + bool ok = true; for (i = 0; i < noIdxCols && ok; i++) { int j = 0; - bool found = FALSE; + bool found = false; // Find the column definition that has the ColName that matches the // index column name. We need to do this to get the DB_DATA_TYPE of // the index column, as MySQL's syntax for the ALTER column requires @@ -1629,7 +1663,7 @@ bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, UWORD noIdxCol while (!found && (j < this->noCols)) { if (wxStrcmp(colDefs[j].ColName,pIdxDefs[i].ColName) == 0) - found = TRUE; + found = true; if (!found) j++; } @@ -1642,22 +1676,25 @@ bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, UWORD noIdxCol if (!ok) { + #if 0 + // retcode is not used wxODBC_ERRORS retcode; // Oracle returns a DB_ERR_GENERAL_ERROR if the column is already // defined to be NOT NULL, but reportedly MySQL doesn't mind. // This line is just here for debug checking of the value retcode = (wxODBC_ERRORS)pDb->DB_STATUS; + #endif } } else - ok = FALSE; + ok = false; } if (ok) pDb->CommitTrans(); else { pDb->RollbackTrans(); - return(FALSE); + return false; } } @@ -1700,9 +1737,9 @@ bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, UWORD noIdxCol sqlStmt += s; } } - + // Postgres and SQL Server 7 do not support the ASC/DESC keywords for index columns - if (!((pDb->Dbms() == dbmsMS_SQL_SERVER) && (strncmp(pDb->dbInf.dbmsVer,"07",2)==0)) && + if (!((pDb->Dbms() == dbmsMS_SQL_SERVER) && (wxStrncmp(pDb->dbInf.dbmsVer,_T("07"),2)==0)) && !(pDb->Dbms() == dbmsPOSTGRES)) { if (pIdxDefs[i].Ascending) @@ -1711,7 +1748,7 @@ bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, UWORD noIdxCol sqlStmt += wxT(" DESC"); } else - wxASSERT_MSG(pIdxDefs[i].Ascending, "Datasource does not support DESCending index columns"); + wxASSERT_MSG(pIdxDefs[i].Ascending, _T("Datasource does not support DESCending index columns")); if ((i + 1) < noIdxCols) sqlStmt += wxT(","); @@ -1727,22 +1764,22 @@ bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, UWORD noIdxCol #endif // Execute the CREATE INDEX statement - if (SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) + if (SQLExecDirect(hstmt, (SQLTCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) { pDb->DispAllErrors(henv, hdbc, hstmt); pDb->RollbackTrans(); CloseCursor(hstmt); - return(FALSE); + return false; } // Commit the transaction and close the cursor if (! pDb->CommitTrans()) - return(FALSE); + return false; if (! CloseCursor(hstmt)) - return(FALSE); + return false; // Index Created Successfully - return(TRUE); + return true; } // wxDbTable::CreateIndex() @@ -1750,7 +1787,7 @@ bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, UWORD noIdxCol /********** wxDbTable::DropIndex() **********/ bool wxDbTable::DropIndex(const wxString &idxName) { - // NOTE: This function returns TRUE if the Index does not exist, but + // NOTE: This function returns true if the Index does not exist, but // only for identified databases. Code will need to be added // below for any other databases when those databases are defined // to handle this situation consistently @@ -1764,7 +1801,7 @@ bool wxDbTable::DropIndex(const wxString &idxName) pDb->SQLTableName(tableName.c_str()).c_str()); else if ((pDb->Dbms() == dbmsMS_SQL_SERVER) || (pDb->Dbms() == dbmsSYBASE_ASE) || - (pDb->Dbms() == dbmsXBASE_SEQUITER)) + (pDb->Dbms() == dbmsXBASE_SEQUITER)) sqlStmt.Printf(wxT("DROP INDEX %s.%s"), pDb->SQLTableName(tableName.c_str()).c_str(), pDb->SQLTableName(idxName.c_str()).c_str()); @@ -1778,7 +1815,7 @@ bool wxDbTable::DropIndex(const wxString &idxName) cout << endl << sqlStmt.c_str() << endl; #endif - if (SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) + if (SQLExecDirect(hstmt, (SQLTCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) { // Check for "Index not found" error and ignore pDb->GetNextError(henv, hdbc, hstmt); @@ -1798,18 +1835,18 @@ bool wxDbTable::DropIndex(const wxString &idxName) pDb->DispAllErrors(henv, hdbc, hstmt); pDb->RollbackTrans(); CloseCursor(hstmt); - return(FALSE); + return false; } } } // Commit the transaction and close the cursor if (! pDb->CommitTrans()) - return(FALSE); + return false; if (! CloseCursor(hstmt)) - return(FALSE); + return false; - return(TRUE); + return true; } // wxDbTable::DropIndex() @@ -1819,7 +1856,7 @@ bool wxDbTable::SetOrderByColNums(UWORD first, ... ) int colNo = first; // using 'int' to be able to look for wxDB_NO_MORE_COLUN_NUMBERS va_list argptr; - bool abort = FALSE; + bool abort = false; wxString tempStr; va_start(argptr, first); /* Initialize variable arguments. */ @@ -1831,7 +1868,7 @@ bool wxDbTable::SetOrderByColNums(UWORD first, ... ) // Valid columns are 0 thru noCols-1 if (colNo >= noCols || colNo < 0) { - abort = TRUE; + abort = true; continue; } @@ -1878,7 +1915,8 @@ int wxDbTable::Insert(void) if (retcode == SQL_NEED_DATA) { PTR pParmID; - while ((retcode = SQLParamData(hstmtInsert, &pParmID) == SQL_NEED_DATA)) + retcode = SQLParamData(hstmtInsert, &pParmID); + while (retcode == SQL_NEED_DATA) { // Find the parameter int i; @@ -1897,6 +1935,15 @@ int wxDbTable::Insert(void) break; } } + retcode = SQLParamData(hstmtInsert, &pParmID); + if (retcode != SQL_SUCCESS && + retcode != SQL_SUCCESS_WITH_INFO) + { + // record was not inserted + pDb->DispNextError(); + pDb->DispAllErrors(henv, hdbc, hstmtInsert); + return(DB_FAILURE); + } } } @@ -1911,7 +1958,7 @@ bool wxDbTable::Update(void) { wxASSERT(!queryOnly); if (queryOnly) - return(FALSE); + return false; wxString sqlStmt; @@ -1935,7 +1982,7 @@ bool wxDbTable::Update(const wxString &pSqlStmt) { wxASSERT(!queryOnly); if (queryOnly) - return(FALSE); + return false; pDb->WriteSqlLog(pSqlStmt); @@ -1949,7 +1996,7 @@ bool wxDbTable::UpdateWhere(const wxString &pWhereClause) { wxASSERT(!queryOnly); if (queryOnly) - return(FALSE); + return false; wxString sqlStmt; @@ -1973,7 +2020,7 @@ bool wxDbTable::Delete(void) { wxASSERT(!queryOnly); if (queryOnly) - return(FALSE); + return false; wxString sqlStmt; sqlStmt.Empty(); @@ -1994,7 +2041,7 @@ bool wxDbTable::DeleteWhere(const wxString &pWhereClause) { wxASSERT(!queryOnly); if (queryOnly) - return(FALSE); + return false; wxString sqlStmt; sqlStmt.Empty(); @@ -2015,7 +2062,7 @@ bool wxDbTable::DeleteMatching(void) { wxASSERT(!queryOnly); if (queryOnly) - return(FALSE); + return false; wxString sqlStmt; sqlStmt.Empty(); @@ -2035,7 +2082,7 @@ bool wxDbTable::DeleteMatching(void) bool wxDbTable::IsColNull(UWORD colNo) const { /* - This logic is just not right. It would indicate TRUE + This logic is just not right. It would indicate true if a numeric field were set to a value of 0. switch(colDefs[colNo].SqlCtype) @@ -2058,11 +2105,11 @@ bool wxDbTable::IsColNull(UWORD colNo) const TIMESTAMP_STRUCT *pDt; pDt = (TIMESTAMP_STRUCT *) colDefs[colNo].PtrDataObj; if (pDt->year == 0 && pDt->month == 0 && pDt->day == 0) - return(TRUE); + return true; else - return(FALSE); + return false; default: - return(TRUE); + return true; } */ return (colDefs[colNo].Null); @@ -2073,16 +2120,16 @@ bool wxDbTable::IsColNull(UWORD colNo) const bool wxDbTable::CanSelectForUpdate(void) { if (queryOnly) - return FALSE; + return false; if (pDb->Dbms() == dbmsMY_SQL) - return FALSE; + return false; if ((pDb->Dbms() == dbmsORACLE) || (pDb->dbInf.posStmts & SQL_PS_SELECT_FOR_UPDATE)) - return(TRUE); + return true; else - return(FALSE); + return false; } // wxDbTable::CanSelectForUpdate() @@ -2091,15 +2138,15 @@ bool wxDbTable::CanSelectForUpdate(void) bool wxDbTable::CanUpdByROWID(void) { /* - * NOTE: Returning FALSE for now until this can be debugged, + * NOTE: Returning false for now until this can be debugged, * as the ROWID is not getting updated correctly */ - return FALSE; + return false; /* if (pDb->Dbms() == dbmsORACLE) - return(TRUE); + return true; else - return(FALSE); + return false; */ } // wxDbTable::CanUpdByROWID() @@ -2108,9 +2155,9 @@ bool wxDbTable::CanUpdByROWID(void) bool wxDbTable::IsCursorClosedOnCommit(void) { if (pDb->dbInf.cursorCommitBehavior == SQL_CB_PRESERVE) - return(FALSE); + return false; else - return(TRUE); + return true; } // wxDbTable::IsCursorClosedOnCommit() @@ -2132,6 +2179,7 @@ void wxDbTable::ClearMemberVar(UWORD colNo, bool setToNull) case SQL_C_USHORT: *((UWORD*) colDefs[colNo].PtrDataObj) = 0; break; + case SQL_C_LONG: case SQL_C_SLONG: *((SDWORD *) colDefs[colNo].PtrDataObj) = 0; break; @@ -2187,7 +2235,7 @@ bool wxDbTable::SetQueryTimeout(UDWORD nSeconds) return(pDb->DispAllErrors(henv, hdbc, hstmtInternal)); // Completed Successfully - return(TRUE); + return true; } // wxDbTable::SetQueryTimeout() @@ -2227,8 +2275,8 @@ void wxDbTable::SetColDefs(UWORD index, const wxString &fieldName, int dataType, // Derived columns by definition would NOT be "Insertable" or "Updateable" if (derivedCol) { - colDefs[index].Updateable = FALSE; - colDefs[index].InsertAllowed = FALSE; + colDefs[index].Updateable = false; + colDefs[index].InsertAllowed = false; } else { @@ -2236,7 +2284,7 @@ void wxDbTable::SetColDefs(UWORD index, const wxString &fieldName, int dataType, colDefs[index].InsertAllowed = insAllow; } - colDefs[index].Null = FALSE; + colDefs[index].Null = false; } // wxDbTable::SetColDefs() @@ -2372,14 +2420,14 @@ ULONG wxDbTable::Count(const wxString &args) // Initialize the Count cursor if it's not already initialized if (!hstmtCount) { - hstmtCount = GetNewCursor(FALSE,FALSE); + hstmtCount = GetNewCursor(false,false); wxASSERT(hstmtCount); if (!hstmtCount) return(0); } // Execute the SQL statement - if (SQLExecDirect(*hstmtCount, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) + if (SQLExecDirect(*hstmtCount, (SQLTCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS) { pDb->DispAllErrors(henv, hdbc, *hstmtCount); return(0); @@ -2412,15 +2460,15 @@ ULONG wxDbTable::Count(const wxString &args) /********** wxDbTable::Refresh() **********/ bool wxDbTable::Refresh(void) { - bool result = TRUE; + bool result = true; // Switch to the internal cursor so any active cursors are not corrupted HSTMT currCursor = GetCursor(); hstmt = hstmtInternal; #if wxODBC_BACKWARD_COMPATABILITY // Save the where and order by clauses - char *saveWhere = where; - char *saveOrderBy = orderBy; + wxChar *saveWhere = where; + wxChar *saveOrderBy = orderBy; #else wxString saveWhere = where; wxString saveOrderBy = orderBy; @@ -2456,10 +2504,10 @@ bool wxDbTable::Refresh(void) where = whereClause; orderBy.Empty(); if (!Query()) - result = FALSE; + result = false; if (result && !GetNext()) - result = FALSE; + result = false; // Switch back to original cursor SetCursor(&currCursor); @@ -2484,11 +2532,14 @@ bool wxDbTable::SetColNull(UWORD colNo, bool set) { colDefs[colNo].Null = set; if (set) // Blank out the values in the member variable - ClearMemberVar(colNo,FALSE); // Must call with FALSE, or infinite recursion will happen - return(TRUE); + ClearMemberVar(colNo, false); // Must call with false here, or infinite recursion will happen + + setCbValueForColumn(colNo); + + return true; } else - return(FALSE); + return false; } // wxDbTable::SetColNull() @@ -2496,22 +2547,25 @@ bool wxDbTable::SetColNull(UWORD colNo, bool set) /********** wxDbTable::SetColNull() **********/ bool wxDbTable::SetColNull(const wxString &colName, bool set) { - int i; - for (i = 0; i < noCols; i++) + int colNo; + for (colNo = 0; colNo < noCols; colNo++) { - if (!wxStricmp(colName, colDefs[i].ColName)) + if (!wxStricmp(colName, colDefs[colNo].ColName)) break; } - if (i < noCols) + if (colNo < noCols) { - colDefs[i].Null = set; + colDefs[colNo].Null = set; if (set) // Blank out the values in the member variable - ClearMemberVar(i,FALSE); // Must call with FALSE, or infinite recursion will happen - return(TRUE); + ClearMemberVar(colNo,false); // Must call with false here, or infinite recursion will happen + + setCbValueForColumn(colNo); + + return true; } else - return(FALSE); + return false; } // wxDbTable::SetColNull() @@ -2558,7 +2612,7 @@ HSTMT *wxDbTable::GetNewCursor(bool setCursor, bool bindColumns) /********** wxDbTable::DeleteCursor() **********/ bool wxDbTable::DeleteCursor(HSTMT *hstmtDel) { - bool result = TRUE; + bool result = true; if (!hstmtDel) // Cursor already deleted return(result); @@ -2571,7 +2625,7 @@ ODBC 3.0 says to use this form if (SQLFreeStmt(*hstmtDel, SQL_DROP) != SQL_SUCCESS) { pDb->DispAllErrors(henv, hdbc); - result = FALSE; + result = false; } delete hstmtDel; @@ -2588,7 +2642,7 @@ void wxDbTable::SetRowMode(const rowmode_t rowmode) { if (!m_hstmtGridQuery) { - m_hstmtGridQuery = GetNewCursor(FALSE,FALSE); + m_hstmtGridQuery = GetNewCursor(false,false); if (!bindCols(*m_hstmtGridQuery)) return; } @@ -2603,7 +2657,7 @@ void wxDbTable::SetRowMode(const rowmode_t rowmode) SetCursor(hstmtDefault); break; default: - assert(0); + wxASSERT(0); } } // wxDbTable::SetRowMode() @@ -2631,10 +2685,10 @@ wxVariant wxDbTable::GetCol(const int colNo) const val = (long)(*(unsigned long *)(colDefs[colNo].PtrDataObj)); break; case SQL_C_TINYINT: - val = (long)(*(char *)(colDefs[colNo].PtrDataObj)); + val = (long)(*(wxChar *)(colDefs[colNo].PtrDataObj)); break; case SQL_C_UTINYINT: - val = (long)(*(unsigned char *)(colDefs[colNo].PtrDataObj)); + val = (long)(*(wxChar *)(colDefs[colNo].PtrDataObj)); break; case SQL_C_USHORT: val = (long)(*(UWORD *)(colDefs[colNo].PtrDataObj)); @@ -2659,14 +2713,6 @@ wxVariant wxDbTable::GetCol(const int colNo) const } // wxDbTable::GetCol() -void csstrncpyt(char *s, const char *t, int n) -{ - while ( (*s++ = *t++) != '\0' && --n ) - ; - - *s = '\0'; -} - void wxDbTable::SetCol(const int colNo, const wxVariant val) { //FIXME: Add proper wxDateTime support to wxVariant.. @@ -2682,14 +2728,14 @@ void wxDbTable::SetCol(const int colNo, const wxVariant val) { //Returns null if invalid! if (!dateval.ParseDate(val.GetString())) - SetColNull(colNo, TRUE); + SetColNull(colNo, true); } switch (colDefs[colNo].SqlCtype) { case SQL_CHAR: case SQL_VARCHAR: - csstrncpyt((char *)(colDefs[colNo].PtrDataObj), + csstrncpyt((wxChar *)(colDefs[colNo].PtrDataObj), val.GetString().c_str(), colDefs[colNo].SzDataObj-1); break; @@ -2705,10 +2751,10 @@ void wxDbTable::SetCol(const int colNo, const wxVariant val) *(unsigned long *)(colDefs[colNo].PtrDataObj) = val.GetLong(); break; case SQL_C_TINYINT: - *(char *)(colDefs[colNo].PtrDataObj) = val.GetChar(); + *(wxChar *)(colDefs[colNo].PtrDataObj) = val.GetChar(); break; case SQL_C_UTINYINT: - *(unsigned char *)(colDefs[colNo].PtrDataObj) = val.GetChar(); + *(wxChar *)(colDefs[colNo].PtrDataObj) = val.GetChar(); break; case SQL_C_USHORT: *(unsigned short *)(colDefs[colNo].PtrDataObj) = val.GetLong(); @@ -2795,7 +2841,7 @@ void wxDbTable::SetKey(const GenericKey& k) { if (colDefs[i].KeyField) { - SetColNull(i, FALSE); + SetColNull(i, false); memcpy(colDefs[i].PtrDataObj, blkptr, colDefs[i].SzDataObj); blkptr += colDefs[i].SzDataObj; }