]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/dbtable.cpp
Changes to allow Cygwin to compile in non-PCH mode
[wxWidgets.git] / src / common / dbtable.cpp
index 32c78953961db7faf83b62ad15965d0809381cd2..645cac8005e667883d2b3ab5baeb6ff649406302 100644 (file)
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////
-// Name:        table.cpp
+// Name:        dbtable.cpp
 // Purpose:     Implementation of the wxTable class.
 // Author:      Doug Card
 // Modified by:
 //                 the wxWindows GUI development toolkit.
 ///////////////////////////////////////////////////////////////////////////////
 
+#ifdef __GNUG__
+#pragma implementation "dbtable.h"
+#endif
+
 /*
 // SYNOPSIS START
 // SYNOPSIS STOP
   #include  <wx/wx.h>
 #endif //WX_PRECOMP
 
-#if USE_ODBC
+#if wxUSE_ODBC
 
 #include <wx/dbtable.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <assert.h>
 
-#ifdef __WXUNIX__
+#ifdef __UNIX__
 // The HPUX preprocessor lines below were commented out on 8/20/97
 // because macros.h currently redefines DEBUG and is unneeded.
 // #  ifdef HPUX
 // #    include <macros.h>
 // #  endif
-#  ifdef __WXLINUX__
+#  ifdef LINUX
 #    include <sys/minmax.h>
 #  endif
 #endif
@@ -63,16 +68,22 @@ wxTable::wxTable(wxDB *pwxDB, const char *tblName, const int nCols, const char *
 {
        // Assign member variables
        pDb = pwxDB;                                                                    // Pointer to the wxDB object
+
        strcpy(tableName, tblName);                             // Table Name
        if (qryTblName)                                                         // Name of the table/view to query
                strcpy(queryTableName, qryTblName);
        else
                strcpy(queryTableName, tblName);
 
-       noCols = nCols;                                                         // No. of cols in the table
-       where = 0;                                                                              // Where clause
-       orderBy = 0;                                                                    // Order By clause
-       selectForUpdate = FALSE;                                        // SELECT ... FOR UPDATE; Indicates whether to include the FOR UPDATE phrase
+       assert(pDb);  // Assert is placed after table name is assigned for error reporting reasons
+       if (!pDb)
+               return;
+
+       noCols                          = nCols;                                        // No. of cols in the table
+       where                                   = 0;                                            // Where clause
+       orderBy                         = 0;                                            // Order By clause
+       from                                    = 0;                                            // From clause
+       selectForUpdate = FALSE;                                        // SELECT ... FOR UPDATE; Indicates whether to include the FOR UPDATE phrase
 
        // Grab the HENV and HDBC from the wxDB object
        henv = pDb->henv;
@@ -121,7 +132,7 @@ wxTable::wxTable(wxDB *pwxDB, const char *tblName, const int nCols, const char *
                        // Datasource does not support static cursors.  Driver
                        // will substitute a cursor type.  Call SQLGetStmtOption()
                        // to determine which cursor type was selected.
-                       if (SQLGetStmtOption(c1, SQL_CURSOR_TYPE, &cursorType) != SQL_SUCCESS)
+                       if (SQLGetStmtOption(c1, SQL_CURSOR_TYPE, (UCHAR*) &cursorType) != SQL_SUCCESS)
                                pDb->DispAllErrors(henv, hdbc, c1);
 #ifdef _CONSOLE
                        cout << "Static cursor changed to: ";
@@ -214,6 +225,9 @@ wxTable::~wxTable()
 /********** wxTable::Open() **********/
 bool wxTable::Open(void)
 {
+       if (!pDb)
+               return FALSE;
+
        int i;
        char sqlStmt[DB_MAX_STATEMENT_LEN];
 
@@ -272,6 +286,8 @@ bool wxTable::Open(void)
                }
                strcat(sqlStmt, ")");
 
+               pDb->WriteSqlLog(sqlStmt);
+
                // Prepare the insert statement for execution
                if (SQLPrepare(hstmtInsert, (UCHAR FAR *) sqlStmt, SQL_NTS) != SQL_SUCCESS)
                        return(pDb->DispAllErrors(henv, hdbc, hstmtInsert));
