-} // wxTable::QueryBySqlStmt()
-
-
-/********** wxTable::QueryMatching() **********/
-bool wxTable::QueryMatching(bool forUpdate, bool distinct)
-{
-
- return(query(DB_SELECT_MATCHING, forUpdate, distinct));
-
-} // wxTable::QueryMatching()
-
-
-/********** wxTable::QueryOnKeyFields() **********/
-bool wxTable::QueryOnKeyFields(bool forUpdate, bool distinct)
-{
-
- return(query(DB_SELECT_KEYFIELDS, forUpdate, distinct));
-
-} // wxTable::QueryOnKeyFields()
-
-
-/********** wxTable::GetPrev() **********/
-bool wxTable::GetPrev(void)
-{
- if (pDb->FwdOnlyCursors())
- {
- wxFAIL_MSG(wxT("GetPrev()::Backward scrolling cursors are not enabled for this instance of wxTable"));
- return FALSE;
- }
- else
- return(getRec(SQL_FETCH_PRIOR));
-} // wxTable::GetPrev()
-
-
-/********** wxTable::operator-- **********/
-bool wxTable::operator--(int)
-{
- if (pDb->FwdOnlyCursors())
- {
- wxFAIL_MSG(wxT("operator--:Backward scrolling cursors are not enabled for this instance of wxTable"));
- return FALSE;
- }
- else
- return(getRec(SQL_FETCH_PRIOR));
-} // wxTable::operator--
-
-
-/********** wxTable::GetFirst() **********/
-bool wxTable::GetFirst(void)
-{
- if (pDb->FwdOnlyCursors())
- {
- wxFAIL_MSG(wxT("GetFirst():Backward scrolling cursors are not enabled for this instance of wxTable"));
- return FALSE;
- }
- else
- return(getRec(SQL_FETCH_FIRST));
-} // wxTable::GetFirst()
-
-
-/********** wxTable::GetLast() **********/
-bool wxTable::GetLast(void)
-{
- if (pDb->FwdOnlyCursors())
- {
- wxFAIL_MSG(wxT("GetLast()::Backward scrolling cursors are not enabled for this instance of wxTable"));
- return FALSE;
- }
- else
- return(getRec(SQL_FETCH_LAST));
-} // wxTable::GetLast()
-
-
-/********** wxTable::GetSelectStmt() **********/
-void wxTable::GetSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct)
-{
- char whereClause[DB_MAX_WHERE_CLAUSE_LEN];
-
- whereClause[0] = 0;
-
- // Build a select statement to query the database
- wxStrcpy(pSqlStmt, "SELECT ");
+/********** wxDbTable::BuildSelectStmt() **********/
+void wxDbTable::BuildSelectStmt(wxString &pSqlStmt, int typeOfSelect, bool distinct)
+{
+ wxString whereClause;
+ whereClause.Empty();
+
+ // Build a select statement to query the database
+ pSqlStmt = wxT("SELECT ");
+
+ // SELECT DISTINCT values only?
+ if (distinct)
+ pSqlStmt += wxT("DISTINCT ");
+
+ // Was a FROM clause specified to join tables to the base table?
+ // Available for ::Query() only!!!
+ bool appendFromClause = FALSE;
+#if wxODBC_BACKWARD_COMPATABILITY
+ if (typeOfSelect == DB_SELECT_WHERE && from && wxStrlen(from))
+ appendFromClause = TRUE;
+#else
+ if (typeOfSelect == DB_SELECT_WHERE && from.Length())
+ appendFromClause = TRUE;
+#endif
+
+ // Add the column list
+ int i;
+ for (i = 0; i < noCols; i++)
+ {
+ // If joining tables, the base table column names must be qualified to avoid ambiguity
+ if (appendFromClause || pDb->Dbms() == dbmsACCESS)
+ {
+ 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(",");
+ }
+
+ // If the datasource supports ROWID, get this column as well. Exception: Don't retrieve
+ // the ROWID if querying distinct records. The rowid will always be unique.
+ if (!distinct && CanUpdByROWID())
+ {
+ // If joining tables, the base table column names must be qualified to avoid ambiguity
+ if (appendFromClause || pDb->Dbms() == dbmsACCESS)
+ {
+ pSqlStmt += wxT(",");
+ pSqlStmt += pDb->SQLTableName(queryTableName);
+// pSqlStmt += queryTableName;
+ pSqlStmt += wxT(".ROWID");
+ }
+ else
+ pSqlStmt += wxT(",ROWID");
+ }
+
+ // Append the FROM tablename portion
+ pSqlStmt += wxT(" FROM ");
+ pSqlStmt += pDb->SQLTableName(queryTableName);
+// pSqlStmt += queryTableName;
+
+ // Sybase uses the HOLDLOCK keyword to lock a record during query.
+ // The HOLDLOCK keyword follows the table name in the from clause.
+ // Each table in the from clause must specify HOLDLOCK or
+ // 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))
+ pSqlStmt += wxT(" HOLDLOCK");
+
+ if (appendFromClause)
+ pSqlStmt += from;
+
+ // Append the WHERE clause. Either append the where clause for the class
+ // or build a where clause. The typeOfSelect determines this.
+ switch(typeOfSelect)
+ {
+ case DB_SELECT_WHERE:
+#if wxODBC_BACKWARD_COMPATABILITY
+ if (where && wxStrlen(where)) // May not want a where clause!!!
+#else
+ if (where.Length()) // May not want a where clause!!!
+#endif
+ {
+ pSqlStmt += wxT(" WHERE ");
+ pSqlStmt += where;
+ }
+ break;
+ case DB_SELECT_KEYFIELDS:
+ BuildWhereClause(whereClause, DB_WHERE_KEYFIELDS);
+ if (whereClause.Length())
+ {
+ pSqlStmt += wxT(" WHERE ");
+ pSqlStmt += whereClause;
+ }
+ break;
+ case DB_SELECT_MATCHING:
+ BuildWhereClause(whereClause, DB_WHERE_MATCHING);
+ if (whereClause.Length())
+ {
+ pSqlStmt += wxT(" WHERE ");
+ pSqlStmt += whereClause;
+ }
+ break;
+ }
+
+ // Append the ORDER BY clause
+#if wxODBC_BACKWARD_COMPATABILITY
+ if (orderBy && wxStrlen(orderBy))
+#else
+ if (orderBy.Length())
+#endif
+ {
+ 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())
+ 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 "),
+ pDb->SQLTableName(tableName.c_str()).c_str());
+
+ // 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 += pDb->SQLColumnName(colDefs[i].ColName);
+// 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, (UWORD)(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()