]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/db.cpp
Mutiple updates from SciTech for wxWindows including the following:
[wxWidgets.git] / src / common / db.cpp
index 39a224f14ce0b4daa5ec741b2e2ee6434e5c8732..c3957c35e6eb2067e9ce9d03f9e20de219706b8a 100644 (file)
 // SYNOPSIS START
 // SYNOPSIS STOP
 */
+#ifdef __GNUG__
+    #pragma implementation "db.h"
+#endif
 
 #include "wx/wxprec.h"
 
-
-// Use this line for wxWindows v1.x
-//#include "wx_ver.h"
-// Use this line for wxWindows v2.x
-#include "wx/version.h"
-
-#if wxMAJOR_VERSION == 2
-    #ifdef __GNUG__
-        #pragma implementation "db.h"
-    #endif
+#ifdef __BORLANDC__
+    #pragma hdrstop
 #endif
 
 #ifdef DBDEBUG_CONSOLE
     #include "wx/ioswrap.h"
 #endif
 
-#ifdef    __BORLANDC__
-    #pragma hdrstop
-#endif  //__BORLANDC__
-
-#if wxMAJOR_VERSION == 2
-    #ifndef WX_PRECOMP
-        #include "wx/string.h"
-        #include "wx/object.h"
-        #include "wx/list.h"
-        #include "wx/utils.h"
+#ifndef WX_PRECOMP
+    #include "wx/string.h"
+    #include "wx/object.h"
+    #include "wx/list.h"
+    #include "wx/utils.h"
+    #if wxUSE_GUI
         #include "wx/msgdlg.h"
-        #include "wx/log.h"
     #endif
-    #include "wx/filefn.h"
-    #include "wx/wxchar.h"
-#endif
-
-
-#if wxMAJOR_VERSION == 1
-#    if defined(wx_msw) || defined(wx_x)
-#        ifdef WX_PRECOMP
-#            include "wx_prec.h"
-#        else
-#            include "wx.h"
-#        endif
-#    endif
-#    define wxUSE_ODBC 1
+    #include "wx/log.h"
 #endif
+#include "wx/filefn.h"
+#include "wx/wxchar.h"
 
 #if wxUSE_ODBC
 
 #include <stdlib.h>
 #include <ctype.h>
 
-#if   wxMAJOR_VERSION == 1
-    #include "db.h"
-#elif wxMAJOR_VERSION == 2
-    #include "wx/db.h"
-#endif
+#include "wx/db.h"
 
 WXDLLEXPORT_DATA(wxDbList*) PtrBegDbList = 0;
 
@@ -121,6 +96,7 @@ static wxString SQLLOGfn = SQL_LOG_FILENAME;
 // connection
 wxChar DBerrorList[DB_MAX_ERROR_HISTORY][DB_MAX_ERROR_MSG_LEN];
 
+
 // This type defines the return row-struct form
 // SQLTablePrivileges, and is used by wxDB::TablePrivileges.
 typedef struct
@@ -475,7 +451,7 @@ bool wxDbInf::Initialize()
 }  // wxDbInf::Initialize()
 
 
-/********** wxDb Constructors **********/
+/********** wxDb Constructor **********/
 wxDb::wxDb(const HENV &aHenv, bool FwdOnlyCursors)
 {
     // Copy the HENV into the db class
@@ -486,6 +462,19 @@ wxDb::wxDb(const HENV &aHenv, bool FwdOnlyCursors)
 } // wxDb::wxDb()
 
 
+/********** wxDb Destructor **********/
+wxDb::~wxDb()
+{
+    wxASSERT_MSG(!IsCached(),wxT("Cached connections must not be manually deleted, use\nwxDbFreeConnection() or wxDbCloseConnections()."));
+
+    if (IsOpen())
+    {
+        Close();
+    }
+}  // wxDb destructor
+
+
+
 /********** PRIVATE! wxDb::initialize PRIVATE! **********/
 /********** wxDb::initialize() **********/
 void wxDb::initialize()
@@ -550,6 +539,7 @@ void wxDb::initialize()
 
     // Mark database as not open as of yet
     dbIsOpen = FALSE;
+    dbIsCached = FALSE;
 }  // wxDb::initialize()
 
 