@@ -293,6 +309,7 @@ bool wxTable::Query(bool forUpdate, bool distinct)
 /********** wxTable::QueryBySqlStmt() **********/
 bool wxTable::QueryBySqlStmt(char *pSqlStmt)
 {
+       pDb->WriteSqlLog(pSqlStmt);
 
        return(query(DB_SELECT_STATEMENT, FALSE, FALSE, pSqlStmt));
 
@@ -328,7 +345,10 @@ bool wxTable::query(int queryType, bool forUpdate, bool distinct, char *pSqlStmt
 
        // Set the SQL SELECT string
        if (queryType != DB_SELECT_STATEMENT)                           // A select statement was not passed in,
-               GetSelectStmt(sqlStmt, queryType, distinct);    // so generate a select statement.
+       {                                                                                                                               // so generate a select statement.
+               GetSelectStmt(sqlStmt, queryType, distinct);
+               pDb->WriteSqlLog(sqlStmt);
+       }
 
        // Make sure the cursor is closed first
        if (! CloseCursor(hstmt))
@@ -358,9 +378,21 @@ void wxTable::GetSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct)
        if (distinct)
                strcat(pSqlStmt, "DISTINCT ");
 
+       // Was a FROM clause specified to join tables to the base table?
+       // Available for ::Query() only!!!
+       bool appendFromClause = FALSE;
+       if (typeOfSelect == DB_SELECT_WHERE && from && strlen(from))
+               appendFromClause = TRUE;
+
        // Add the column list
        for (int i = 0; i < noCols; i++)
        {
+               // If joining tables, the base table column names must be qualified to avoid ambiguity
+               if (appendFromClause)
+               {
+                       strcat(pSqlStmt, queryTableName);
+                       strcat(pSqlStmt, ".");
+               }
                strcat(pSqlStmt, colDefs[i].ColName);
                if (i + 1 < noCols)
                        strcat(pSqlStmt, ",");
@@ -369,11 +401,23 @@ void wxTable::GetSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct)
        // 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())
-               strcat(pSqlStmt, ",ROWID");
+       {
+               // If joining tables, the base table column names must be qualified to avoid ambiguity
+               if (appendFromClause)
+               {
+                       strcat(pSqlStmt, ",");
+                       strcat(pSqlStmt, queryTableName);
+                       strcat(pSqlStmt, ".ROWID");
+               }
+               else
+                       strcat(pSqlStmt, ",ROWID");
+       }
 
        // Append the FROM tablename portion
        strcat(pSqlStmt, " FROM ");
        strcat(pSqlStmt, queryTableName);
+       if (appendFromClause)
+               strcat(pSqlStmt, from);
 
        // Append the WHERE clause.  Either append the where clause for the class
        // or build a where clause.  The typeOfSelect determines this.
@@ -450,7 +494,7 @@ UWORD wxTable::GetRowNum(void)
 {
        UDWORD rowNum;
 
-       if (SQLGetStmtOption(hstmt, SQL_ROW_NUMBER, &rowNum) != SQL_SUCCESS)
+       if (SQLGetStmtOption(hstmt, SQL_ROW_NUMBER, (UCHAR*) &rowNum) != SQL_SUCCESS)
        {
                pDb->DispAllErrors(henv, hdbc, hstmt);
                return(0);
@@ -468,12 +512,9 @@ bool wxTable::bindInsertParams(void)
        UDWORD  precision;
        SWORD   scale;
 
-//glt CcolDef  *tColDef;
-
        // Bind each column (that can be inserted) of the table to a parameter marker
        for (int i = 0; i < noCols; i++)
        {
-//glt tColDef = &colDefs[i];
                if (! colDefs[i].InsertAllowed)
                        continue;
                switch(colDefs[i].DbDataType)
@@ -509,7 +550,7 @@ bool wxTable::bindInsertParams(void)
                        break;
                }
                if (SQLBindParameter(hstmtInsert, i+1, SQL_PARAM_INPUT, colDefs[i].SqlCtype,
-                                                                       fSqlType, precision, scale, colDefs[i].PtrDataObj, 
+                                                                       fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, 
                                                                        precision+1,&colDefs[i].CbValue) != SQL_SUCCESS)
                        return(pDb->DispAllErrors(henv, hdbc, hstmtInsert));
        }
@@ -564,7 +605,7 @@ bool wxTable::bindUpdateParams(void)
                        break;
                }
                if (SQLBindParameter(hstmtUpdate, colNo++, SQL_PARAM_INPUT, colDefs[i].SqlCtype,
-                                                                       fSqlType, precision, scale, colDefs[i].PtrDataObj, 
+                                                                       fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, 
                                                                        precision+1, &colDefs[i].CbValue) != SQL_SUCCESS)
                        return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate));
        }
