+/********** 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)
+{
+/*
+ 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)
+ {
+ case SQL_C_CHAR:
+ return(((UCHAR FAR *) colDefs[colNo].PtrDataObj)[0] == 0);
+ case SQL_C_SSHORT:
+ return(( *((SWORD *) colDefs[colNo].PtrDataObj)) == 0);
+ case SQL_C_USHORT:
+ return(( *((UWORD*) colDefs[colNo].PtrDataObj)) == 0);
+ case SQL_C_SLONG:
+ return(( *((SDWORD *) colDefs[colNo].PtrDataObj)) == 0);
+ case SQL_C_ULONG:
+ return(( *((UDWORD *) colDefs[colNo].PtrDataObj)) == 0);
+ case SQL_C_FLOAT:
+ return(( *((SFLOAT *) colDefs[colNo].PtrDataObj)) == 0);
+ case SQL_C_DOUBLE:
+ return((*((SDOUBLE *) colDefs[colNo].PtrDataObj)) == 0);
+ case SQL_C_TIMESTAMP:
+ TIMESTAMP_STRUCT *pDt;
+ pDt = (TIMESTAMP_STRUCT *) colDefs[colNo].PtrDataObj;
+ if (pDt->year == 0 && pDt->month == 0 && pDt->day == 0)
+ return(TRUE);
+ else
+ return(FALSE);
+ default:
+ return(TRUE);
+ }
+*/
+ return (colDefs[colNo].Null);
+} // wxDbTable::IsColNull()