@@ -613,15 +603,6 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt
                          (UCHAR FAR *) uid.c_str(), SQL_NTS,
                          (UCHAR FAR *) authStr.c_str(), SQL_NTS);
 
-/*
-    if (retcode == SQL_SUCCESS_WITH_INFO)
-        DispAllErrors(henv, hdbc);
-    else if (retcode != SQL_SUCCESS)
-        return(DispAllErrors(henv, hdbc));
-
-    if (retcode == SQL_ERROR)
-        return(DispAllErrors(henv, hdbc));
-*/
     if ((retcode != SQL_SUCCESS) &&
         (retcode != SQL_SUCCESS_WITH_INFO))
         return(DispAllErrors(henv, hdbc));
@@ -733,7 +714,7 @@ bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthSt
     // Date/Time
     if (Dbms() != dbmsDBASE)
     {
-        if (! getDataTypeInfo(SQL_TIMESTAMP,typeInfDate))
+        if (!getDataTypeInfo(SQL_TIMESTAMP,typeInfDate))
             return(FALSE);
         else
             typeInfDate.FsqlType = SQL_TIMESTAMP;
@@ -1415,7 +1396,7 @@ void wxDb::Close(void)
         {
             s.Printf(wxT("(%-20s)     tableID:[%6lu]     pDb:[%p]"), tiu->tableName,tiu->tableID,tiu->pDb);
             s2.Printf(wxT("Orphaned found using pDb:[%p]"),this);
-            wxLogDebug (s,s2);
+            wxLogDebug (s.c_str(),s2.c_str());
         }
         pNode = pNode->Next();
     }
@@ -1426,7 +1407,7 @@ void wxDb::Close(void)
     for (i = 0; i < DB_MAX_ERROR_HISTORY; i++)
         wxStrcpy(DBerrorList[i], errorList[i]);
 
-    dbmsType    = dbmsUNIDENTIFIED;
+    dbmsType = dbmsUNIDENTIFIED;
     dbIsOpen = FALSE;
 
 } // wxDb::Close()
@@ -1499,7 +1480,7 @@ bool wxDb::DispAllErrors(HENV aHenv, HDBC aHdbc, HSTMT aHstmt)
         }
     }
 
-    return(FALSE);  // This function always returns false.
+    return(FALSE);  // This function always returns FALSE.
 
 } // wxDb::DispAllErrors()
 
@@ -1794,7 +1775,7 @@ bool wxDb::Grant(int privileges, const wxString &tableName, const wxString &user
     }
 
     sqlStmt += wxT(" ON ");
-    sqlStmt += tableName;
+    sqlStmt += SQLTableName(tableName);
     sqlStmt += wxT(" TO ");
     sqlStmt += userList;
 
@@ -1881,7 +1862,7 @@ bool wxDb::DropView(const wxString &viewName)
     }
 
     // Commit the transaction
-    if (! CommitTrans())
+    if (!CommitTrans())
         return(FALSE);
 
     return TRUE;
