/********** wxDbTable::wxDbTable() Constructor **********/
-wxDbTable::wxDbTable(wxDb *pwxDb, const wxString &tblName, const int nCols,
+wxDbTable::wxDbTable(wxDb *pwxDb, const wxString &tblName, const UWORD numColumns,
const wxString &qryTblName, bool qryOnly, const wxString &tblPath)
{
- if (!initialize(pwxDb, tblName, nCols, qryTblName, qryOnly, tblPath))
+ if (!initialize(pwxDb, tblName, numColumns, qryTblName, qryOnly, tblPath))
cleanup();
} // wxDbTable::wxDbTable()
/***** DEPRECATED: use wxDbTable::wxDbTable() format above *****/
-wxDbTable::wxDbTable(wxDb *pwxDb, const wxString &tblName, const int nCols,
+wxDbTable::wxDbTable(wxDb *pwxDb, const wxString &tblName, const UWORD numColumns,
const wxChar *qryTblName, bool qryOnly, const wxString &tblPath)
{
wxString tempQryTblName;
tempQryTblName = qryTblName;
- if (!initialize(pwxDb, tblName, nCols, tempQryTblName, qryOnly, tblPath))
+ if (!initialize(pwxDb, tblName, numColumns, tempQryTblName, qryOnly, tblPath))
cleanup();
} // wxDbTable::wxDbTable()
} // wxDbTable::~wxDbTable()
-bool wxDbTable::initialize(wxDb *pwxDb, const wxString &tblName, const int nCols,
+bool wxDbTable::initialize(wxDb *pwxDb, const wxString &tblName, const UWORD numColumns,
const wxString &qryTblName, bool qryOnly, const wxString &tblPath)
{
// Initializing member variables
hstmtInternal = 0;
colDefs = 0;
tableID = 0;
- noCols = nCols; // No. of cols in the table
+ noCols = numColumns; // Number of cols in the table
where.Empty(); // Where clause
orderBy.Empty(); // Order By clause
from.Empty(); // From clause
wxString s;
tableID = ++lastTableID;
s.Printf(wxT("wxDbTable constructor (%-20s) tableID:[%6lu] pDb:[%p]"), tblName.c_str(), tableID, pDb);
-
+
#ifdef __WXDEBUG__
wxTablesInUse *tableInUse;
tableInUse = new wxTablesInUse();
/***************************** PRIVATE FUNCTIONS *****************************/
-/********** wxDbTable::bindUpdateParams() **********/
+/********** wxDbTable::bindParams() **********/
bool wxDbTable::bindParams(bool forUpdate)
{
wxASSERT(!queryOnly);
// 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++)
+ int i;
+ UWORD colNo;
+
+ for (i=0, colNo=1; i < noCols; i++)
{
if (forUpdate)
{
- if (! colDefs[i].Updateable)
+ if (!colDefs[i].Updateable)
continue;
}
else
{
- if (! colDefs[i].InsertAllowed)
+ if (!colDefs[i].InsertAllowed)
continue;
}
/********** wxDbTable::bindCols() **********/
bool wxDbTable::bindCols(HSTMT cursor)
{
-//RG-NULL static SDWORD cb;
-
// Bind each column of the table to a memory address for fetching data
- int i;
+ UWORD i;
for (i = 0; i < noCols; i++)
{
- if (SQLBindCol(cursor, i+1, colDefs[i].SqlCtype, (UCHAR*) colDefs[i].PtrDataObj,
-//RG-NULL colDefs[i].SzDataObj, &cb) != SQL_SUCCESS)
+ if (SQLBindCol(cursor, (UWORD)(i+1), colDefs[i].SqlCtype, (UCHAR*) colDefs[i].PtrDataObj,
colDefs[i].SzDataObj, &colDefs[i].CbValue ) != SQL_SUCCESS)
{
return (pDb->DispAllErrors(henv, hdbc, cursor));
UWORD rowStatus;
retcode = SQLExtendedFetch(hstmt, fetchType, 0, &cRowsFetched, &rowStatus);
- if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
{
if (retcode == SQL_NO_DATA_FOUND)
return(FALSE);
/********** wxDbTable::execDelete() **********/
bool wxDbTable::execDelete(const wxString &pSqlStmt)
{
+ RETCODE retcode;
+
// Execute the DELETE statement
- if (SQLExecDirect(hstmtDelete, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS)
- return(pDb->DispAllErrors(henv, hdbc, hstmtDelete));
+ retcode = SQLExecDirect(hstmtDelete, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS);
- // Record deleted successfully
- return(TRUE);
+ if (retcode == SQL_SUCCESS ||
+ retcode == SQL_NO_DATA_FOUND ||
+ retcode == SQL_SUCCESS_WITH_INFO)
+ {
+ // Record deleted successfully
+ return(TRUE);
+ }
+
+ // Problem deleting record
+ return(pDb->DispAllErrors(henv, hdbc, hstmtDelete));
} // wxDbTable::execDelete()
/********** wxDbTable::execUpdate() **********/
bool wxDbTable::execUpdate(const wxString &pSqlStmt)
{
+ RETCODE retcode;
+
// Execute the UPDATE statement
- if (SQLExecDirect(hstmtUpdate, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS)
- return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate));
+ retcode = SQLExecDirect(hstmtUpdate, (UCHAR FAR *) pSqlStmt.c_str(), SQL_NTS);
- // Record deleted successfully
- return(TRUE);
+ if (retcode == SQL_SUCCESS ||
+ retcode == SQL_NO_DATA_FOUND ||
+ retcode == SQL_SUCCESS_WITH_INFO)
+ {
+ // Record updated successfully
+ return(TRUE);
+ }
+
+ // Problem updating record
+ return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate));
} // wxDbTable::execUpdate()
BuildSelectStmt(sqlStmt, queryType, distinct);
pDb->WriteSqlLog(sqlStmt);
}
-/*
- This is the block of code that got added during the 2.2.1 merge with
- the 2.2 main branch that somehow got added here when it should not have. - gt
- else
- wxStrcpy(sqlStmt, pSqlStmt);
-
- SQLFreeStmt(hstmt, SQL_CLOSE);
- if (SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt, SQL_NTS) == SQL_SUCCESS)
- return(TRUE);
- else
- {
- pDb->DispAllErrors(henv, hdbc, hstmt);
- return(FALSE);
- }
-*/
// Make sure the cursor is closed first
if (!CloseCursor(hstmt))
return(FALSE);
s.Empty();
// Verify that the table exists in the database
- if (checkTableExists && !pDb->TableExists(tableName,/*pDb->GetUsername()*/NULL,tablePath))
+ if (checkTableExists && !pDb->TableExists(tableName, pDb->GetUsername(), tablePath))
{
s = wxT("Table/view does not exist in the database");
if ( *(pDb->dbInf.accessibleTables) == wxT('Y'))
// Unfortunately this optimization doesn't seem to be
// reliable!
if (// *(pDb->dbInf.accessibleTables) == 'N' &&
- !pDb->TablePrivileges(tableName,wxT("SELECT"),NULL,pDb->GetUsername(),tablePath))
+ !pDb->TablePrivileges(tableName,wxT("SELECT"), pDb->GetUsername(), pDb->GetUsername(), tablePath))
s = wxT("Current logged in user does not have sufficient privileges to access this table.\n");
}
// 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)
+ if (SQLGetData(hstmt, (UWORD)(noCols+1), SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS)
{
pSqlStmt += wxT("ROWID = '");
pSqlStmt += rowid;
for (i = 0; i < noCols; i++)
{
// If joining tables, the base table column names must be qualified to avoid ambiguity
- if (appendFromClause)
+ if (appendFromClause || pDb->Dbms() == dbmsACCESS)
{
pSqlStmt += queryTableName;
pSqlStmt += wxT(".");
if (!distinct && CanUpdByROWID())
{
// If joining tables, the base table column names must be qualified to avoid ambiguity
- if (appendFromClause)
+ if (appendFromClause || pDb->Dbms() == dbmsACCESS)
{
pSqlStmt += wxT(",");
pSqlStmt += queryTableName;
bool firstColumn = TRUE;
- pSqlStmt.Printf(wxT("UPDATE %s SET "), tableName.c_str());
+ pSqlStmt.Printf(wxT("UPDATE %s SET "), tableName.Upper().c_str());
// Append a list of columns to be updated
int i;
// Only append Updateable columns
if (colDefs[i].Updateable)
{
- if (! firstColumn)
+ if (!firstColumn)
pSqlStmt += wxT(",");
else
firstColumn = FALSE;
// 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)
+ if (SQLGetData(hstmt, (UWORD)(noCols+1), SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS)
{
pSqlStmt += wxT("ROWID = '");
pSqlStmt += rowid;
if (pDb->Dbms() == dbmsDB2 ||
pDb->Dbms() == dbmsMY_SQL ||
pDb->Dbms() == dbmsSYBASE_ASE ||
+ pDb->Dbms() == dbmsINTERBASE ||
pDb->Dbms() == dbmsMS_SQL_SERVER)
{
if (colDefs[i].KeyField)
}
if (j && pDb->Dbms() != dbmsDBASE) // Found a keyfield
{
- if (pDb->Dbms() != dbmsMY_SQL)
- {
- sqlStmt += wxT(",CONSTRAINT ");
- sqlStmt += tableName;
- sqlStmt += wxT("_PIDX PRIMARY KEY (");
- }
- else
+ switch (pDb->Dbms())
{
- /* MySQL goes out on this one. We also declare the relevant key NON NULL above */
- sqlStmt += wxT(", PRIMARY KEY (");
+ case dbmsSYBASE_ASA:
+ case dbmsSYBASE_ASE:
+ case dbmsMY_SQL:
+ {
+ // MySQL goes out on this one. We also declare the relevant key NON NULL above
+ sqlStmt += wxT(",PRIMARY KEY (");
+ break;
+ }
+ default:
+ {
+ sqlStmt += wxT(",CONSTRAINT ");
+ // DB2 is limited to 18 characters for index names
+ if (pDb->Dbms() == dbmsDB2)
+ {
+ wxASSERT_MSG((tableName && wxStrlen(tableName) <= 13), wxT("DB2 table/index names must be no longer than 13 characters in length.\n\nTruncating table name to 13 characters."));
+ sqlStmt += tableName.substr(0, 13);
+ }
+ else
+ sqlStmt += tableName;
+
+ sqlStmt += wxT("_PIDX PRIMARY KEY (");
+ break;
+ }
}
// List column name(s) of column(s) comprising the primary key
sqlStmt += colDefs[i].ColName;
}
}
- sqlStmt += wxT(")");
+ sqlStmt += wxT(")");
+
+ if (pDb->Dbms() == dbmsSYBASE_ASA ||
+ pDb->Dbms() == dbmsSYBASE_ASE)
+ {
+ sqlStmt += wxT(" CONSTRAINT ");
+ sqlStmt += tableName;
+ sqlStmt += wxT("_PIDX");
+ }
}
// Append the closing parentheses for the create table statement
sqlStmt += wxT(")");
cout << endl << sqlStmt.c_str() << endl;
#endif
- if (SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS)
+
+
+
+ RETCODE retcode = SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS);
+ if (retcode != SQL_SUCCESS)
{
// Check for "Base table not found" error and ignore
pDb->GetNextError(henv, hdbc, hstmt);
- if (wxStrcmp(pDb->sqlState, wxT("S0002")) &&
- wxStrcmp(pDb->sqlState, wxT("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,wxT("42000"))) || // 5.x (and lower?)
- (pDb->Dbms() == dbmsSYBASE_ASE && !wxStrcmp(pDb->sqlState,wxT("37000"))) ||
- (pDb->Dbms() == dbmsPOSTGRES && !wxStrcmp(pDb->sqlState,wxT("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() == dbmsPERVASIVE_SQL && !wxStrcmp(pDb->sqlState,wxT("S1000"))) || // Returns an S1000 then an S0002
+ (pDb->Dbms() == dbmsPOSTGRES && !wxStrcmp(pDb->sqlState,wxT("08S01")))))
{
pDb->DispNextError();
pDb->DispAllErrors(henv, hdbc, hstmt);
pDb->RollbackTrans();
- CloseCursor(hstmt);
+// CloseCursor(hstmt);
return(FALSE);
}
}
/********** wxDbTable::CreateIndex() **********/
-bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, int noIdxCols, wxDbIdxDef *pIdxDefs, bool attemptDrop)
+bool wxDbTable::CreateIndex(const wxString &idxName, bool unique, UWORD noIdxCols,
+ wxDbIdxDef *pIdxDefs, bool attemptDrop)
{
wxString sqlStmt;
for (i = 0; i < noIdxCols; i++)
{
sqlStmt += pIdxDefs[i].ColName;
- /* Postgres doesn't cope with ASC */
- if (pDb->Dbms() != dbmsPOSTGRES)
+
+ // 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)) &&
+ !(pDb->Dbms() == dbmsPOSTGRES))
{
if (pIdxDefs[i].Ascending)
sqlStmt += wxT(" ASC");
else
sqlStmt += wxT(" DESC");
}
+ else
+ wxASSERT_MSG(!pIdxDefs[i].Ascending, "Datasource does not support DESCending index columns");
if ((i + 1) < noIdxCols)
sqlStmt += wxT(",");
{
// 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
+ // below for any other databases when those databases are defined
// to handle this situation consistently
wxString sqlStmt;
- if (pDb->Dbms() == dbmsACCESS || pDb->Dbms() == dbmsMY_SQL)
+ if (pDb->Dbms() == dbmsACCESS || pDb->Dbms() == dbmsMY_SQL ||
+ pDb->Dbms() == dbmsDBASE /*|| Paradox needs this syntax too when we add support*/)
sqlStmt.Printf(wxT("DROP INDEX %s ON %s"),idxName.c_str(), tableName.c_str());
else if ((pDb->Dbms() == dbmsMS_SQL_SERVER) ||
(pDb->Dbms() == dbmsSYBASE_ASE))
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() == dbmsINTERBASE && !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")))
/********** wxDbTable::SetOrderByColNums() **********/
-bool wxDbTable::SetOrderByColNums(int first, ... )
+bool wxDbTable::SetOrderByColNums(UWORD first, ... )
{
- int colNo = first;
+ int colNo = first; // using 'int' to be able to look for wxDB_NO_MORE_COLUN_NUMBERS
va_list argptr;
bool abort = FALSE;
/********** wxDbTable::IsColNull() **********/
-bool wxDbTable::IsColNull(int colNo)
+bool wxDbTable::IsColNull(UWORD colNo)
{
/*
This logic is just not right. It would indicate TRUE
* as the ROWID is not getting updated correctly
*/
return FALSE;
-
+/*
if (pDb->Dbms() == dbmsORACLE)
return(TRUE);
else
return(FALSE);
-
+*/
} // wxDbTable::CanUpdByROWID()
/********** wxDbTable::ClearMemberVar() **********/
-void wxDbTable::ClearMemberVar(int colNo, bool setToNull)
+void wxDbTable::ClearMemberVar(UWORD colNo, bool setToNull)
{
wxASSERT(colNo < noCols);
/********** wxDbTable::SetColDefs() **********/
-void wxDbTable::SetColDefs(int index, const wxString &fieldName, int dataType, void *pData,
- int cType, int size, bool keyField, bool upd,
+void wxDbTable::SetColDefs(UWORD index, const wxString &fieldName, int dataType, void *pData,
+ SWORD cType, int size, bool keyField, bool upd,
bool insAllow, bool derivedCol)
{
if (!colDefs) // May happen if the database connection fails
if (fieldName.Length() > (unsigned int) DB_MAX_COLUMN_NAME_LEN)
{
- wxStrncpy (colDefs[index].ColName, fieldName, DB_MAX_COLUMN_NAME_LEN);
+ int assertColumnNameTooLong = 0;
+ wxStrncpy(colDefs[index].ColName, fieldName, DB_MAX_COLUMN_NAME_LEN);
colDefs[index].ColName[DB_MAX_COLUMN_NAME_LEN] = 0;
+ wxString tmpMsg;
+ tmpMsg.sprintf("Column name '%s' is too long. Truncated to '%s'.",fieldName,colDefs[index].ColName);
+ wxASSERT_MSG(assertColumnNameTooLong,tmpMsg.c_str());
}
else
wxStrcpy(colDefs[index].ColName, fieldName);
/********** wxDbTable::SetColDefs() **********/
-wxDbColDataPtr* wxDbTable::SetColDefs(wxDbColInf *pColInfs, ULONG numCols)
+wxDbColDataPtr* wxDbTable::SetColDefs(wxDbColInf *pColInfs, UWORD numCols)
{
wxASSERT(pColInfs);
wxDbColDataPtr *pColDataPtrs = NULL;
if (pColInfs)
{
- ULONG index;
+ UWORD index;
pColDataPtrs = new wxDbColDataPtr[numCols+1];
pColDataPtrs[index].SqlCtype = SQL_C_TIMESTAMP;
break;
case DB_DATA_TYPE_BLOB:
- int notSupportedYet = 0;
+ int notSupportedYet = 0;
wxASSERT_MSG(notSupportedYet, wxT("This form of ::SetColDefs() cannot be used with BLOB columns"));
pColDataPtrs[index].PtrDataObj = /*BLOB ADDITION NEEDED*/NULL;
pColDataPtrs[index].SzDataObj = /*BLOB ADDITION NEEDED*/sizeof(void *);
}
// Obtain the result
- if (SQLGetData(*hstmtCount, 1, SQL_C_ULONG, &count, sizeof(count), &cb) != SQL_SUCCESS)
+ if (SQLGetData(*hstmtCount, (UWORD)1, SQL_C_ULONG, &count, sizeof(count), &cb) != SQL_SUCCESS)
{
pDb->DispAllErrors(henv, hdbc, *hstmtCount);
return(0);
// 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)
+ if (SQLGetData(hstmt, (UWORD)(noCols+1), SQL_C_CHAR, (UCHAR*) rowid, wxDB_ROWID_LEN, &cb) == SQL_SUCCESS)
{
whereClause += queryTableName;
whereClause += wxT(".ROWID = '");
} // wxDbTable::Refresh()
-/********** wxDbTable::SetColNull(int colNo, bool set) **********/
-bool wxDbTable::SetColNull(int colNo, bool set)
+/********** wxDbTable::SetColNull() **********/
+bool wxDbTable::SetColNull(UWORD colNo, bool set)
{
if (colNo < noCols)
{
} // wxDbTable::SetColNull()
-/********** wxDbTable::SetColNull(const wxString &colName, bool set) **********/
+/********** wxDbTable::SetColNull() **********/
bool wxDbTable::SetColNull(const wxString &colName, bool set)
{
int i;