@@ -582,7 +623,7 @@ bool wxTable::bindCols(HSTMT cursor)
        // Bind each column of the table to a memory address for fetching data
        for (int i = 0; i < noCols; i++)
        {
-               if (SQLBindCol(cursor, i+1, colDefs[i].SqlCtype, colDefs[i].PtrDataObj,
+               if (SQLBindCol(cursor, i+1, colDefs[i].SqlCtype, (UCHAR*) colDefs[i].PtrDataObj,
                                                        colDefs[i].SzDataObj, &cb) != SQL_SUCCESS)
                        return(pDb->DispAllErrors(henv, hdbc, cursor));
        }
@@ -606,6 +647,9 @@ bool wxTable::CloseCursor(HSTMT cursor)
 /********** wxTable::CreateTable() **********/
 bool wxTable::CreateTable(void)
 {
+       if (!pDb)
+               return FALSE;
+
        int i, j;
        char sqlStmt[DB_MAX_STATEMENT_LEN];
 
@@ -632,6 +676,8 @@ bool wxTable::CreateTable(void)
                }
        }
 
+       pDb->WriteSqlLog(sqlStmt);
+
        // Commit the transaction and close the cursor
        if (! pDb->CommitTrans())
                return(FALSE);
@@ -732,6 +778,8 @@ bool wxTable::CreateTable(void)
        // Append the closing parentheses for the create table statement
    strcat(sqlStmt, ")");
 
+       pDb->WriteSqlLog(sqlStmt);
+
 #ifdef _CONSOLE
        cout << endl << sqlStmt << endl;
 #endif
@@ -787,6 +835,8 @@ bool wxTable::CreateIndex(char * idxName, bool unique, int noIdxCols, CidxDef *p
        // Append closing parentheses
        strcat(sqlStmt, ")");
 
+       pDb->WriteSqlLog(sqlStmt);
+
 #ifdef _CONSOLE
        cout << endl << sqlStmt << endl << endl;
 #endif
@@ -837,6 +887,7 @@ int wxTable::Insert(void)
 /********** wxTable::Update(pSqlStmt) **********/
 bool wxTable::Update(char *pSqlStmt)
 {
+       pDb->WriteSqlLog(pSqlStmt);
 
        return(execUpdate(pSqlStmt));
 
@@ -850,6 +901,8 @@ bool wxTable::Update(void)
        // Build the SQL UPDATE statement
        GetUpdateStmt(sqlStmt, DB_UPD_KEYFIELDS);
 
+       pDb->WriteSqlLog(sqlStmt);
+
 #ifdef _CONSOLE
        cout << endl << sqlStmt << endl << endl;
 #endif
@@ -867,6 +920,8 @@ bool wxTable::UpdateWhere(char *pWhereClause)
        // Build the SQL UPDATE statement
        GetUpdateStmt(sqlStmt, DB_UPD_WHERE, pWhereClause);
 
+       pDb->WriteSqlLog(sqlStmt);
+
 #ifdef _CONSOLE
        cout << endl << sqlStmt << endl << endl;
 #endif
@@ -884,6 +939,8 @@ bool wxTable::Delete(void)
        // Build the SQL DELETE statement
        GetDeleteStmt(sqlStmt, DB_DEL_KEYFIELDS);
 
+       pDb->WriteSqlLog(sqlStmt);
+
        // Execute the SQL DELETE statement
        return(execDelete(sqlStmt));
 
@@ -897,6 +954,8 @@ bool wxTable::DeleteWhere(char *pWhereClause)
        // Build the SQL DELETE statement
        GetDeleteStmt(sqlStmt, DB_DEL_WHERE, pWhereClause);
 
+       pDb->WriteSqlLog(sqlStmt);
+
        // Execute the SQL DELETE statement
        return(execDelete(sqlStmt));
 
@@ -910,6 +969,8 @@ bool wxTable::DeleteMatching(void)
        // Build the SQL DELETE statement
        GetDeleteStmt(sqlStmt, DB_DEL_MATCHING);
 
+       pDb->WriteSqlLog(sqlStmt);
+
        // Execute the SQL DELETE statement
        return(execDelete(sqlStmt));
 
@@ -979,7 +1040,7 @@ void wxTable::GetUpdateStmt(char *pSqlStmt, int typeOfUpd, char *pWhereClause)
                        // 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, rowid, ROWID_LEN, &cb) == SQL_SUCCESS)
+                       if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, ROWID_LEN, &cb) == SQL_SUCCESS)
                        {
                                strcat(pSqlStmt, "ROWID = '");
                                strcat(pSqlStmt, rowid);
@@ -1031,7 +1092,7 @@ void wxTable::GetDeleteStmt(char *pSqlStmt, int typeOfDel, char *pWhereClause)
                        // 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, rowid, ROWID_LEN, &cb) == SQL_SUCCESS)
+                       if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, ROWID_LEN, &cb) == SQL_SUCCESS)
                        {
                                strcat(pSqlStmt, "ROWID = '");
                                strcat(pSqlStmt, rowid);
@@ -1061,7 +1122,7 @@ void wxTable::GetDeleteStmt(char *pSqlStmt, int typeOfDel, char *pWhereClause)
  *       They are not included as part of the where clause.
  */
 
-void wxTable::GetWhereClause(char *pWhereClause, int typeOfWhere)
+void wxTable::GetWhereClause(char *pWhereClause, int typeOfWhere, char *qualTableName)
 {
        bool moreThanOneColumn = FALSE;
        char colValue[255];
@@ -1082,6 +1143,11 @@ void wxTable::GetWhereClause(char *pWhereClause, int typeOfWhere)
                        else
                                moreThanOneColumn = TRUE;
                        // Concatenate where phrase for the column
+                       if (qualTableName && strlen(qualTableName))
+                       {
+                               strcat(pWhereClause, qualTableName);
+                               strcat(pWhereClause, ".");
+                       }
                        strcat(pWhereClause, colDefs[i].ColName);
                        strcat(pWhereClause, " = ");
                        switch(colDefs[i].SqlCtype)
@@ -1150,9 +1216,11 @@ bool wxTable::IsColNull(int colNo)
 
 bool wxTable::CanSelectForUpdate(void)
 {
+#ifndef __WXGTK__
        if (pDb->dbInf.posStmts & SQL_PS_SELECT_FOR_UPDATE)
                return(TRUE);
        else
+#endif
                return(FALSE);
 
 }  // wxTable::CanSelectForUpdate()
@@ -1161,7 +1229,8 @@ bool wxTable::CanSelectForUpdate(void)
 bool wxTable::CanUpdByROWID(void)
 {
 
-//@@@@@@glt - returning FALSE for testing purposes, as the ROWID is not getting updated correctly
+//NOTE: Returning FALSE for now until this can be debugged,
+//          as the ROWID is not getting updated correctly
        return FALSE;
 
        if ((! strcmp(pDb->dbInf.dbmsName, "Oracle")) || (! strcmp(pDb->dbInf.dbmsName, "ORACLE")))
@@ -1260,7 +1329,8 @@ void wxTable::SetColDefs (int index, char *fieldName, int dataType, void *pData,
                                                                 int cType, int size, bool keyField, bool upd,
                                                                 bool insAllow, bool derivedCol)
 {
-       if (strlen(fieldName) > DB_MAX_COLUMN_NAME_LEN)  // glt 4/21/97
+    // Please, no uint, it doesn't exist for VC++
+       if (strlen(fieldName) > (unsigned int) DB_MAX_COLUMN_NAME_LEN)  // glt 4/21/97
        {
                strncpy (colDefs[index].ColName, fieldName, DB_MAX_COLUMN_NAME_LEN);
                colDefs[index].ColName[DB_MAX_COLUMN_NAME_LEN] = 0;  // glt 10/23/97
@@ -1345,6 +1415,9 @@ ULONG wxTable::Count(void)
        strcpy(sqlStmt, "SELECT COUNT(*) FROM ");
        strcat(sqlStmt, queryTableName);
 
+       if (from && strlen(from))
+               strcat(sqlStmt, from);
+
        // Add the where clause if one is provided
        if (where && strlen(where))
        {
@@ -1352,6 +1425,8 @@ ULONG wxTable::Count(void)
                strcat(sqlStmt, where);
        }
 
+       pDb->WriteSqlLog(sqlStmt);
+
        // Execute the SQL statement
        if (SQLExecDirect(hstmtCount, (UCHAR FAR *) sqlStmt, SQL_NTS) != SQL_SUCCESS)
        {
@@ -1367,7 +1442,7 @@ ULONG wxTable::Count(void)
        }
 
        // Obtain the result
-       if (SQLGetData(hstmtCount, 1, SQL_C_ULONG, &l, sizeof(l), &cb) != SQL_SUCCESS)
+       if (SQLGetData(hstmtCount, 1, SQL_C_ULONG, (UCHAR*) &l, sizeof(l), &cb) != SQL_SUCCESS)
        {
                pDb->DispAllErrors(henv, hdbc, hstmtCount);
                return(0);
@@ -1408,9 +1483,10 @@ bool wxTable::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.
-               if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, rowid, ROWID_LEN, &cb) == SQL_SUCCESS)
+               if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, ROWID_LEN, &cb) == SQL_SUCCESS)
                {
-                       strcat(whereClause, "ROWID = '");
+                       strcat(whereClause, queryTableName);
+                       strcat(whereClause, ".ROWID = '");
                        strcat(whereClause, rowid);
                        strcat(whereClause, "'");
                }
@@ -1418,7 +1494,7 @@ bool wxTable::Refresh(void)
 
        // If unable to use the ROWID, build a where clause from the keyfields
        if (strlen(whereClause) == 0)
-               GetWhereClause(whereClause, DB_WHERE_KEYFIELDS);
+               GetWhereClause(whereClause, DB_WHERE_KEYFIELDS, queryTableName);
 
        // Requery the record
        where = whereClause;
@@ -1442,4 +1518,5 @@ bool wxTable::Refresh(void)
 }  // wxTable::Refresh()
 
 #endif
-    // USE_ODBC
+  // wxUSE_ODBC
+