@@ -2112,7 +2093,7 @@ wxDbColInf *wxDb::GetColumns(wxChar *tableName[], const wxChar *userID)
  */
 {
     UWORD       noCols = 0;
-    UWORD        colNo  = 0;
+    UWORD       colNo  = 0;
     wxDbColInf *colInf = 0;
 
     RETCODE  retcode;
@@ -2697,7 +2678,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh
     // Build a generic SELECT statement which returns 0 rows
     wxString Stmt;
 
-    Stmt.Printf(wxT("select * from %s where 0=1"), tableName);
+    Stmt.Printf(wxT("select * from \"%s\" where 0=1"), tableName);
 
     // Execute query
     if (SQLExecDirect(hstmt, (UCHAR FAR *) Stmt.c_str(), SQL_NTS) != SQL_SUCCESS)
@@ -2769,7 +2750,7 @@ wxDbColInf *wxDb::GetColumns(const wxString &tableName, int *numCols, const wxCh
 
 
 /********** wxDb::GetColumnCount() **********/
-UWORD wxDb::GetColumnCount(const wxString &tableName, const wxChar *userID)
+int wxDb::GetColumnCount(const wxString &tableName, const wxChar *userID)
 /*
  * Returns a count of how many columns are in a table.
  * If an error occurs in computing the number of columns
@@ -2990,7 +2971,7 @@ bool wxDb::Catalog(const wxChar *userID, const wxString &fileName)
     wxChar    colName[DB_MAX_COLUMN_NAME_LEN+1];
     SWORD     sqlDataType;
     wxChar    typeName[30+1];
-    SWORD     precision, length;
+    SDWORD    precision, length;
 
     FILE *fp = fopen(fileName.c_str(),wxT("wt"));
     if (fp == NULL)
@@ -3032,8 +3013,12 @@ bool wxDb::Catalog(const wxChar *userID, const wxString &fileName)
     tblNameSave.Empty();
     int cnt = 0;
 
-    while ((retcode = SQLFetch(hstmt)) == SQL_SUCCESS)
+    while (TRUE)
     {
+        retcode = SQLFetch(hstmt);
+        if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
+            break;
+
         if (wxStrcmp(tblName, tblNameSave.c_str()))
         {
             if (cnt)
@@ -3054,12 +3039,12 @@ bool wxDb::Catalog(const wxChar *userID, const wxString &fileName)
             tblNameSave = tblName;
         }
 
-      GetData(3,SQL_C_CHAR,  (UCHAR *)tblName,     DB_MAX_TABLE_NAME_LEN+1, &cb);
-      GetData(4,SQL_C_CHAR,  (UCHAR *)colName,     DB_MAX_COLUMN_NAME_LEN+1,&cb);
-      GetData(5,SQL_C_SSHORT,(UCHAR *)&sqlDataType,0,                       &cb);
-      GetData(6,SQL_C_CHAR,  (UCHAR *)typeName,    sizeof(typeName),        &cb);
-      GetData(7,SQL_C_SSHORT,(UCHAR *)&precision,  0,                       &cb);
-      GetData(8,SQL_C_SSHORT,(UCHAR *)&length,     0,                       &cb);
+      GetData(3,SQL_C_CHAR,  (UCHAR *) tblName,     DB_MAX_TABLE_NAME_LEN+1, &cb);
+      GetData(4,SQL_C_CHAR,  (UCHAR *) colName,     DB_MAX_COLUMN_NAME_LEN+1,&cb);
+      GetData(5,SQL_C_SSHORT,(UCHAR *)&sqlDataType, 0,                       &cb);
+      GetData(6,SQL_C_CHAR,  (UCHAR *) typeName,    sizeof(typeName),        &cb);
+      GetData(7,SQL_C_SLONG, (UCHAR *)&precision,   0,                       &cb);
+      GetData(8,SQL_C_SLONG, (UCHAR *)&length,      0,                       &cb);
 
         outStr.Printf(wxT("%-32s %-32s (%04d)%-15s %9d %9d\n"),
             tblName, colName, sqlDataType, typeName, precision, length);
@@ -3085,7 +3070,7 @@ bool wxDb::Catalog(const wxChar *userID, const wxString &fileName)
 
 bool wxDb::TableExists(const wxString &tableName, const wxChar *userID, const wxString &tablePath)
 /*
- * Table name can refer to a table, view, alias or synonym.  Returns true
+ * Table name can refer to a table, view, alias or synonym.  Returns TRUE
  * if the object exists in the database.  This function does not indicate
  * whether or not the user has privleges to query or perform other functions
  * on the table.
@@ -3287,6 +3272,34 @@ bool wxDb::TablePrivileges(const wxString &tableName, const wxString &priv, cons
 }  // wxDb::TablePrivileges
 
 
+const wxString wxDb::SQLTableName(const char *tableName)
+{
+    wxString TableName;
+
+    if (Dbms() == dbmsACCESS)
+        TableName = '"';
+    TableName += tableName;
+    if (Dbms() == dbmsACCESS)
+        TableName += '"';
+
+    return TableName;
+}  // wxDb::SQLTableName()
+
+
+const wxString wxDb::SQLColumnName(const char *colName)
+{
+    wxString ColName;
+
+    if (Dbms() == dbmsACCESS)
+        ColName = '"';
+    ColName += colName;
+    if (Dbms() == dbmsACCESS)
+        ColName += '"';
+
+    return ColName;
+}  // wxDb::SQLColumnName()
+
+
 /********** wxDb::SetSqlLogging() **********/
 bool wxDb::SetSqlLogging(wxDbSqlLogState state, const wxString &filename, bool append)
 {
@@ -3535,7 +3548,7 @@ bool wxDb::ModifyColumn(const wxString &tableName, const wxString &columnName,
     }
 
     // create the SQL statement
-    sqlStmt.Printf(wxT("ALTER TABLE %s %s %s %s"), tableName.c_str(), alterSlashModify.c_str(),
+    sqlStmt.Printf(wxT("ALTER TABLE \"%s\" \"%s\" \"%s\" %s"), tableName.c_str(), alterSlashModify.c_str(),
               columnName.c_str(), dataTypeName.c_str());
 
     // For varchars only, append the size of the column
@@ -3611,7 +3624,7 @@ wxDb WXDLLEXPORT *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCurso
     // Initialize new node in the linked list
     pList->PtrNext  = 0;
     pList->Free     = FALSE;
-    pList->Dsn      = pDbConfig->GetDsn();   //glt - will this assignment work?
+    pList->Dsn      = pDbConfig->GetDsn();
     pList->Uid      = pDbConfig->GetUserID();
     pList->AuthStr  = pDbConfig->GetPassword();
 
@@ -3627,6 +3640,7 @@ wxDb WXDLLEXPORT *wxDbGetConnection(wxDbConnectInf *pDbConfig, bool FwdOnlyCurso
     // Connect to the datasource
     if (opened)
     {
+        pList->PtrDb->setCached(TRUE);  // Prevent a user from deleting a cached connection
         pList->PtrDb->SetSqlLogging(SQLLOGstate,SQLLOGfn,TRUE);
         return(pList->PtrDb);
     }
@@ -3675,6 +3689,7 @@ void WXDLLEXPORT wxDbCloseConnections(void)
         pNext = pList->PtrNext;       // Save the pointer to next
         pList->PtrDb->CommitTrans();  // Commit any open transactions on wxDb object
         pList->PtrDb->Close();        // Close the wxDb object
+        pList->PtrDb->setCached(FALSE);  // Allows deletion of the wxDb instance
         delete pList->PtrDb;          // Deletes the wxDb object
         delete pList;                 // Deletes the linked list object
     }
@@ -3703,6 +3718,52 @@ int WXDLLEXPORT wxDbConnectionsInUse(void)
 }  // wxDbConnectionsInUse()
 
 
+
+/********** wxDbLogExtendedErrorMsg() **********/
+// DEBUG ONLY function
+const wxChar WXDLLEXPORT *wxDbLogExtendedErrorMsg(const wxChar *userText, wxDb *pDb,
+                             char *ErrFile, int ErrLine)
+{
+    static wxString msg;
+    msg = userText;
+
+    wxString tStr;
+
+    if (ErrFile || ErrLine)
+    {
+        msg += wxT("File: ");
+        msg += ErrFile;
+        msg += wxT("   Line: ");
+        tStr.Printf(wxT("%d"),ErrLine);
+        msg += tStr.c_str();
+        msg += wxT("\n");
+    }
+
+    msg.Append (wxT("\nODBC errors:\n"));
+    msg += wxT("\n");
+
+    // Display errors for this connection
+    int i;
+    for (i = 0; i < DB_MAX_ERROR_HISTORY; i++)
+    {
+        if (pDb->errorList[i])
+        {
+            msg.Append(pDb->errorList[i]);
+            if (wxStrcmp(pDb->errorList[i],wxT("")) != 0)
+                msg.Append(wxT("\n"));
+            // Clear the errmsg buffer so the next error will not
+            // end up showing the previous error that have occurred
+            wxStrcpy(pDb->errorList[i],wxT(""));
+        }
+    }
+    msg += wxT("\n");
+
+    wxLogDebug(msg.c_str());
+
+    return msg.c_str();
+}  // wxDbLogExtendedErrorMsg()
+
+
 /********** wxDbSqlLog() **********/
 bool wxDbSqlLog(wxDbSqlLogState state, const wxChar *filename)
 {