]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/dbtable.cpp
Fixes errno.h problems with OS/2
[wxWidgets.git] / src / common / dbtable.cpp
index 2a64883a0bcd0106b649dfc2f89c46e9b8f135f0..0df9c08bc44e3fae50edee19b87f1df4a85548a2 100644 (file)
@@ -128,21 +128,21 @@ bool wxDbColDef::Initialize()
 
 
 /********** wxDbTable::wxDbTable() Constructor **********/
 
 
 /********** 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)
 {
                     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 *****/
         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;
                     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()
 
         cleanup();
 }  // wxDbTable::wxDbTable()
 
@@ -154,7 +154,7 @@ wxDbTable::~wxDbTable()
 }  // 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
                     const wxString &qryTblName, bool qryOnly, const wxString &tblPath)
 {
     // Initializing member variables
@@ -170,7 +170,7 @@ bool wxDbTable::initialize(wxDb *pwxDb, const wxString &tblName, const int nCols
     hstmtInternal       = 0;
     colDefs             = 0;
     tableID             = 0;
     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
     where.Empty();                                  // Where clause
     orderBy.Empty();                                // Order By clause
     from.Empty();                                   // From clause
@@ -417,7 +417,7 @@ ODBC 3.0 says to use this form
 /***************************** PRIVATE FUNCTIONS *****************************/
 
 
 /***************************** PRIVATE FUNCTIONS *****************************/
 
 
-/********** wxDbTable::bindUpdateParams() **********/
+/********** wxDbTable::bindParams() **********/
 bool wxDbTable::bindParams(bool forUpdate)
 {
     wxASSERT(!queryOnly);
 bool wxDbTable::bindParams(bool forUpdate)
 {
     wxASSERT(!queryOnly);
@@ -430,17 +430,19 @@ bool wxDbTable::bindParams(bool forUpdate)
     
     // Bind each column of the table that should be bound
     // 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++)
+    int i;
+    UWORD colNo;
+
+    for (i=0, colNo=1; i < noCols; i++)
     {
         if (forUpdate)
         {
     {
         if (forUpdate)
         {
-            if (! colDefs[i].Updateable)
+            if (!colDefs[i].Updateable)
                 continue;
         }
         else
         {
                 continue;
         }
         else
         {
-            if (! colDefs[i].InsertAllowed)
+            if (!colDefs[i].InsertAllowed)
                 continue;
         }
 
                 continue;
         }
 
@@ -487,6 +489,15 @@ bool wxDbTable::bindParams(bool forUpdate)
                 else
                     colDefs[i].CbValue = 0;
                 break;
                 else
                     colDefs[i].CbValue = 0;
                 break;
+            case DB_DATA_TYPE_BLOB:
+                fSqlType = pDb->GetTypeInfBlob().FsqlType;
+                precision = 50000;
+                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;
         }
         if (forUpdate)
         {
         }
         if (forUpdate)
         {
@@ -531,14 +542,11 @@ bool wxDbTable::bindUpdateParams(void)
 /********** wxDbTable::bindCols() **********/
 bool wxDbTable::bindCols(HSTMT cursor)
 {
 /********** 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
     // Bind each column of the table to a memory address for fetching data
-    int i;
+    UWORD i;
     for (i = 0; i < noCols; 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));
                        colDefs[i].SzDataObj, &colDefs[i].CbValue ) != SQL_SUCCESS)
         {
           return (pDb->DispAllErrors(henv, hdbc, cursor));
@@ -563,7 +571,7 @@ bool wxDbTable::getRec(UWORD fetchType)
         UWORD   rowStatus;
 
         retcode = SQLExtendedFetch(hstmt, fetchType, 0, &cRowsFetched, &rowStatus);
         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);
         {
             if (retcode == SQL_NO_DATA_FOUND)
                 return(FALSE);
@@ -609,12 +617,21 @@ bool wxDbTable::getRec(UWORD fetchType)
 /********** wxDbTable::execDelete() **********/
 bool wxDbTable::execDelete(const wxString &pSqlStmt)
 {
 /********** wxDbTable::execDelete() **********/
 bool wxDbTable::execDelete(const wxString &pSqlStmt)
 {
+    RETCODE retcode;
+
     // Execute the DELETE statement
     // 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::execDelete()
 
@@ -622,12 +639,21 @@ bool wxDbTable::execDelete(const wxString &pSqlStmt)
 /********** wxDbTable::execUpdate() **********/
 bool wxDbTable::execUpdate(const wxString &pSqlStmt)
 {
 /********** wxDbTable::execUpdate() **********/
 bool wxDbTable::execUpdate(const wxString &pSqlStmt)
 {
+    RETCODE retcode;
+
     // Execute the UPDATE statement
     // 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()
 
 
 }  // wxDbTable::execUpdate()
 
@@ -685,7 +711,7 @@ bool wxDbTable::query(int queryType, bool forUpdate, bool distinct, const wxStri
 
 
 /********** wxDbTable::Open() **********/
 
 
 /********** wxDbTable::Open() **********/
-bool wxDbTable::Open(bool checkPrivileges)
+bool wxDbTable::Open(bool checkPrivileges, bool checkTableExists)
 {
     if (!pDb)
         return FALSE;   
 {
     if (!pDb)
         return FALSE;   
@@ -696,7 +722,7 @@ bool wxDbTable::Open(bool checkPrivileges)
 
     s.Empty();
     // Verify that the table exists in the database
 
     s.Empty();
     // Verify that the table exists in the database
-    if (!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'))
     {
         s = wxT("Table/view does not exist in the database");
         if ( *(pDb->dbInf.accessibleTables) == wxT('Y'))
@@ -713,7 +739,7 @@ bool wxDbTable::Open(bool checkPrivileges)
         // Unfortunately this optimization doesn't seem to be
         // reliable!
         if (// *(pDb->dbInf.accessibleTables) == 'N' && 
         // 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");
     }
 
             s = wxT("Current logged in user does not have sufficient privileges to access this table.\n");
     }
 
@@ -929,7 +955,7 @@ void wxDbTable::BuildDeleteStmt(wxString &pSqlStmt, int typeOfDel, const wxStrin
                 // 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.
                 // 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;
                 {
                     pSqlStmt += wxT("ROWID = '");
                     pSqlStmt += rowid;
@@ -992,7 +1018,7 @@ void wxDbTable::BuildSelectStmt(wxString &pSqlStmt, int typeOfSelect, bool disti
     for (i = 0; i < noCols; i++)
     {
         // If joining tables, the base table column names must be qualified to avoid ambiguity
     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(".");
         {
             pSqlStmt += queryTableName;
             pSqlStmt += wxT(".");
@@ -1007,7 +1033,7 @@ void wxDbTable::BuildSelectStmt(wxString &pSqlStmt, int typeOfSelect, bool disti
     if (!distinct && CanUpdByROWID())
     {
         // If joining tables, the base table column names must be qualified to avoid ambiguity
     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;
         {
             pSqlStmt += wxT(",");
             pSqlStmt += queryTableName;
@@ -1106,7 +1132,7 @@ void wxDbTable::BuildUpdateStmt(wxString &pSqlStmt, int typeOfUpd, const wxStrin
 
     bool firstColumn = TRUE;
 
 
     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;
 
     // Append a list of columns to be updated
     int i;
@@ -1140,7 +1166,7 @@ void wxDbTable::BuildUpdateStmt(wxString &pSqlStmt, int typeOfUpd, const wxStrin
                 // 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.
                 // 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;
                 {
                     pSqlStmt += wxT("ROWID = '");
                     pSqlStmt += rowid;
@@ -1315,6 +1341,9 @@ bool wxDbTable::CreateTable(bool attemptDrop)
             case DB_DATA_TYPE_DATE:
                 cout << pDb->typeInfDate.TypeName;
                 break;
             case DB_DATA_TYPE_DATE:
                 cout << pDb->typeInfDate.TypeName;
                 break;
+            case DB_DATA_TYPE_BLOB:
+                cout << pDb->typeInfBlob.TypeName;
+                break;
         }
         cout << endl;
     }
         }
         cout << endl;
     }
@@ -1350,9 +1379,13 @@ bool wxDbTable::CreateTable(bool attemptDrop)
             case DB_DATA_TYPE_DATE:
                 sqlStmt += pDb->GetTypeInfDate().TypeName;
                 break;
             case DB_DATA_TYPE_DATE:
                 sqlStmt += pDb->GetTypeInfDate().TypeName;
                 break;
+            case DB_DATA_TYPE_BLOB:
+                sqlStmt += pDb->GetTypeInfBlob().TypeName;
+                break;
         }
         // For varchars, append the size of the string
         }
         // For varchars, append the size of the string
-        if (colDefs[i].DbDataType == DB_DATA_TYPE_VARCHAR)
+        if (colDefs[i].DbDataType == DB_DATA_TYPE_VARCHAR)// ||
+//            colDefs[i].DbDataType == DB_DATA_TYPE_BLOB)
         {
             wxString s;
             s.Printf(wxT("(%d)"), colDefs[i].SzDataObj);
         {
             wxString s;
             s.Printf(wxT("(%d)"), colDefs[i].SzDataObj);
@@ -1383,16 +1416,31 @@ bool wxDbTable::CreateTable(bool attemptDrop)
     }
     if (j && pDb->Dbms() != dbmsDBASE)  // Found a keyfield
     {
     }
     if (j && pDb->Dbms() != dbmsDBASE)  // Found a keyfield
     {
-        if (pDb->Dbms() != dbmsMY_SQL)
+        switch (pDb->Dbms())
         {
         {
-            sqlStmt += wxT(",CONSTRAINT ");
-            sqlStmt += tableName;
-            sqlStmt += wxT("_PIDX PRIMARY KEY (");
-        }
-        else
-        {
-            /* 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
         }
 
         // List column name(s) of column(s) comprising the primary key
@@ -1405,7 +1453,15 @@ bool wxDbTable::CreateTable(bool attemptDrop)
                 sqlStmt += colDefs[i].ColName;
             }
         }
                 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(")");
     }
     // Append the closing parentheses for the create table statement
     sqlStmt += wxT(")");
@@ -1456,22 +1512,27 @@ bool wxDbTable::DropTable()
     cout << endl << sqlStmt.c_str() << endl;
 #endif
 
     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);   
     {
         // 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
             // 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();
             {
                 pDb->DispNextError();
                 pDb->DispAllErrors(henv, hdbc, hstmt);
                 pDb->RollbackTrans();
-                CloseCursor(hstmt);
+//                CloseCursor(hstmt);
                 return(FALSE);
             }
         }
                 return(FALSE);
             }
         }
@@ -1488,7 +1549,8 @@ bool wxDbTable::DropTable()
 
 
 /********** wxDbTable::CreateIndex() **********/
 
 
 /********** 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;
 
 {
     wxString sqlStmt;
 
@@ -1616,12 +1678,13 @@ 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
 {
     // 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;
 
     //       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))
         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))
@@ -1670,9 +1733,9 @@ bool wxDbTable::DropIndex(const wxString &idxName)
 
 
 /********** wxDbTable::SetOrderByColNums() **********/
 
 
 /********** 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;
     va_list     argptr;
 
     bool        abort = FALSE;
@@ -1863,7 +1926,7 @@ bool wxDbTable::DeleteMatching(void)
 
 
 /********** wxDbTable::IsColNull() **********/
 
 
 /********** wxDbTable::IsColNull() **********/
-bool wxDbTable::IsColNull(int colNo)
+bool wxDbTable::IsColNull(UWORD colNo)
 {
 /*
     This logic is just not right.  It would indicate TRUE
 {
 /*
     This logic is just not right.  It would indicate TRUE
@@ -1926,12 +1989,12 @@ bool wxDbTable::CanUpdByROWID(void)
  *        as the ROWID is not getting updated correctly
  */
     return FALSE;
  *        as the ROWID is not getting updated correctly
  */
     return FALSE;
-
+/*
     if (pDb->Dbms() == dbmsORACLE)
         return(TRUE);
     else
         return(FALSE);
     if (pDb->Dbms() == dbmsORACLE)
         return(TRUE);
     else
         return(FALSE);
-
+*/
 }  // wxDbTable::CanUpdByROWID()
 
 
 }  // wxDbTable::CanUpdByROWID()
 
 
@@ -1948,7 +2011,7 @@ bool wxDbTable::IsCursorClosedOnCommit(void)
 
 
 /********** wxDbTable::ClearMemberVar() **********/
 
 
 /********** wxDbTable::ClearMemberVar() **********/
-void wxDbTable::ClearMemberVar(int colNo, bool setToNull)
+void wxDbTable::ClearMemberVar(UWORD colNo, bool setToNull)
 {
     wxASSERT(colNo < noCols);
 
 {
     wxASSERT(colNo < noCols);
 
@@ -2024,8 +2087,8 @@ bool wxDbTable::SetQueryTimeout(UDWORD nSeconds)
 
 
 /********** wxDbTable::SetColDefs() **********/
 
 
 /********** 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
                            bool insAllow, bool derivedCol)
 {
     if (!colDefs)  // May happen if the database connection fails
@@ -2063,14 +2126,14 @@ void wxDbTable::SetColDefs(int index, const wxString &fieldName, int dataType, v
 
 
 /********** wxDbTable::SetColDefs() **********/
 
 
 /********** wxDbTable::SetColDefs() **********/
-wxDbColDataPtr* wxDbTable::SetColDefs(wxDbColInf *pColInfs, ULONG numCols)
+wxDbColDataPtr* wxDbTable::SetColDefs(wxDbColInf *pColInfs, UWORD numCols)
 {
     wxASSERT(pColInfs);
     wxDbColDataPtr *pColDataPtrs = NULL;
 
     if (pColInfs)
     {
 {
     wxASSERT(pColInfs);
     wxDbColDataPtr *pColDataPtrs = NULL;
 
     if (pColInfs)
     {
-        ULONG index;
+        UWORD index;
        
         pColDataPtrs = new wxDbColDataPtr[numCols+1];
 
        
         pColDataPtrs = new wxDbColDataPtr[numCols+1];
 
@@ -2119,8 +2182,26 @@ wxDbColDataPtr* wxDbTable::SetColDefs(wxDbColInf *pColInfs, ULONG numCols)
                     pColDataPtrs[index].SzDataObj  = sizeof(TIMESTAMP_STRUCT);
                     pColDataPtrs[index].SqlCtype   = SQL_C_TIMESTAMP;
                     break;
                     pColDataPtrs[index].SzDataObj  = sizeof(TIMESTAMP_STRUCT);
                     pColDataPtrs[index].SqlCtype   = SQL_C_TIMESTAMP;
                     break;
+                case DB_DATA_TYPE_BLOB:
+                    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 *);
+                    pColDataPtrs[index].SqlCtype   = SQL_VARBINARY;
+                    break;
+            }
+            if (pColDataPtrs[index].PtrDataObj != NULL)
+                SetColDefs (index,pColInfs[index].colName,pColInfs[index].dbDataType, pColDataPtrs[index].PtrDataObj, pColDataPtrs[index].SqlCtype, pColDataPtrs[index].SzDataObj);
+            else
+            {
+                // Unable to build all the column definitions, as either one of 
+                // the calls to "new" failed above, or there was a BLOB field
+                // to have a column definition for.  If BLOBs are to be used,
+                // the other form of ::SetColDefs() must be used, as it is impossible
+                // to know the maximum size to create the PtrDataObj to be.
+                delete [] pColDataPtrs;
+                return NULL;
             }
             }
-            SetColDefs (index,pColInfs[index].colName,pColInfs[index].dbDataType, pColDataPtrs[index].PtrDataObj, pColDataPtrs[index].SqlCtype, pColDataPtrs[index].SzDataObj);
         }
     }
 
         }
     }
 
@@ -2196,7 +2277,7 @@ ULONG wxDbTable::Count(const wxString &args)
     }
 
     // Obtain the result
     }
 
     // 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);
     {
         pDb->DispAllErrors(henv, hdbc, *hstmtCount);
         return(0);
@@ -2241,7 +2322,7 @@ bool wxDbTable::Refresh(void)
         // 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.
         // 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 = '");
         {
             whereClause += queryTableName;
             whereClause += wxT(".ROWID = '");
@@ -2279,8 +2360,8 @@ bool wxDbTable::Refresh(void)
 }  // wxDbTable::Refresh()
 
 
 }  // 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)
     {
 {
     if (colNo < noCols)
     {
@@ -2295,7 +2376,7 @@ bool wxDbTable::SetColNull(int colNo, bool set)
 }  // wxDbTable::SetColNull()
 
 
 }  // wxDbTable::SetColNull()
 
 
-/********** wxDbTable::SetColNull(const wxString &colName, bool set) **********/
+/********** wxDbTable::SetColNull() **********/
 bool wxDbTable::SetColNull(const wxString &colName, bool set)
 {
     int i;
 bool wxDbTable::SetColNull(const wxString &colName, bool set)
 {
     int i;