]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/db/dbtest.cpp
interface additions (mostly for new generic/toolwin)
[wxWidgets.git] / samples / db / dbtest.cpp
index b859661ca3d573b092145608295c2098cb4106d7..9643f3dff5aa2097586bf9455ec0ac0bf2416c00 100644 (file)
@@ -16,7 +16,7 @@
     donated by the development team at Remstar International.
 
     The table this sample is based on is developer contact table, and shows
     donated by the development team at Remstar International.
 
     The table this sample is based on is developer contact table, and shows
-    some of the simple uses of the database classes wxDB and wxTable.
+    some of the simple uses of the database classes wxDb and wxDbTable.
 
  *  SYNOPSIS END
  */
 
  *  SYNOPSIS END
  */
@@ -42,9 +42,9 @@
 #include <stdio.h>                  /* Included strictly for reading the text file with the database parameters */
 
 #include <wx/db.h>                  /* Required in the file which will get the data source connection */
 #include <stdio.h>                  /* Included strictly for reading the text file with the database parameters */
 
 #include <wx/db.h>                  /* Required in the file which will get the data source connection */
-#include <wx/dbtable.h>             /* Has the wxTable object from which all data objects will inherit their data table functionality */
+#include <wx/dbtable.h>             /* Has the wxDbTable object from which all data objects will inherit their data table functionality */
 
 
-extern DbList WXDLLEXPORT *PtrBegDbList;    /* from db.cpp, used in getting back error results from db connections */
+extern wxDbList WXDLLEXPORT *PtrBegDbList;    /* from db.cpp, used in getting back error results from db connections */
 
 #include "dbtest.h"                 /* Header file for this demonstration program */
 #include "listdb.h"                 /* Code to support the "Lookup" button on the editor dialog */
 
 #include "dbtest.h"                 /* Header file for this demonstration program */
 #include "listdb.h"                 /* Code to support the "Lookup" button on the editor dialog */
@@ -61,28 +61,29 @@ DatabaseDemoFrame *DemoFrame;       /* Pointer to the main frame */
  * for user login names and passwords, getting workstation settings, etc.
  * ---> IMPORTANT <---
  * 
  * for user login names and passwords, getting workstation settings, etc.
  * ---> IMPORTANT <---
  * 
- *        For each database object created which uses this wxDB pointer
+ *        For each database object created which uses this wxDb pointer
  *    connection to the database, when a CommitTrans() or RollBackTrans()
  *    connection to the database, when a CommitTrans() or RollBackTrans()
- *    will commit or rollback EVERY object which uses this wxDB pointer.
+ *    will commit or rollback EVERY object which uses this wxDb pointer.
  *
  *
- *    To allow each table object (those derived from wxTable) to be 
+ *    To allow each table object (those derived from wxDbTable) to be 
  *    individually committed or rolled back, you MUST use a different
  *    individually committed or rolled back, you MUST use a different
- *    instance of wxDB in the constructor of the table.  Doing so creates 
+ *    instance of wxDb in the constructor of the table.  Doing so creates 
  *        more overhead, and will use more database connections (some DBs have
  *    connection limits...), so use connections sparringly.
  *
  *        It is recommended that one "main" database connection be created for
  *        the entire program to use for READ-ONLY database accesses, but for each
  *        table object which will do a CommitTrans() or RollbackTrans() that a
  *        more overhead, and will use more database connections (some DBs have
  *    connection limits...), so use connections sparringly.
  *
  *        It is recommended that one "main" database connection be created for
  *        the entire program to use for READ-ONLY database accesses, but for each
  *        table object which will do a CommitTrans() or RollbackTrans() that a
- *        new wxDB object be created and used for it.
+ *        new wxDb object be created and used for it.
  */
  
  */
  
-wxDB    *READONLY_DB;
+wxDb    *READONLY_DB;
 
 /*
  * This function will return the exact string(s) from the database engine
  * indicating all error conditions which have just occured during the
 
 /*
  * This function will return the exact string(s) from the database engine
  * indicating all error conditions which have just occured during the
- * last call to the database engine.
+ * last call to the database engine for the database connection pointed
+ * to by pDb.
  *
  * This demo uses the returned string by displaying it in a wxMessageBox.  The
  * formatting therefore is not the greatest, but this is just a demo, not a
  *
  * This demo uses the returned string by displaying it in a wxMessageBox.  The
  * formatting therefore is not the greatest, but this is just a demo, not a
@@ -91,9 +92,10 @@ wxDB    *READONLY_DB;
  * NOTE: The value returned by this function is for temporary use only and
  *       should be copied for long term use
  */
  * NOTE: The value returned by this function is for temporary use only and
  *       should be copied for long term use
  */
-char *GetExtendedDBErrorMsg(char *ErrFile, int ErrLine)
+const char *GetExtendedDBErrorMsg(wxDb *pDb, char *ErrFile, int ErrLine)
 {
     static wxString msg;
 {
     static wxString msg;
+    msg = "";
 
     wxString tStr;
 
 
     wxString tStr;
 
@@ -103,35 +105,30 @@ char *GetExtendedDBErrorMsg(char *ErrFile, int ErrLine)
         msg += ErrFile;
         msg += "   Line: ";
         tStr.Printf("%d",ErrLine);
         msg += ErrFile;
         msg += "   Line: ";
         tStr.Printf("%d",ErrLine);
-        msg += tStr.GetData();
+        msg += tStr.c_str();
         msg += "\n";
     }
 
     msg.Append ("\nODBC errors:\n");
     msg += "\n";
     
         msg += "\n";
     }
 
     msg.Append ("\nODBC errors:\n");
     msg += "\n";
     
-    /* Scan through each database connection displaying 
-     * any ODBC errors that have occured. */
-    for (DbList *pDbList = PtrBegDbList; pDbList; pDbList = pDbList->PtrNext)
-    {
-        // Skip over any free connections
-        if (pDbList->Free)
-            continue;
-        // Display errors for this connection
-        int i;
-        for (i = 0; i < DB_MAX_ERROR_HISTORY; i++)
+    // Display errors for this connection
+    int i;
+    for (i = 0; i < DB_MAX_ERROR_HISTORY; i++)
+    {
+        if (pDb->errorList[i])
         {
         {
-            if (pDbList->PtrDb->errorList[i])
-            {
-                msg.Append(pDbList->PtrDb->errorList[i]);
-                if (strcmp(pDbList->PtrDb->errorList[i],"") != 0)
-                    msg.Append("\n");
-            }
+            msg.Append(pDb->errorList[i]);
+            if (wxStrcmp(pDb->errorList[i],"") != 0)
+                msg.Append("\n");
+            // Clear the errmsg buffer so the next error will not
+            // end up showing the previous error that have occurred
+            wxStrcpy(pDb->errorList[i],"");
         }
     }
     msg += "\n";
 
         }
     }
     msg += "\n";
 
-    return (char*) (const char*) msg;
+    return msg.c_str();
 }  // GetExtendedDBErrorMsg
 
 
 }  // GetExtendedDBErrorMsg
 
 
@@ -145,7 +142,9 @@ bool DatabaseDemoApp::OnInit()
 
     // Make a menubar
     wxMenu *file_menu = new wxMenu;
 
     // Make a menubar
     wxMenu *file_menu = new wxMenu;
-    file_menu->Append(FILE_CREATE, "&Create contact table");
+    file_menu->Append(FILE_CREATE, "&Create CONTACT table");
+    file_menu->Append(FILE_RECREATE_TABLE, "&Recreate CONTACT table");
+    file_menu->Append(FILE_RECREATE_INDEXES, "&Recreate CONTACT indexes");
     file_menu->Append(FILE_EXIT, "E&xit");
 
     wxMenu *edit_menu = new wxMenu;
     file_menu->Append(FILE_EXIT, "E&xit");
 
     wxMenu *edit_menu = new wxMenu;
@@ -172,6 +171,9 @@ bool DatabaseDemoApp::OnInit()
     params.Password[0]   = 0;
     params.DirPath[0]    = 0;
 
     params.Password[0]   = 0;
     params.DirPath[0]    = 0;
 
+    // Show the frame
+    DemoFrame->Show(TRUE);
+
     FILE *paramFile;
     if ((paramFile = fopen(paramFilename, "r")) == NULL)
     {
     FILE *paramFile;
     if ((paramFile = fopen(paramFilename, "r")) == NULL)
     {
@@ -186,37 +188,37 @@ bool DatabaseDemoApp::OnInit()
 
     char buffer[1000+1];
     fgets(buffer, sizeof(params.ODBCSource), paramFile);
 
     char buffer[1000+1];
     fgets(buffer, sizeof(params.ODBCSource), paramFile);
-    buffer[strlen(buffer)-1] = '\0';
-    strcpy(params.ODBCSource,buffer);
+    buffer[wxStrlen(buffer)-1] = '\0';
+    wxStrcpy(params.ODBCSource,buffer);
 
     fgets(buffer, sizeof(params.UserName), paramFile);
 
     fgets(buffer, sizeof(params.UserName), paramFile);
-    buffer[strlen(buffer)-1] = '\0';
-    strcpy(params.UserName,buffer);
+    buffer[wxStrlen(buffer)-1] = '\0';
+    wxStrcpy(params.UserName,buffer);
 
     fgets(buffer, sizeof(params.Password), paramFile);
 
     fgets(buffer, sizeof(params.Password), paramFile);
-    buffer[strlen(buffer)-1] = '\0';
-    strcpy(params.Password,buffer);
+    buffer[wxStrlen(buffer)-1] = '\0';
+    wxStrcpy(params.Password,buffer);
 
     fgets(buffer, sizeof(params.DirPath), paramFile);
 
     fgets(buffer, sizeof(params.DirPath), paramFile);
-    buffer[strlen(buffer)-1] = '\0';
-    strcpy(params.DirPath,buffer);
+    buffer[wxStrlen(buffer)-1] = '\0';
+    wxStrcpy(params.DirPath,buffer);
 
     fclose(paramFile);
 
     // Connect to datasource
 
     fclose(paramFile);
 
     // Connect to datasource
-    strcpy(DbConnectInf.Dsn,        params.ODBCSource);    // ODBC data source name (created with ODBC Administrator under Win95/NT)
-    strcpy(DbConnectInf.Uid,        params.UserName);      // database username - must already exist in the data source
-    strcpy(DbConnectInf.AuthStr,    params.Password);      // password database username
-    strcpy(DbConnectInf.defaultDir, params.DirPath);       // path where the table exists (needed for dBase)
+    wxStrcpy(DbConnectInf.Dsn,        params.ODBCSource);    // ODBC data source name (created with ODBC Administrator under Win95/NT)
+    wxStrcpy(DbConnectInf.Uid,        params.UserName);      // database username - must already exist in the data source
+    wxStrcpy(DbConnectInf.AuthStr,    params.Password);      // password database username
+    wxStrcpy(DbConnectInf.defaultDir, params.DirPath);       // path where the table exists (needed for dBase)
 
 
-    READONLY_DB = GetDbConnection(&DbConnectInf);
+    READONLY_DB = wxDbGetConnection(&DbConnectInf);
     if (READONLY_DB == 0)
     {
         wxMessageBox("Unable to connect to the data source.\n\nCheck the name of your data source to verify it has been correctly entered/spelled.\n\nWith some databases, the user name and password must\nbe created with full rights to the CONTACT table prior to making a connection\n(using tools provided by the database manufacturer)", "DB CONNECTION ERROR...",wxOK | wxICON_EXCLAMATION);
         DemoFrame->BuildParameterDialog(NULL);
     if (READONLY_DB == 0)
     {
         wxMessageBox("Unable to connect to the data source.\n\nCheck the name of your data source to verify it has been correctly entered/spelled.\n\nWith some databases, the user name and password must\nbe created with full rights to the CONTACT table prior to making a connection\n(using tools provided by the database manufacturer)", "DB CONNECTION ERROR...",wxOK | wxICON_EXCLAMATION);
         DemoFrame->BuildParameterDialog(NULL);
-        strcpy(DbConnectInf.Dsn,        "");
-        strcpy(DbConnectInf.Uid,        "");
-        strcpy(DbConnectInf.AuthStr,    "");
+        wxStrcpy(DbConnectInf.Dsn,        "");
+        wxStrcpy(DbConnectInf.Uid,        "");
+        wxStrcpy(DbConnectInf.AuthStr,    "");
         wxMessageBox("Now exiting program.\n\nRestart program to try any new settings.","Notice...",wxOK | wxICON_INFORMATION);
         return(FALSE);
     }
         wxMessageBox("Now exiting program.\n\nRestart program to try any new settings.","Notice...",wxOK | wxICON_INFORMATION);
         return(FALSE);
     }
@@ -224,36 +226,77 @@ bool DatabaseDemoApp::OnInit()
     DemoFrame->BuildEditorDialog();
 
     // Show the frame
     DemoFrame->BuildEditorDialog();
 
     // Show the frame
-    DemoFrame->Show(TRUE);
+    DemoFrame->Refresh();
 
     return TRUE;
 }  // DatabaseDemoApp::OnInit()
 
 
     return TRUE;
 }  // DatabaseDemoApp::OnInit()
 
+
 BEGIN_EVENT_TABLE(DatabaseDemoFrame, wxFrame)
     EVT_MENU(FILE_CREATE, DatabaseDemoFrame::OnCreate)
 BEGIN_EVENT_TABLE(DatabaseDemoFrame, wxFrame)
     EVT_MENU(FILE_CREATE, DatabaseDemoFrame::OnCreate)
+    EVT_MENU(FILE_RECREATE_TABLE, DatabaseDemoFrame::OnRecreateTable)
+    EVT_MENU(FILE_RECREATE_INDEXES, DatabaseDemoFrame::OnRecreateIndexes)
     EVT_MENU(FILE_EXIT, DatabaseDemoFrame::OnExit)
     EVT_MENU(EDIT_PARAMETERS, DatabaseDemoFrame::OnEditParameters)
     EVT_MENU(ABOUT_DEMO, DatabaseDemoFrame::OnAbout)
     EVT_CLOSE(DatabaseDemoFrame::OnCloseWindow)
 END_EVENT_TABLE()
 
     EVT_MENU(FILE_EXIT, DatabaseDemoFrame::OnExit)
     EVT_MENU(EDIT_PARAMETERS, DatabaseDemoFrame::OnEditParameters)
     EVT_MENU(ABOUT_DEMO, DatabaseDemoFrame::OnAbout)
     EVT_CLOSE(DatabaseDemoFrame::OnCloseWindow)
 END_EVENT_TABLE()
 
+
 // DatabaseDemoFrame constructor
 DatabaseDemoFrame::DatabaseDemoFrame(wxFrame *frame, const wxString& title,
 // DatabaseDemoFrame constructor
 DatabaseDemoFrame::DatabaseDemoFrame(wxFrame *frame, const wxString& title,
-  const wxPoint& pos, const wxSize& size):
-  wxFrame(frame, -1, title, pos, size)
+                                     const wxPoint& pos, const wxSize& size):
+                                        wxFrame(frame, -1, title, pos, size)
 {
 {
-// Put any code in necessary for initializing the main frame here
-}
+    // Put any code in necessary for initializing the main frame here
+    pEditorDlg = NULL;
+    pParamDlg  = NULL;
+}  // DatabaseDemoFrame constructor
+
 
 void DatabaseDemoFrame::OnCreate(wxCommandEvent& event)
 {
 
 void DatabaseDemoFrame::OnCreate(wxCommandEvent& event)
 {
-    CreateDataTable();
-}
+    CreateDataTable(FALSE);
+}  // DatabaseDemoFrame::OnCreate()
+
+
+void DatabaseDemoFrame::OnRecreateTable(wxCommandEvent& event)
+{
+    CreateDataTable(TRUE);
+}  // DatabaseDemoFrame::OnRecreate()
+
+
+void DatabaseDemoFrame::OnRecreateIndexes(wxCommandEvent& event)
+{
+    // Using a new connection to the database so as not to disturb
+    // the current cursors on the table in use in the editor dialog
+    Ccontact *Contact = new Ccontact();
+
+    if (!Contact)
+    {
+        wxEndBusyCursor();
+        wxMessageBox("Error allocating memory for 'Ccontact'object.\n\nTable could not be opened.","Error...",wxOK | wxICON_EXCLAMATION);
+        return;
+    }
+
+    if (!Contact->CreateIndexes())
+    {
+       wxEndBusyCursor();
+       wxString tStr;
+       tStr  = "Error creating CONTACTS indexes.\nNew indexes will be unavailable.\n\n";
+       tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
+       wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
+    }
+
+    delete Contact;
+    Contact = NULL;
+}  // DatabaseDemoFrame::OnRecreateIndexes()
 
 void DatabaseDemoFrame::OnExit(wxCommandEvent& event)
 {
 
 void DatabaseDemoFrame::OnExit(wxCommandEvent& event)
 {
-    this->Destroy();
-}
+    Close();
+}  // DatabaseDemoFrame::OnExit()
+
 
 void DatabaseDemoFrame::OnEditParameters(wxCommandEvent& event)
 {
 
 void DatabaseDemoFrame::OnEditParameters(wxCommandEvent& event)
 {
@@ -261,25 +304,49 @@ void DatabaseDemoFrame::OnEditParameters(wxCommandEvent& event)
         BuildParameterDialog(this);
     else
         wxMessageBox("Cannot change database parameters while creating or editing a record","Notice...",wxOK | wxICON_INFORMATION);
         BuildParameterDialog(this);
     else
         wxMessageBox("Cannot change database parameters while creating or editing a record","Notice...",wxOK | wxICON_INFORMATION);
-}
+}  // DatabaseDemoFrame::OnEditParameters()
+
 
 void DatabaseDemoFrame::OnAbout(wxCommandEvent& event)
 {
     wxMessageBox("wxWindows sample program for database classes\n\nContributed on 27 July 1998","About...",wxOK | wxICON_INFORMATION);
 
 void DatabaseDemoFrame::OnAbout(wxCommandEvent& event)
 {
     wxMessageBox("wxWindows sample program for database classes\n\nContributed on 27 July 1998","About...",wxOK | wxICON_INFORMATION);
-}
+}  // DatabaseDemoFrame::OnAbout()
+
 
 void DatabaseDemoFrame::OnCloseWindow(wxCloseEvent& event)
 {
     // Put any additional checking necessary to make certain it is alright
     // to close the program here that is not done elsewhere
 
 
 void DatabaseDemoFrame::OnCloseWindow(wxCloseEvent& event)
 {
     // Put any additional checking necessary to make certain it is alright
     // to close the program here that is not done elsewhere
 
+    // Clean up time
+    if (pEditorDlg && pEditorDlg->Close())
+        pEditorDlg = NULL;
+    else
+    {
+        if (pEditorDlg)
+        {
+            event.Veto();
+            return;
+        }
+    }
+
+    // This function will close all the connections to the database that have been
+    // previously cached.
+    wxDbCloseConnections();
+
+    // Cleans up the environment space allocated for the SQL/ODBC connection handle
+    SQLFreeEnv(DbConnectInf.Henv);
+
     this->Destroy();
     this->Destroy();
+
 }  // DatabaseDemoFrame::OnCloseWindow()
 
 
 }  // DatabaseDemoFrame::OnCloseWindow()
 
 
-void DatabaseDemoFrame::CreateDataTable()
+void DatabaseDemoFrame::CreateDataTable(bool recreate)
 {
 {
-    bool Ok = (wxMessageBox("Any data currently residing in the table will be erased.\n\nAre you sure?","Confirm",wxYES_NO|wxICON_QUESTION) == wxYES);
+    bool Ok = TRUE;
+    if (recreate)
+       Ok = (wxMessageBox("Any data currently residing in the table will be erased.\n\nAre you sure?","Confirm",wxYES_NO|wxICON_QUESTION) == wxYES);
 
     if (!Ok)
         return;
 
     if (!Ok)
         return;
@@ -296,23 +363,23 @@ void DatabaseDemoFrame::CreateDataTable()
         return;
     }
 
         return;
     }
 
-    if (!Contact->CreateTable(FALSE))
+    if (!Contact->CreateTable(recreate))
     {
         wxEndBusyCursor();
         wxString tStr;
         tStr  = "Error creating CONTACTS table.\nTable was not created.\n\n";
     {
         wxEndBusyCursor();
         wxString tStr;
         tStr  = "Error creating CONTACTS table.\nTable was not created.\n\n";
-        tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+        tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
         wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
         success = FALSE;
     }
         wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
         success = FALSE;
     }
-     else
+    else
     {
         if (!Contact->CreateIndexes())
         {
             wxEndBusyCursor();
             wxString tStr;
             tStr  = "Error creating CONTACTS indexes.\nIndexes will be unavailable.\n\n";
     {
         if (!Contact->CreateIndexes())
         {
             wxEndBusyCursor();
             wxString tStr;
             tStr  = "Error creating CONTACTS indexes.\nIndexes will be unavailable.\n\n";
-            tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+            tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
             success = FALSE;
         }
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
             success = FALSE;
         }
@@ -321,6 +388,7 @@ void DatabaseDemoFrame::CreateDataTable()
         wxEndBusyCursor();
 
     delete Contact;
         wxEndBusyCursor();
 
     delete Contact;
+     Contact = NULL;
 
     if (success)
         wxMessageBox("Table and index(es) were successfully created.","Notice...",wxOK | wxICON_INFORMATION);
 
     if (success)
         wxMessageBox("Table and index(es) were successfully created.","Notice...",wxOK | wxICON_INFORMATION);
@@ -329,9 +397,24 @@ void DatabaseDemoFrame::CreateDataTable()
 
 void DatabaseDemoFrame::BuildEditorDialog()
 {
 
 void DatabaseDemoFrame::BuildEditorDialog()
 {
+    pEditorDlg = NULL;
     pEditorDlg = new CeditorDlg(this);
     pEditorDlg = new CeditorDlg(this);
-    if (!pEditorDlg)
+    if (pEditorDlg)
+    {
+        pEditorDlg->Initialize();
+        if (!pEditorDlg->initialized)
+        {
+            pEditorDlg->Close();
+            delete pEditorDlg;
+            wxMessageBox("Unable to initialize the editor dialog for some reason","Error...",wxOK | wxICON_EXCLAMATION);
+            DemoFrame->Close();
+        }
+    } 
+    else
+    {
         wxMessageBox("Unable to create the editor dialog for some reason","Error...",wxOK | wxICON_EXCLAMATION);
         wxMessageBox("Unable to create the editor dialog for some reason","Error...",wxOK | wxICON_EXCLAMATION);
+        DemoFrame->Close();
+    }
 }  // DatabaseDemoFrame::BuildEditorDialog()
 
 
 }  // DatabaseDemoFrame::BuildEditorDialog()
 
 
@@ -345,24 +428,24 @@ void DatabaseDemoFrame::BuildParameterDialog(wxWindow *parent)
 
 
 /*
 
 
 /*
- * Constructor note: If no wxDB object is passed in, a new connection to the database
+ * Constructor note: If no wxDb object is passed in, a new connection to the database
  *     is created for this instance of Ccontact.  This can be a slow process depending
  *     on the database engine being used, and some database engines have a limit on the
  *     number of connections (either hard limits, or license restricted) so care should 
  *     be used to use as few connections as is necessary.  
  *
  *     is created for this instance of Ccontact.  This can be a slow process depending
  *     on the database engine being used, and some database engines have a limit on the
  *     number of connections (either hard limits, or license restricted) so care should 
  *     be used to use as few connections as is necessary.  
  *
- * IMPORTANT: Objects which share a wxDB pointer are ALL acted upon whenever a member 
+ * IMPORTANT: Objects which share a wxDb pointer are ALL acted upon whenever a member 
  *     function of pDb is called (i.e. CommitTrans() or RollbackTrans(), so if modifying 
  *     or creating a table objects which use the same pDb, know that all the objects
  *     will be committed or rolled back when any of the objects has this function call made.
  */
  *     function of pDb is called (i.e. CommitTrans() or RollbackTrans(), so if modifying 
  *     or creating a table objects which use the same pDb, know that all the objects
  *     will be committed or rolled back when any of the objects has this function call made.
  */
-Ccontact::Ccontact (wxDB *pwxDB) : wxTable(pwxDB ? pwxDB : GetDbConnection(&DbConnectInf),CONTACT_TABLE_NAME,CONTACT_NO_COLS,NULL,!QUERY_ONLY,DbConnectInf.defaultDir)
+Ccontact::Ccontact (wxDb *pwxDb) : wxDbTable(pwxDb ? pwxDb : wxDbGetConnection(&DbConnectInf),CONTACT_TABLE_NAME,CONTACT_NO_COLS,NULL,!wxDB_QUERY_ONLY,DbConnectInf.defaultDir)
 {
     // This is used to represent whether the database connection should be released
     // when this instance of the object is deleted.  If using the same connection
     // for multiple instance of database objects, then the connection should only be 
     // released when the last database instance using the connection is deleted
 {
     // This is used to represent whether the database connection should be released
     // when this instance of the object is deleted.  If using the same connection
     // for multiple instance of database objects, then the connection should only be 
     // released when the last database instance using the connection is deleted
-    freeDbConn = !pwxDB;
+    freeDbConn = !pwxDb;
     
     SetupColumns();
 
     
     SetupColumns();
 
@@ -396,11 +479,11 @@ Ccontact::~Ccontact()
 {
     if (freeDbConn)
     {
 {
     if (freeDbConn)
     {
-        if (!FreeDbConnection(pDb))
+        if (!wxDbFreeConnection(GetDb()))
         {
             wxString tStr;
             tStr  = "Unable to Free the Ccontact data table handle\n\n";
         {
             wxString tStr;
             tStr  = "Unable to Free the Ccontact data table handle\n\n";
-            tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+            tStr += GetExtendedDBErrorMsg(GetDb(),__FILE__,__LINE__);
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
         }
     }
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
         }
     }
@@ -408,7 +491,7 @@ Ccontact::~Ccontact()
 
 
 /*
 
 
 /*
- * Handles setting up all the connections for the interface from the wxTable
+ * Handles setting up all the connections for the interface from the wxDbTable
  * functions to interface to the data structure used to store records in 
  * memory, and for all the column definitions that define the table structure
  */
  * functions to interface to the data structure used to store records in 
  * memory, and for all the column definitions that define the table structure
  */
@@ -436,19 +519,19 @@ bool Ccontact::CreateIndexes(void)
     // This index could easily be accomplished with an "orderBy" clause, 
     // but is done to show how to construct a non-primary index.
     wxString    indexName;
     // This index could easily be accomplished with an "orderBy" clause, 
     // but is done to show how to construct a non-primary index.
     wxString    indexName;
-    CidxDef     idxDef[2];
+    wxDbIdxDef  idxDef[2];
 
     bool        Ok = TRUE;
 
 
     bool        Ok = TRUE;
 
-    strcpy(idxDef[0].ColName, "IS_DEV");
+    wxStrcpy(idxDef[0].ColName, "IS_DEV");
     idxDef[0].Ascending = TRUE;
 
     idxDef[0].Ascending = TRUE;
 
-    strcpy(idxDef[1].ColName, "NAME");
+    wxStrcpy(idxDef[1].ColName, "NAME");
     idxDef[1].Ascending = TRUE;
 
     idxDef[1].Ascending = TRUE;
 
-    indexName = CONTACT_TABLE_NAME;
+    indexName = GetTableName();
     indexName += "_IDX1";
     indexName += "_IDX1";
-    Ok = CreateIndex((char*) (const char*) indexName, TRUE, 2, idxDef);
+    Ok = CreateIndex(indexName.c_str(), TRUE, 2, idxDef);
 
     return Ok;
 }  // Ccontact::CreateIndexes()
 
     return Ok;
 }  // Ccontact::CreateIndexes()
@@ -462,8 +545,8 @@ bool Ccontact::CreateIndexes(void)
 bool Ccontact::FetchByName(char *name)
 {
     whereStr.Printf("NAME = '%s'",name);
 bool Ccontact::FetchByName(char *name)
 {
     whereStr.Printf("NAME = '%s'",name);
-    where = (char*) (const char*) this->whereStr;
-    orderBy = 0;
+    SetWhereClause(whereStr.c_str());
+    SetOrderByClause("");
 
     if (!Query())
         return(FALSE);
 
     if (!Query())
         return(FALSE);
@@ -492,180 +575,34 @@ bool Ccontact::FetchByName(char *name)
  
 BEGIN_EVENT_TABLE(CeditorDlg, wxPanel)
     EVT_BUTTON(-1,  CeditorDlg::OnButton)
  
 BEGIN_EVENT_TABLE(CeditorDlg, wxPanel)
     EVT_BUTTON(-1,  CeditorDlg::OnButton)
+    EVT_CLOSE(CeditorDlg::OnCloseWindow)
 END_EVENT_TABLE()
  
 END_EVENT_TABLE()
  
-CeditorDlg::CeditorDlg(wxWindow *parent) : wxPanel (parent, 1, 1, 460, 455)
+CeditorDlg::CeditorDlg(wxWindow *parent) : wxPanel (parent, 0, 0, 537, 480)
 {
     // Since the ::OnCommand() function is overridden, this prevents the widget
     // detection in ::OnCommand() until all widgets have been initialized to prevent
     // uninitialized pointers from crashing the program
     widgetPtrsSet = FALSE;
 
 {
     // Since the ::OnCommand() function is overridden, this prevents the widget
     // detection in ::OnCommand() until all widgets have been initialized to prevent
     // uninitialized pointers from crashing the program
     widgetPtrsSet = FALSE;
 
-    // Create the data structure and a new database connection.  
-    // (As there is not a pDb being passed in the constructor, a new database
-    // connection is created)
-    Contact = new Ccontact();
-
-    if (!Contact)
-    {
-        wxMessageBox("Unable to instantiate an instance of Ccontact","Error...",wxOK | wxICON_EXCLAMATION);
-        return;
-    }
-
-    // Check if the table exists or not.  If it doesn't, ask the user if they want to 
-    // create the table.  Continue trying to create the table until it exists, or user aborts
-    while (!Contact->pDb->TableExists((char *)CONTACT_TABLE_NAME,DbConnectInf.Uid,DbConnectInf.defaultDir))
-    {
-        wxString tStr;
-        tStr.Printf("Unable to open the table '%s'.\n\nTable may need to be created...?\n\n",CONTACT_TABLE_NAME);
-        tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
-        wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
-
-        bool createTable = (wxMessageBox("Do you wish to try to create/clear the CONTACTS table?","Confirm",wxYES_NO|wxICON_QUESTION) == wxYES);
-
-        if (!createTable)
-        {
-            delete Contact;
-            Close();
-            DemoFrame->Close();
-            return;
-        }
-        else
-            DemoFrame->CreateDataTable();
-    }
-
-    // Tables must be "opened" before anything other than creating/deleting table can be done
-    if (!Contact->Open())
-    {
-        // Table does exist, there was some problem opening it.  Currently this should
-        // never fail, except in the case of the table not exisiting.  Open() basically
-        // only sets up variable/pointer values, other than checking for table existence.
-        if (Contact->pDb->TableExists((char *)CONTACT_TABLE_NAME))
-        {
-            wxString tStr;
-            tStr.Printf("Unable to open the table '%s'.\n\n",CONTACT_TABLE_NAME);
-            tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
-            wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
-            delete Contact;
-            Close();
-            DemoFrame->Close();
-            return;
-        }
-    }
-
-    // Build the dialog
-
-    (void)new wxStaticBox(this, EDITOR_DIALOG_FN_GROUP, "",  wxPoint(15, 1), wxSize(497,  69), 0, "FunctionGrp");
-    (void)new wxStaticBox(this, EDITOR_DIALOG_SEARCH_GROUP, "", wxPoint(417, 1), wxSize(95, 242), 0, "SearchGrp");
-
-    pCreateBtn      = new wxButton(this, EDITOR_DIALOG_CREATE,           "&Create",     wxPoint( 25,  21), wxSize( 70,  35), 0, wxDefaultValidator, "CreateBtn");
-    pEditBtn        = new wxButton(this, EDITOR_DIALOG_EDIT,             "&Edit",       wxPoint(102,  21), wxSize( 70,  35), 0, wxDefaultValidator, "EditBtn");
-    pDeleteBtn      = new wxButton(this, EDITOR_DIALOG_DELETE,           "&Delete",     wxPoint(179,  21), wxSize( 70,  35), 0, wxDefaultValidator, "DeleteBtn");
-    pCopyBtn        = new wxButton(this, EDITOR_DIALOG_COPY,             "Cop&y",       wxPoint(256,  21), wxSize( 70,  35), 0, wxDefaultValidator, "CopyBtn");
-    pSaveBtn        = new wxButton(this, EDITOR_DIALOG_SAVE,             "&Save",       wxPoint(333,  21), wxSize( 70,  35), 0, wxDefaultValidator, "SaveBtn");
-    pCancelBtn      = new wxButton(this, EDITOR_DIALOG_CANCEL,           "C&ancel",     wxPoint(430,  21), wxSize( 70,  35), 0, wxDefaultValidator, "CancelBtn");
-    pPrevBtn        = new wxButton(this, EDITOR_DIALOG_PREV,             "<< &Prev",    wxPoint(430,  81), wxSize( 70,  35), 0, wxDefaultValidator, "PrevBtn");
-    pNextBtn        = new wxButton(this, EDITOR_DIALOG_NEXT,             "&Next >>",    wxPoint(430, 121), wxSize( 70,  35), 0, wxDefaultValidator, "NextBtn");
-    pQueryBtn       = new wxButton(this, EDITOR_DIALOG_QUERY,            "&Query",      wxPoint(430, 161), wxSize( 70,  35), 0, wxDefaultValidator, "QueryBtn");
-    pResetBtn       = new wxButton(this, EDITOR_DIALOG_RESET,            "&Reset",      wxPoint(430, 200), wxSize( 70,  35), 0, wxDefaultValidator, "ResetBtn");
-    pNameMsg        = new wxStaticText(this, EDITOR_DIALOG_NAME_MSG,     "Name:",       wxPoint( 17,  80), wxSize( -1,  -1), 0, "NameMsg");
-    pNameTxt        = new wxTextCtrl(this, EDITOR_DIALOG_NAME_TEXT,      "",            wxPoint( 17,  97), wxSize(308,  25), 0, wxDefaultValidator, "NameTxt");
-    pNameListBtn    = new wxButton(this, EDITOR_DIALOG_LOOKUP,           "&Lookup",     wxPoint(333,  99), wxSize( 70,  24), 0, wxDefaultValidator, "LookupBtn");
-    pAddress1Msg    = new wxStaticText(this, EDITOR_DIALOG_ADDRESS1_MSG, "Address:",    wxPoint( 17, 130), wxSize( -1,  -1), 0, "Address1Msg");
-    pAddress1Txt    = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT,  "",            wxPoint( 17, 147), wxSize(308,  25), 0, wxDefaultValidator, "Address1Txt");
-    pAddress2Msg    = new wxStaticText(this, EDITOR_DIALOG_ADDRESS2_MSG, "Address:",    wxPoint( 17, 180), wxSize( -1,  -1), 0, "Address2Msg");
-    pAddress2Txt    = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT,  "",            wxPoint( 17, 197), wxSize(308,  25), 0, wxDefaultValidator, "Address2Txt");
-    pCityMsg        = new wxStaticText(this, EDITOR_DIALOG_CITY_MSG,     "City:",       wxPoint( 17, 230), wxSize( -1,  -1), 0, "CityMsg");
-    pCityTxt        = new wxTextCtrl(this, EDITOR_DIALOG_CITY_TEXT,      "",            wxPoint( 17, 247), wxSize(225,  25), 0, wxDefaultValidator, "CityTxt");
-    pStateMsg       = new wxStaticText(this, EDITOR_DIALOG_STATE_MSG,    "State:",      wxPoint(250, 230), wxSize( -1,  -1), 0, "StateMsg");
-    pStateTxt       = new wxTextCtrl(this, EDITOR_DIALOG_STATE_TEXT,     "",            wxPoint(250, 247), wxSize(153,  25), 0, wxDefaultValidator, "StateTxt");
-    pCountryMsg     = new wxStaticText(this, EDITOR_DIALOG_COUNTRY_MSG,  "Country:",    wxPoint( 17, 280), wxSize( -1,  -1), 0, "CountryMsg");
-    pCountryTxt     = new wxTextCtrl(this, EDITOR_DIALOG_COUNTRY_TEXT,   "",            wxPoint( 17, 297), wxSize(225,  25), 0, wxDefaultValidator, "CountryTxt");
-    pPostalCodeMsg  = new wxStaticText(this, EDITOR_DIALOG_POSTAL_MSG,   "Postal Code:",wxPoint(250, 280), wxSize( -1,  -1), 0, "PostalCodeMsg");
-    pPostalCodeTxt  = new wxTextCtrl(this, EDITOR_DIALOG_POSTAL_TEXT,    "",            wxPoint(250, 297), wxSize(153,  25), 0, wxDefaultValidator, "PostalCodeTxt");
-
-    wxString choice_strings[5];
-    choice_strings[0] = "English";
-    choice_strings[1] = "French";
-    choice_strings[2] = "German";
-    choice_strings[3] = "Spanish";
-    choice_strings[4] = "Other";
-
-    pNativeLangChoice = new wxChoice(this, EDITOR_DIALOG_LANG_CHOICE,                        wxPoint( 17, 346), wxSize(277,  -1), 5, choice_strings);
-    pNativeLangMsg    = new wxStaticText(this, EDITOR_DIALOG_LANG_MSG,   "Native language:", wxPoint( 17, 330), wxSize( -1,  -1), 0, "NativeLangMsg");
+    initialized = FALSE;
 
 
-    wxString radio_strings[2];
-    radio_strings[0]  = "No";
-    radio_strings[1]  = "Yes";
-    pDeveloperRadio   = new wxRadioBox(this,EDITOR_DIALOG_DEVELOPER,     "Developer:",       wxPoint(303, 330), wxSize( -1,  -1), 2, radio_strings, 2, wxHORIZONTAL);
-    pJoinDateMsg      = new wxStaticText(this, EDITOR_DIALOG_JOIN_MSG,   "Date joined:",     wxPoint( 17, 380), wxSize( -1,  -1), 0, "JoinDateMsg");
-    pJoinDateTxt      = new wxTextCtrl(this, EDITOR_DIALOG_JOIN_TEXT,    "",                 wxPoint( 17, 397), wxSize(150,  25), 0, wxDefaultValidator, "JoinDateTxt");
-    pContribMsg       = new wxStaticText(this, EDITOR_DIALOG_CONTRIB_MSG,"Contributions:",   wxPoint(175, 380), wxSize( -1,  -1), 0, "ContribMsg");
-    pContribTxt       = new wxTextCtrl(this, EDITOR_DIALOG_CONTRIB_TEXT, "",                 wxPoint(175, 397), wxSize(120,  25), 0, wxDefaultValidator, "ContribTxt");
-    pLinesMsg         = new wxStaticText(this, EDITOR_DIALOG_LINES_MSG,  "Lines of code:",   wxPoint(303, 380), wxSize( -1,  -1), 0, "LinesMsg");
-    pLinesTxt         = new wxTextCtrl(this, EDITOR_DIALOG_LINES_TEXT,   "",                 wxPoint(303, 397), wxSize(100,  25), 0, wxDefaultValidator, "LinesTxt");
+    Contact = NULL;
 
 
-    // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to 
-    // handle all widget processing
-    widgetPtrsSet = TRUE;
-
-    // Setup the orderBy and where clauses to return back a single record as the result set, 
-    // as there will only be one record being shown on the dialog at a time, this optimizes
-    // network traffic by only returning a one row result
-    
-    Contact->orderBy = "NAME";  // field name to sort by
-
-    // The wxString "whereStr" is not a member of the wxTable object, it is a member variable
-    // specifically in the Ccontact class.  It is used here for simpler construction of a varying
-    // length string, and then after the string is built, the wxTable member variable "where" is
-    // assigned the pointer to the constructed string.
-    //
-    // The constructed where clause below has a sub-query within it "SELECT MIN(NAME) FROM %s" 
-    // to achieve a single row (in this case the first name in alphabetical order).
-    
-    if (Contact->pDb->Dbms() != dbmsPOSTGRES)
-    {
-        Contact->whereStr.sprintf("NAME = (SELECT MIN(NAME) FROM %s)",Contact->tableName);
-        // NOTE: (const char*) returns a pointer which may not be valid later, so this is short term use only
-        Contact->where = (char*) (const char*) Contact->whereStr;
-    }
-    else
-        Contact->where = 0;
-
-    // Perform the Query to get the result set.  
-    // NOTE: If there are no rows returned, that is a valid result, so Query() would return TRUE.  
-    //       Only if there is a database error will Query() come back as FALSE
-    if (!Contact->Query())
-    {
-        wxString tStr;
-        tStr  = "ODBC error during Query()\n\n";
-        tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
-        wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
-        GetParent()->Close();
-        return;
-    }
-
-    // Since Query succeeded, now get the row that was returned
-    if (!Contact->GetNext())
-        // If the GetNext() failed at this point, then there are no rows to retrieve, 
-        // so clear the values in the members of "Contact" so that PutData() blanks the 
-        // widgets on the dialog
-        Contact->Initialize();
-
-    SetMode(mView);
-    PutData();
-
-    Show(TRUE);
+    Show(FALSE);
 }  // CeditorDlg constructor
 
 
 void CeditorDlg::OnCloseWindow(wxCloseEvent& event)
 {
     // Clean up time
 }  // CeditorDlg constructor
 
 
 void CeditorDlg::OnCloseWindow(wxCloseEvent& event)
 {
     // Clean up time
-     if ((mode != mCreate) && (mode != mEdit))
+    if ((mode != mCreate) && (mode != mEdit))
     {
         if (Contact)
     {
         if (Contact)
+        {
             delete Contact;
             delete Contact;
+            Contact = NULL;
+        }
         this->Destroy();
     }
     else
         this->Destroy();
     }
     else
@@ -676,11 +613,11 @@ void CeditorDlg::OnCloseWindow(wxCloseEvent& event)
 }  // CeditorDlg::OnCloseWindow()
 
 
 }  // CeditorDlg::OnCloseWindow()
 
 
-void CeditorDlg::OnButton( wxCommandEvent &event )
+void CeditorDlg::OnButton(wxCommandEvent &event)
 {
 {
-  wxWindow *win = (wxWindow*) event.GetEventObject();
-  OnCommand( *win, event );
-}
+    wxWindow *win = (wxWindow*) event.GetEventObject();
+    OnCommand( *win, event );
+}  // CeditorDlg::OnButton()
 
 
 void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
 
 
 void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
@@ -715,6 +652,7 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         SetMode(mCreate);
         pNameTxt->SetValue("");
         pNameTxt->SetFocus();
         SetMode(mCreate);
         pNameTxt->SetValue("");
         pNameTxt->SetFocus();
+
         return;
     }
 
         return;
     }
 
@@ -733,7 +671,7 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
             //       of Ccontact is deleted.  If the Commit wasn't performed, the 
             //       database will automatically Rollback the changes when the database
             //       connection is terminated
             //       of Ccontact is deleted.  If the Commit wasn't performed, the 
             //       database will automatically Rollback the changes when the database
             //       connection is terminated
-            Contact->pDb->CommitTrans();
+            Contact->GetDb()->CommitTrans();
 
             // Try to get the row that followed the just deleted row in the orderBy sequence
             if (!GetNextRec())
 
             // Try to get the row that followed the just deleted row in the orderBy sequence
             if (!GetNextRec())
@@ -751,7 +689,7 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         }
         else
             // Delete failed
         }
         else
             // Delete failed
-            Contact->pDb->RollbackTrans();
+            Contact->GetDb()->RollbackTrans();
 
         SetMode(mView);
         return;
 
         SetMode(mView);
         return;
@@ -770,7 +708,7 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         if (!Ok)
             return;
 
         if (!Ok)
             return;
 
-        if (!strcmp((const char*) saveName,""))
+        if (!wxStrcmp((const char*) saveName,""))
         {
             Contact->Initialize();
             PutData();
         {
             Contact->Initialize();
             PutData();
@@ -789,21 +727,21 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         }
 
         // Previous record not available, retrieve first record in table
         }
 
         // Previous record not available, retrieve first record in table
-        if (Contact->pDb->Dbms() != dbmsPOSTGRES)
+        if (Contact->GetDb()->Dbms() != dbmsPOSTGRES && Contact->GetDb()->Dbms() != dbmsMY_SQL)
         {
             Contact->whereStr  = "NAME = (SELECT MIN(NAME) FROM ";
         {
             Contact->whereStr  = "NAME = (SELECT MIN(NAME) FROM ";
-            Contact->whereStr += Contact->tableName;
+            Contact->whereStr += Contact->GetTableName();
             Contact->whereStr += ")";
             Contact->whereStr += ")";
-            Contact->where = (char*) (const char*) Contact->whereStr;
+            Contact->SetWhereClause(Contact->whereStr.c_str());
         }
         else
         }
         else
-            Contact->where = 0;
+            Contact->SetWhereClause("");
 
         if (!Contact->Query())
         {
             wxString tStr;
             tStr  = "ODBC error during Query()\n\n";
 
         if (!Contact->Query())
         {
             wxString tStr;
             tStr  = "ODBC error during Query()\n\n";
-            tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+            tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
             SetMode(mView);
             return;
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
             SetMode(mView);
             return;
@@ -839,19 +777,18 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         // Display the query dialog box
         char qryWhere[DB_MAX_WHERE_CLAUSE_LEN+1];
     {
         // Display the query dialog box
         char qryWhere[DB_MAX_WHERE_CLAUSE_LEN+1];
-        strcpy(qryWhere, (const char*) Contact->qryWhereStr);
+        wxStrcpy(qryWhere, (const char*) Contact->qryWhereStr);
         char *tblName[] = {(char *)CONTACT_TABLE_NAME, 0};
         char *tblName[] = {(char *)CONTACT_TABLE_NAME, 0};
-        new CqueryDlg(GetParent(), Contact->pDb, tblName, qryWhere);
+        new CqueryDlg(GetParent(), Contact->GetDb(), tblName, qryWhere);
 
         // Query the first record in the new record set and
         // display it, if the query string has changed.
 
         // Query the first record in the new record set and
         // display it, if the query string has changed.
-        if (strcmp(qryWhere, (const char*) Contact->qryWhereStr))
+        if (wxStrcmp(qryWhere, (const char*) Contact->qryWhereStr))
         {
         {
             Contact->whereStr = "";
             Contact->whereStr = "";
-            Contact->orderBy  = "NAME";
+            Contact->SetOrderByClause("NAME");
 
 
-            if (Contact->pDb->Dbms() != dbmsPOSTGRES)
+            if (Contact->GetDb()->Dbms() != dbmsPOSTGRES && Contact->GetDb()->Dbms() != dbmsMY_SQL)
             {
                 Contact->whereStr  = "NAME = (SELECT MIN(NAME) FROM ";
                 Contact->whereStr += CONTACT_TABLE_NAME;
             {
                 Contact->whereStr  = "NAME = (SELECT MIN(NAME) FROM ";
                 Contact->whereStr += CONTACT_TABLE_NAME;
@@ -859,20 +796,20 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
             
             // Append the query where string (if there is one)
             Contact->qryWhereStr  = qryWhere;
             
             // Append the query where string (if there is one)
             Contact->qryWhereStr  = qryWhere;
-            if (strlen(qryWhere))
+            if (wxStrlen(qryWhere))
             {
                 Contact->whereStr += " WHERE ";
                 Contact->whereStr += Contact->qryWhereStr;
             }
             // Close the expression with a right paren
             {
                 Contact->whereStr += " WHERE ";
                 Contact->whereStr += Contact->qryWhereStr;
             }
             // Close the expression with a right paren
-            // Contact->whereStr += ")";
+            Contact->whereStr += ")";
             // Requery the table
             // Requery the table
-            Contact->where = (char*) (const char*) Contact->whereStr;
+            Contact->SetWhereClause(Contact->whereStr.c_str());
             if (!Contact->Query())
             {
                 wxString tStr;
                 tStr  = "ODBC error during Query()\n\n";
             if (!Contact->Query())
             {
                 wxString tStr;
                 tStr  = "ODBC error during Query()\n\n";
-                tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+                tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
                 wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
                 return;
             }
                 wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
                 return;
             }
@@ -893,21 +830,21 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         // Clear the additional where criteria established by the query feature
         Contact->qryWhereStr = "";
     {
         // Clear the additional where criteria established by the query feature
         Contact->qryWhereStr = "";
-        Contact->orderBy        = "NAME";
+        Contact->SetOrderByClause("NAME");
 
 
-        if (Contact->pDb->Dbms() != dbmsPOSTGRES)
+        if (Contact->GetDb()->Dbms() != dbmsPOSTGRES && Contact->GetDb()->Dbms() != dbmsMY_SQL)
         {
             Contact->whereStr        = "NAME = (SELECT MIN(NAME) FROM ";
             Contact->whereStr        += CONTACT_TABLE_NAME;
             Contact->whereStr        += ")";
         }
 
         {
             Contact->whereStr        = "NAME = (SELECT MIN(NAME) FROM ";
             Contact->whereStr        += CONTACT_TABLE_NAME;
             Contact->whereStr        += ")";
         }
 
-        Contact->where            = (char*) (const char*) Contact->whereStr;
+        Contact->SetWhereClause(Contact->whereStr.c_str());
         if (!Contact->Query())
         {
             wxString tStr;
             tStr  = "ODBC error during Query()\n\n";
         if (!Contact->Query())
         {
             wxString tStr;
             tStr  = "ODBC error during Query()\n\n";
-            tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+            tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
             return;
         }
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
             return;
         }
@@ -931,7 +868,7 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
                        /* char      *orderBy       */ "NAME",
                        /* bool      distinctValues */ TRUE);
 
                        /* char      *orderBy       */ "NAME",
                        /* bool      distinctValues */ TRUE);
 
-        if (ListDB_Selection && strlen(ListDB_Selection))
+        if (ListDB_Selection && wxStrlen(ListDB_Selection))
         {
             wxString w = "NAME = '";
             w += ListDB_Selection;
         {
             wxString w = "NAME = '";
             w += ListDB_Selection;
@@ -941,10 +878,182 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
 
         return;
     }
 
         return;
     }
-
 }  // CeditorDlg::OnCommand()
 
 
 }  // CeditorDlg::OnCommand()
 
 
+bool CeditorDlg::Initialize()
+{
+    // Create the data structure and a new database connection.  
+    // (As there is not a pDb being passed in the constructor, a new database
+    // connection is created)
+    Contact = new Ccontact();
+
+    if (!Contact)
+    {
+        wxMessageBox("Unable to instantiate an instance of Ccontact","Error...",wxOK | wxICON_EXCLAMATION);
+        return FALSE;
+    }
+
+    // Check if the table exists or not.  If it doesn't, ask the user if they want to 
+    // create the table.  Continue trying to create the table until it exists, or user aborts
+    while (!Contact->GetDb()->TableExists((char *)CONTACT_TABLE_NAME,DbConnectInf.Uid,DbConnectInf.defaultDir))
+    {
+        wxString tStr;
+        tStr.Printf("Unable to open the table '%s'.\n\nTable may need to be created...?\n\n",CONTACT_TABLE_NAME);
+        tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
+        wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
+
+        bool createTable = (wxMessageBox("Do you wish to try to create/clear the CONTACTS table?","Confirm",wxYES_NO|wxICON_QUESTION) == wxYES);
+
+        if (!createTable)
+        {
+//            Close();
+            return FALSE;
+        }
+        else
+            DemoFrame->CreateDataTable(TRUE);
+    }
+
+    // Tables must be "opened" before anything other than creating/deleting table can be done
+    if (!Contact->Open())
+    {
+        // Table does exist, or there was some problem opening it.  Currently this should
+        // never fail, except in the case of the table not exisiting or the current 
+        // user has insufficent privileges to access the table
+#if 0
+// This code is experimenting with a new function that will hopefully be available
+// in the 2.4 release.  This check will determine whether the open failing was due
+// to the table not existing, or the users privileges being insufficient to
+// open the table.
+        if (!Contact->GetDb()->TablePrivileges(CONTACT_TABLE_NAME,"SELECT",Contact->GetDb()->GetUsername(),DbConnectInf.defaultDir))
+        {
+            wxString tStr;
+            tStr.Printf("Unable to open the table '%s'.\n\n",CONTACT_TABLE_NAME);
+            tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
+            wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
+        }
+        else 
+#endif
+        if (Contact->GetDb()->TableExists(CONTACT_TABLE_NAME,Contact->GetDb()->GetUsername(),DbConnectInf.defaultDir))
+        {
+            wxString tStr;
+            tStr.Printf("Unable to open the table '%s'.\n\n",CONTACT_TABLE_NAME);
+            tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
+            wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
+        }
+
+        return FALSE;
+    }
+
+    // Build the dialog
+
+    (void)new wxStaticBox(this, EDITOR_DIALOG_FN_GROUP, "",  wxPoint(15, 1), wxSize(497,  69), 0, "FunctionGrp");
+    (void)new wxStaticBox(this, EDITOR_DIALOG_SEARCH_GROUP, "", wxPoint(417, 1), wxSize(95, 242), 0, "SearchGrp");
+
+    pCreateBtn      = new wxButton(this, EDITOR_DIALOG_CREATE,           "&Create",     wxPoint( 25,  21), wxSize( 70,  35), 0, wxDefaultValidator, "CreateBtn");
+    pEditBtn        = new wxButton(this, EDITOR_DIALOG_EDIT,             "&Edit",       wxPoint(102,  21), wxSize( 70,  35), 0, wxDefaultValidator, "EditBtn");
+    pDeleteBtn      = new wxButton(this, EDITOR_DIALOG_DELETE,           "&Delete",     wxPoint(179,  21), wxSize( 70,  35), 0, wxDefaultValidator, "DeleteBtn");
+    pCopyBtn        = new wxButton(this, EDITOR_DIALOG_COPY,             "Cop&y",       wxPoint(256,  21), wxSize( 70,  35), 0, wxDefaultValidator, "CopyBtn");
+    pSaveBtn        = new wxButton(this, EDITOR_DIALOG_SAVE,             "&Save",       wxPoint(333,  21), wxSize( 70,  35), 0, wxDefaultValidator, "SaveBtn");
+    pCancelBtn      = new wxButton(this, EDITOR_DIALOG_CANCEL,           "C&ancel",     wxPoint(430,  21), wxSize( 70,  35), 0, wxDefaultValidator, "CancelBtn");
+    pPrevBtn        = new wxButton(this, EDITOR_DIALOG_PREV,             "<< &Prev",    wxPoint(430,  81), wxSize( 70,  35), 0, wxDefaultValidator, "PrevBtn");
+    pNextBtn        = new wxButton(this, EDITOR_DIALOG_NEXT,             "&Next >>",    wxPoint(430, 121), wxSize( 70,  35), 0, wxDefaultValidator, "NextBtn");
+    pQueryBtn       = new wxButton(this, EDITOR_DIALOG_QUERY,            "&Query",      wxPoint(430, 161), wxSize( 70,  35), 0, wxDefaultValidator, "QueryBtn");
+    pResetBtn       = new wxButton(this, EDITOR_DIALOG_RESET,            "&Reset",      wxPoint(430, 200), wxSize( 70,  35), 0, wxDefaultValidator, "ResetBtn");
+    pNameMsg        = new wxStaticText(this, EDITOR_DIALOG_NAME_MSG,     "Name:",       wxPoint( 17,  80), wxSize( -1,  -1), 0, "NameMsg");
+    pNameTxt        = new wxTextCtrl(this, EDITOR_DIALOG_NAME_TEXT,      "",            wxPoint( 17,  97), wxSize(308,  25), 0, wxDefaultValidator, "NameTxt");
+    pNameListBtn    = new wxButton(this, EDITOR_DIALOG_LOOKUP,           "&Lookup",     wxPoint(333,  97), wxSize( 70,  24), 0, wxDefaultValidator, "LookupBtn");
+    pAddress1Msg    = new wxStaticText(this, EDITOR_DIALOG_ADDRESS1_MSG, "Address:",    wxPoint( 17, 130), wxSize( -1,  -1), 0, "Address1Msg");
+    pAddress1Txt    = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT,  "",            wxPoint( 17, 147), wxSize(308,  25), 0, wxDefaultValidator, "Address1Txt");
+    pAddress2Msg    = new wxStaticText(this, EDITOR_DIALOG_ADDRESS2_MSG, "Address:",    wxPoint( 17, 180), wxSize( -1,  -1), 0, "Address2Msg");
+    pAddress2Txt    = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT,  "",            wxPoint( 17, 197), wxSize(308,  25), 0, wxDefaultValidator, "Address2Txt");
+    pCityMsg        = new wxStaticText(this, EDITOR_DIALOG_CITY_MSG,     "City:",       wxPoint( 17, 230), wxSize( -1,  -1), 0, "CityMsg");
+    pCityTxt        = new wxTextCtrl(this, EDITOR_DIALOG_CITY_TEXT,      "",            wxPoint( 17, 247), wxSize(225,  25), 0, wxDefaultValidator, "CityTxt");
+    pStateMsg       = new wxStaticText(this, EDITOR_DIALOG_STATE_MSG,    "State:",      wxPoint(250, 230), wxSize( -1,  -1), 0, "StateMsg");
+    pStateTxt       = new wxTextCtrl(this, EDITOR_DIALOG_STATE_TEXT,     "",            wxPoint(250, 247), wxSize(153,  25), 0, wxDefaultValidator, "StateTxt");
+    pCountryMsg     = new wxStaticText(this, EDITOR_DIALOG_COUNTRY_MSG,  "Country:",    wxPoint( 17, 280), wxSize( -1,  -1), 0, "CountryMsg");
+    pCountryTxt     = new wxTextCtrl(this, EDITOR_DIALOG_COUNTRY_TEXT,   "",            wxPoint( 17, 297), wxSize(225,  25), 0, wxDefaultValidator, "CountryTxt");
+    pPostalCodeMsg  = new wxStaticText(this, EDITOR_DIALOG_POSTAL_MSG,   "Postal Code:",wxPoint(250, 280), wxSize( -1,  -1), 0, "PostalCodeMsg");
+    pPostalCodeTxt  = new wxTextCtrl(this, EDITOR_DIALOG_POSTAL_TEXT,    "",            wxPoint(250, 297), wxSize(153,  25), 0, wxDefaultValidator, "PostalCodeTxt");
+
+    wxString choice_strings[5];
+    choice_strings[0] = "English";
+    choice_strings[1] = "French";
+    choice_strings[2] = "German";
+    choice_strings[3] = "Spanish";
+    choice_strings[4] = "Other";
+
+    pNativeLangChoice = new wxChoice(this, EDITOR_DIALOG_LANG_CHOICE,                        wxPoint( 17, 346), wxSize(277,  -1), 5, choice_strings);
+    pNativeLangMsg    = new wxStaticText(this, EDITOR_DIALOG_LANG_MSG,   "Native language:", wxPoint( 17, 330), wxSize( -1,  -1), 0, "NativeLangMsg");
+
+    wxString radio_strings[2];
+    radio_strings[0]  = "No";
+    radio_strings[1]  = "Yes";
+    pDeveloperRadio   = new wxRadioBox(this,EDITOR_DIALOG_DEVELOPER,     "Developer:",       wxPoint(303, 330), wxSize( -1,  -1), 2, radio_strings, 2, wxHORIZONTAL);
+    pJoinDateMsg      = new wxStaticText(this, EDITOR_DIALOG_JOIN_MSG,   "Date joined:",     wxPoint( 17, 380), wxSize( -1,  -1), 0, "JoinDateMsg");
+    pJoinDateTxt      = new wxTextCtrl(this, EDITOR_DIALOG_JOIN_TEXT,    "",                 wxPoint( 17, 397), wxSize(150,  25), 0, wxDefaultValidator, "JoinDateTxt");
+    pContribMsg       = new wxStaticText(this, EDITOR_DIALOG_CONTRIB_MSG,"Contributions:",   wxPoint(175, 380), wxSize( -1,  -1), 0, "ContribMsg");
+    pContribTxt       = new wxTextCtrl(this, EDITOR_DIALOG_CONTRIB_TEXT, "",                 wxPoint(175, 397), wxSize(120,  25), 0, wxDefaultValidator, "ContribTxt");
+    pLinesMsg         = new wxStaticText(this, EDITOR_DIALOG_LINES_MSG,  "Lines of code:",   wxPoint(303, 380), wxSize( -1,  -1), 0, "LinesMsg");
+    pLinesTxt         = new wxTextCtrl(this, EDITOR_DIALOG_LINES_TEXT,   "",                 wxPoint(303, 397), wxSize(100,  25), 0, wxDefaultValidator, "LinesTxt");
+
+    // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to 
+    // handle all widget processing
+    widgetPtrsSet = TRUE;
+
+    // Setup the orderBy and where clauses to return back a single record as the result set, 
+    // as there will only be one record being shown on the dialog at a time, this optimizes
+    // network traffic by only returning a one row result
+    
+    Contact->SetOrderByClause("NAME");  // field name to sort by
+
+    // The wxString "whereStr" is not a member of the wxDbTable object, it is a member variable
+    // specifically in the Ccontact class.  It is used here for simpler construction of a varying
+    // length string, and then after the string is built, the wxDbTable member variable "where" is
+    // assigned the pointer to the constructed string.
+    //
+    // The constructed where clause below has a sub-query within it "SELECT MIN(NAME) FROM %s" 
+    // to achieve a single row (in this case the first name in alphabetical order).
+    
+    if (Contact->GetDb()->Dbms() != dbmsPOSTGRES && Contact->GetDb()->Dbms() != dbmsMY_SQL)
+    {
+        Contact->whereStr.sprintf("NAME = (SELECT MIN(NAME) FROM %s)",Contact->GetTableName());
+        // NOTE: (const char*) returns a pointer which may not be valid later, so this is short term use only
+        Contact->SetWhereClause(Contact->whereStr.c_str());
+    }
+    else
+       Contact->SetWhereClause("");
+
+    // Perform the Query to get the result set.  
+    // NOTE: If there are no rows returned, that is a valid result, so Query() would return TRUE.  
+    //       Only if there is a database error will Query() come back as FALSE
+    if (!Contact->Query())
+    {
+        wxString tStr;
+        tStr  = "ODBC error during Query()\n\n";
+        tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
+        wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
+//        GetParent()->Close();
+        return FALSE;
+    }
+
+    // Since Query succeeded, now get the row that was returned
+    if (!Contact->GetNext())
+        // If the GetNext() failed at this point, then there are no rows to retrieve, 
+        // so clear the values in the members of "Contact" so that PutData() blanks the 
+        // widgets on the dialog
+        Contact->Initialize();
+
+    SetMode(mView);
+    PutData();
+
+    Show(TRUE);
+
+    initialized = TRUE;
+    return TRUE;
+}  // CeditorDlg::Initialize()
+
+
 void CeditorDlg::FieldsEditable()
 {
     pNameTxt->Enable((mode == mCreate) || (mode == mEdit));
 void CeditorDlg::FieldsEditable()
 {
     pNameTxt->Enable((mode == mCreate) || (mode == mEdit));
@@ -966,7 +1075,7 @@ void CeditorDlg::FieldsEditable()
 
 void CeditorDlg::SetMode(enum DialogModes m)
 {
 
 void CeditorDlg::SetMode(enum DialogModes m)
 {
-    bool    edit = FALSE;
+    bool edit = FALSE;
 
     mode = m;
     switch (mode)
 
     mode = m;
     switch (mode)
@@ -986,9 +1095,9 @@ void CeditorDlg::SetMode(enum DialogModes m)
     if (widgetPtrsSet)
     {
         pCreateBtn->Enable( !edit );
     if (widgetPtrsSet)
     {
         pCreateBtn->Enable( !edit );
-        pEditBtn->Enable( !edit && (strcmp(Contact->Name,"")!=0) );
-        pDeleteBtn->Enable( !edit && (strcmp(Contact->Name,"")!=0) );
-        pCopyBtn->Enable( !edit && (strcmp(Contact->Name,"")!=0) );
+        pEditBtn->Enable( !edit && (wxStrcmp(Contact->Name,"")!=0) );
+        pDeleteBtn->Enable( !edit && (wxStrcmp(Contact->Name,"")!=0) );
+        pCopyBtn->Enable( !edit && (wxStrcmp(Contact->Name,"")!=0) );
         pSaveBtn->Enable( edit );
         pCancelBtn->Enable( edit );
         pPrevBtn->Enable( !edit );
         pSaveBtn->Enable( edit );
         pCancelBtn->Enable( edit );
         pPrevBtn->Enable( !edit );
@@ -1045,7 +1154,7 @@ bool CeditorDlg::GetData()
 
     wxString tStr;
     tStr = pNameTxt->GetValue();
 
     wxString tStr;
     tStr = pNameTxt->GetValue();
-    if (!strcmp((const char*) tStr,""))
+    if (!wxStrcmp((const char*) tStr,""))
     {
         wxMessageBox("A name is required for entry into the contact table","Notice...",wxOK | wxICON_INFORMATION);
         return FALSE;
     {
         wxMessageBox("A name is required for entry into the contact table","Notice...",wxOK | wxICON_INFORMATION);
         return FALSE;
@@ -1117,13 +1226,13 @@ bool CeditorDlg::GetData()
     }
 
     tStr = pNameTxt->GetValue();
     }
 
     tStr = pNameTxt->GetValue();
-    strcpy(Contact->Name,(const char*) tStr);
-    strcpy(Contact->Addr1,pAddress1Txt->GetValue());
-    strcpy(Contact->Addr2,pAddress2Txt->GetValue());
-    strcpy(Contact->City,pCityTxt->GetValue());
-    strcpy(Contact->State,pStateTxt->GetValue());
-    strcpy(Contact->Country,pCountryTxt->GetValue());
-    strcpy(Contact->PostalCode,pPostalCodeTxt->GetValue());
+    wxStrcpy(Contact->Name,(const char*) tStr);
+    wxStrcpy(Contact->Addr1,pAddress1Txt->GetValue());
+    wxStrcpy(Contact->Addr2,pAddress2Txt->GetValue());
+    wxStrcpy(Contact->City,pCityTxt->GetValue());
+    wxStrcpy(Contact->State,pStateTxt->GetValue());
+    wxStrcpy(Contact->Country,pCountryTxt->GetValue());
+    wxStrcpy(Contact->PostalCode,pPostalCodeTxt->GetValue());
 
     Contact->Contributions = atoi(pContribTxt->GetValue());
     Contact->LinesOfCode = atol(pLinesTxt->GetValue());
 
     Contact->Contributions = atoi(pContribTxt->GetValue());
     Contact->LinesOfCode = atol(pLinesTxt->GetValue());
@@ -1170,7 +1279,7 @@ bool CeditorDlg::Save()
                 {
                     wxString tStr;
                     tStr  = "A duplicate key value already exists in the table.\nUnable to save record\n\n";
                 {
                     wxString tStr;
                     tStr  = "A duplicate key value already exists in the table.\nUnable to save record\n\n";
-                    tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+                    tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
                     wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
                 }
                 else
                     wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
                 }
                 else
@@ -1178,7 +1287,7 @@ bool CeditorDlg::Save()
                     // Some other unexpexted error occurred
                     wxString tStr;
                     tStr  = "Database insert failed\n\n";
                     // Some other unexpexted error occurred
                     wxString tStr;
                     tStr  = "Database insert failed\n\n";
-                    tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+                    tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
                     wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
                 }
             }
                     wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
                 }
             }
@@ -1189,7 +1298,7 @@ bool CeditorDlg::Save()
             {
                 wxString tStr;
                 tStr  = "Database update failed\n\n";
             {
                 wxString tStr;
                 tStr  = "Database update failed\n\n";
-                tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+                tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
                 wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
                 failed = TRUE;
             }
                 wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
                 failed = TRUE;
             }
@@ -1197,11 +1306,11 @@ bool CeditorDlg::Save()
 
         if (!failed)
         {
 
         if (!failed)
         {
-            Contact->pDb->CommitTrans();
+            Contact->GetDb()->CommitTrans();
             SetMode(mView);  // Sets the dialog mode back to viewing after save is successful
         }
         else
             SetMode(mView);  // Sets the dialog mode back to viewing after save is successful
         }
         else
-            Contact->pDb->RollbackTrans();
+            Contact->GetDb()->RollbackTrans();
 
         wxEndBusyCursor();
     }
 
         wxEndBusyCursor();
     }
@@ -1219,10 +1328,10 @@ bool CeditorDlg::GetNextRec()
 {
     wxString w;
 
 {
     wxString w;
 
-    if (Contact->pDb->Dbms() != dbmsPOSTGRES)
+    if (Contact->GetDb()->Dbms() != dbmsPOSTGRES && Contact->GetDb()->Dbms() != dbmsMY_SQL)
     {
         w  = "NAME = (SELECT MIN(NAME) FROM ";
     {
         w  = "NAME = (SELECT MIN(NAME) FROM ";
-        w += Contact->tableName;
+        w += Contact->GetTableName();
         w += " WHERE NAME > '";
     }
     else
         w += " WHERE NAME > '";
     }
     else
@@ -1254,10 +1363,10 @@ bool CeditorDlg::GetPrevRec()
 {
     wxString w;
 
 {
     wxString w;
 
-    if (Contact->pDb->Dbms() != dbmsPOSTGRES)
+    if (Contact->GetDb()->Dbms() != dbmsPOSTGRES && Contact->GetDb()->Dbms() != dbmsMY_SQL)
     {
         w  = "NAME = (SELECT MAX(NAME) FROM ";
     {
         w  = "NAME = (SELECT MAX(NAME) FROM ";
-        w += Contact->tableName;
+        w += Contact->GetTableName();
         w += " WHERE NAME < '";
     }
     else
         w += " WHERE NAME < '";
     }
     else
@@ -1287,14 +1396,14 @@ bool CeditorDlg::GetPrevRec()
  */
 bool CeditorDlg::GetRec(char *whereStr)
 {
  */
 bool CeditorDlg::GetRec(char *whereStr)
 {
-    Contact->where = whereStr;
-    Contact->orderBy = "NAME";
+    Contact->SetWhereClause(whereStr);
+    Contact->SetOrderByClause("NAME");
 
     if (!Contact->Query())
     {
         wxString tStr;
         tStr  = "ODBC error during Query()\n\n";
 
     if (!Contact->Query())
     {
         wxString tStr;
         tStr  = "ODBC error during Query()\n\n";
-        tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+        tStr += GetExtendedDBErrorMsg(Contact->GetDb(),__FILE__,__LINE__);
         wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
 
         return(FALSE);
         wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
 
         return(FALSE);
@@ -1359,21 +1468,27 @@ void CparameterDlg::OnCloseWindow(wxCloseEvent& event)
     if (!saved)
     {
         bool Ok = (wxMessageBox("No changes have been saved.\n\nAre you sure you wish exit the parameter screen?","Confirm",wxYES_NO|wxICON_QUESTION) == wxYES);
     if (!saved)
     {
         bool Ok = (wxMessageBox("No changes have been saved.\n\nAre you sure you wish exit the parameter screen?","Confirm",wxYES_NO|wxICON_QUESTION) == wxYES);
-
+        
         if (!Ok)
         {
             event.Veto();
             return;
         }
         if (!Ok)
         {
             event.Veto();
             return;
         }
-
+        
         wxGetApp().params = savedParamSettings;
     }
 
     if (GetParent() != NULL)
         GetParent()->SetFocus();
         wxGetApp().params = savedParamSettings;
     }
 
     if (GetParent() != NULL)
         GetParent()->SetFocus();
-    this->Destroy();
 
 
-}  // Cparameter::OnCloseWindow()
+    while (wxIsBusy())
+        wxEndBusyCursor();
+
+    Show(FALSE);
+    SetReturnCode(0);  // added so BoundsChecker would not report use of uninitialized variable
+
+    this->Destroy();
+}  // CparameterDlg::OnCloseWindow()
 
 
 void CparameterDlg::OnButton( wxCommandEvent &event )
 
 
 void CparameterDlg::OnButton( wxCommandEvent &event )
@@ -1382,6 +1497,7 @@ void CparameterDlg::OnButton( wxCommandEvent &event )
     OnCommand( *win, event );
 }
 
     OnCommand( *win, event );
 }
 
+
 void CparameterDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
 {
     wxString widgetName;
 void CparameterDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
 {
     wxString widgetName;
@@ -1442,7 +1558,7 @@ bool CparameterDlg::GetData()
             wxMessageBox(errmsg,"Internal program error...",wxOK | wxICON_EXCLAMATION);
             return FALSE;
         }
             wxMessageBox(errmsg,"Internal program error...",wxOK | wxICON_EXCLAMATION);
             return FALSE;
         }
-        strcpy(wxGetApp().params.ODBCSource, tStr);
+        wxStrcpy(wxGetApp().params.ODBCSource, tStr);
     }
     else
         return FALSE;
     }
     else
         return FALSE;
@@ -1455,7 +1571,7 @@ bool CparameterDlg::GetData()
         wxMessageBox(errmsg,"Internal program error...",wxOK | wxICON_EXCLAMATION);
         return FALSE;
     }
         wxMessageBox(errmsg,"Internal program error...",wxOK | wxICON_EXCLAMATION);
         return FALSE;
     }
-    strcpy(wxGetApp().params.UserName, tStr);
+    wxStrcpy(wxGetApp().params.UserName, tStr);
 
     tStr = pParamPasswordTxt->GetValue();
     if (tStr.Length() > (sizeof(wxGetApp().params.Password)-1))
 
     tStr = pParamPasswordTxt->GetValue();
     if (tStr.Length() > (sizeof(wxGetApp().params.Password)-1))
@@ -1465,7 +1581,7 @@ bool CparameterDlg::GetData()
         wxMessageBox(errmsg,"Internal program error...",wxOK | wxICON_EXCLAMATION);
         return FALSE;
     }
         wxMessageBox(errmsg,"Internal program error...",wxOK | wxICON_EXCLAMATION);
         return FALSE;
     }
-    strcpy(wxGetApp().params.Password,tStr);
+    wxStrcpy(wxGetApp().params.Password,tStr);
 
     tStr = pParamDirPathTxt->GetValue();
     tStr.Replace("\\","/");
 
     tStr = pParamDirPathTxt->GetValue();
     tStr.Replace("\\","/");
@@ -1476,7 +1592,7 @@ bool CparameterDlg::GetData()
         wxMessageBox(errmsg,"Internal program error...",wxOK | wxICON_EXCLAMATION);
         return FALSE;
     }
         wxMessageBox(errmsg,"Internal program error...",wxOK | wxICON_EXCLAMATION);
         return FALSE;
     }
-    strcpy(wxGetApp().params.DirPath,tStr);
+    wxStrcpy(wxGetApp().params.DirPath,tStr);
     return TRUE;
 }  // CparameterDlg::GetData()
 
     return TRUE;
 }  // CparameterDlg::GetData()
 
@@ -1519,7 +1635,7 @@ void CparameterDlg::FillDataSourceList()
     char DsDesc[255];
     wxStringList strList;
 
     char DsDesc[255];
     wxStringList strList;
 
-    while(GetDataSource(DbConnectInf.Henv, Dsn, SQL_MAX_DSN_LENGTH+1, DsDesc, 255))
+    while (wxDbGetDataSource(DbConnectInf.Henv, Dsn, SQL_MAX_DSN_LENGTH+1, DsDesc, 255))
         strList.Add(Dsn);
 
     strList.Sort();
         strList.Add(Dsn);
 
     strList.Sort();
@@ -1527,8 +1643,10 @@ void CparameterDlg::FillDataSourceList()
     char **p = strList.ListToArray();
 
     int i;
     char **p = strList.ListToArray();
 
     int i;
-    for (i = 0; strlen(p[i]); i++)
+    for (i = 0; wxStrlen(p[i]); i++)
         pParamODBCSourceList->Append(p[i]);
         pParamODBCSourceList->Append(p[i]);
+
+     delete p;
 }  // CparameterDlg::CparameterDlg::FillDataSourceList()
 
 
 }  // CparameterDlg::CparameterDlg::FillDataSourceList()
 
 
@@ -1536,9 +1654,10 @@ BEGIN_EVENT_TABLE(CqueryDlg, wxDialog)
     EVT_BUTTON(-1,  CqueryDlg::OnButton)
     EVT_CLOSE(CqueryDlg::OnCloseWindow)
 END_EVENT_TABLE()
     EVT_BUTTON(-1,  CqueryDlg::OnButton)
     EVT_CLOSE(CqueryDlg::OnCloseWindow)
 END_EVENT_TABLE()
+
  
 // CqueryDlg() constructor
  
 // CqueryDlg() constructor
-CqueryDlg::CqueryDlg(wxWindow *parent, wxDB *pDb, char *tblName[], char *pWhereArg) : wxDialog (parent, QUERY_DIALOG, "Query", wxPoint(-1, -1), wxSize(480, 360))
+CqueryDlg::CqueryDlg(wxWindow *parent, wxDb *pDb, char *tblName[], char *pWhereArg) : wxDialog (parent, QUERY_DIALOG, "Query", wxPoint(-1, -1), wxSize(480, 360))
 {
     wxBeginBusyCursor();
 
 {
     wxBeginBusyCursor();
 
@@ -1550,7 +1669,7 @@ CqueryDlg::CqueryDlg(wxWindow *parent, wxDB *pDb, char *tblName[], char *pWhereA
 
     // Initialize the WHERE clause from the string passed in
     pWhere = pWhereArg;                                            // Save a pointer to the output buffer
 
     // Initialize the WHERE clause from the string passed in
     pWhere = pWhereArg;                                            // Save a pointer to the output buffer
-    if (strlen(pWhere) > DB_MAX_WHERE_CLAUSE_LEN)        // Check the length of the buffer passed in
+    if (wxStrlen(pWhere) > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN)  // Check the length of the buffer passed in
     {
         wxString s;
         s.Printf("Maximum where clause length exceeded.\nLength must be less than %d", DB_MAX_WHERE_CLAUSE_LEN+1);
     {
         wxString s;
         s.Printf("Maximum where clause length exceeded.\nLength must be less than %d", DB_MAX_WHERE_CLAUSE_LEN+1);
@@ -1583,7 +1702,7 @@ CqueryDlg::CqueryDlg(wxWindow *parent, wxDB *pDb, char *tblName[], char *pWhereA
     pQuerySqlWhereMtxt      = new wxTextCtrl(this, QUERY_DIALOG_WHERE_TEXT,     "",                     wxPoint( 10, 159), wxSize(377, 134), wxTE_MULTILINE, wxDefaultValidator, "QuerySqlWhereMtxt");
     pQueryAddBtn            = new wxButton(this, QUERY_DIALOG_ADD,              "&Add",                 wxPoint(406,  24), wxSize( 56,  26), 0, wxDefaultValidator, "QueryAddBtn");
     pQueryAndBtn            = new wxButton(this, QUERY_DIALOG_AND,              "A&nd",                 wxPoint(406,  58), wxSize( 56,  26), 0, wxDefaultValidator, "QueryAndBtn");
     pQuerySqlWhereMtxt      = new wxTextCtrl(this, QUERY_DIALOG_WHERE_TEXT,     "",                     wxPoint( 10, 159), wxSize(377, 134), wxTE_MULTILINE, wxDefaultValidator, "QuerySqlWhereMtxt");
     pQueryAddBtn            = new wxButton(this, QUERY_DIALOG_ADD,              "&Add",                 wxPoint(406,  24), wxSize( 56,  26), 0, wxDefaultValidator, "QueryAddBtn");
     pQueryAndBtn            = new wxButton(this, QUERY_DIALOG_AND,              "A&nd",                 wxPoint(406,  58), wxSize( 56,  26), 0, wxDefaultValidator, "QueryAndBtn");
-    pQueryOrBtn                = new wxButton(this, QUERY_DIALOG_OR,            "&Or",                  wxPoint(406,  92), wxSize( 56,  26), 0, wxDefaultValidator, "QueryOrBtn");
+    pQueryOrBtn             = new wxButton(this, QUERY_DIALOG_OR,               "&Or",                  wxPoint(406,  92), wxSize( 56,  26), 0, wxDefaultValidator, "QueryOrBtn");
     pQueryLParenBtn         = new wxButton(this, QUERY_DIALOG_LPAREN,           "(",                    wxPoint(406, 126), wxSize( 26,  26), 0, wxDefaultValidator, "QueryLParenBtn");
     pQueryRParenBtn         = new wxButton(this, QUERY_DIALOG_RPAREN,           ")",                    wxPoint(436, 126), wxSize( 26,  26), 0, wxDefaultValidator, "QueryRParenBtn");
     pQueryDoneBtn           = new wxButton(this, QUERY_DIALOG_DONE,             "&Done",                wxPoint(406, 185), wxSize( 56,  26), 0, wxDefaultValidator, "QueryDoneBtn");
     pQueryLParenBtn         = new wxButton(this, QUERY_DIALOG_LPAREN,           "(",                    wxPoint(406, 126), wxSize( 26,  26), 0, wxDefaultValidator, "QueryLParenBtn");
     pQueryRParenBtn         = new wxButton(this, QUERY_DIALOG_RPAREN,           ")",                    wxPoint(436, 126), wxSize( 26,  26), 0, wxDefaultValidator, "QueryRParenBtn");
     pQueryDoneBtn           = new wxButton(this, QUERY_DIALOG_DONE,             "&Done",                wxPoint(406, 185), wxSize( 56,  26), 0, wxDefaultValidator, "QueryDoneBtn");
@@ -1607,17 +1726,17 @@ CqueryDlg::CqueryDlg(wxWindow *parent, wxDB *pDb, char *tblName[], char *pWhereA
         wxEndBusyCursor();
         wxString tStr;
         tStr  = "ODBC error during GetColumns()\n\n";
         wxEndBusyCursor();
         wxString tStr;
         tStr  = "ODBC error during GetColumns()\n\n";
-        tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+        tStr += GetExtendedDBErrorMsg(pDb,__FILE__,__LINE__);
         wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
         return;
     }
 
     int i;
         wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
         return;
     }
 
     int i;
-    for (i = 0; colInf[i].colName && strlen(colInf[i].colName); i++)
+    for (i = 0; colInf[i].colName && wxStrlen(colInf[i].colName); i++)
     {
         // If there is more than one table being queried, qualify
         // the column names with the table name prefix.
     {
         // If there is more than one table being queried, qualify
         // the column names with the table name prefix.
-        if (tblName[1] && strlen(tblName[1]))
+        if (tblName[1] && wxStrlen(tblName[1]))
         {
             qualName.Printf("%s.%s", colInf[i].tableName, colInf[i].colName);
             pQueryCol1Choice->Append(qualName);
         {
             qualName.Printf("%s.%s", colInf[i].tableName, colInf[i].colName);
             pQueryCol1Choice->Append(qualName);
@@ -1646,15 +1765,20 @@ CqueryDlg::CqueryDlg(wxWindow *parent, wxDB *pDb, char *tblName[], char *pWhereA
     // Display the dialog window
     Centre(wxBOTH);
     ShowModal();
     // Display the dialog window
     Centre(wxBOTH);
     ShowModal();
-
 }  // CqueryDlg() constructor
 
 
 }  // CqueryDlg() constructor
 
 
-void CqueryDlg::OnButton( wxCommandEvent &event )
+CqueryDlg::~CqueryDlg()
+{
+}  // CqueryDlg::~CqueryDlg() destructor
+
+
+void CqueryDlg::OnButton(wxCommandEvent &event)
 {
   wxWindow *win = (wxWindow*) event.GetEventObject();
   OnCommand( *win, event );
 {
   wxWindow *win = (wxWindow*) event.GetEventObject();
   OnCommand( *win, event );
-}
+}  // CqueryDlg::OnButton()
+
 
 void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
 {
 
 void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
 {
@@ -1672,33 +1796,33 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         // Set the help text
         switch((qryOp) pQueryOperatorChoice->GetSelection())
         {
         // Set the help text
         switch((qryOp) pQueryOperatorChoice->GetSelection())
         {
-        case qryOpEQ:
-            pQueryHintMsg->SetLabel(langQRY_EQ);
-            break;
-        case qryOpLT:
-            pQueryHintMsg->SetLabel(langQRY_LT);
-            break;
-        case qryOpGT:
-            pQueryHintMsg->SetLabel(langQRY_GT);
-            break;
-        case qryOpLE:
-            pQueryHintMsg->SetLabel(langQRY_LE);
-            break;
-        case qryOpGE:
-            pQueryHintMsg->SetLabel(langQRY_GE);
-            break;
-        case qryOpBEGINS:
-            pQueryHintMsg->SetLabel(langQRY_BEGINS);
-            break;
-        case qryOpCONTAINS:
-            pQueryHintMsg->SetLabel(langQRY_CONTAINS);
-            break;
-        case qryOpLIKE:
-            pQueryHintMsg->SetLabel(langQRY_LIKE);
-            break;
-        case qryOpBETWEEN:
-            pQueryHintMsg->SetLabel(langQRY_BETWEEN);
-            break;
+            case qryOpEQ:
+                pQueryHintMsg->SetLabel(langQRY_EQ);
+                break;
+            case qryOpLT:
+                pQueryHintMsg->SetLabel(langQRY_LT);
+                break;
+            case qryOpGT:
+                pQueryHintMsg->SetLabel(langQRY_GT);
+                break;
+            case qryOpLE:
+                pQueryHintMsg->SetLabel(langQRY_LE);
+                break;
+            case qryOpGE:
+                pQueryHintMsg->SetLabel(langQRY_GE);
+                break;
+            case qryOpBEGINS:
+                pQueryHintMsg->SetLabel(langQRY_BEGINS);
+                break;
+            case qryOpCONTAINS:
+                pQueryHintMsg->SetLabel(langQRY_CONTAINS);
+                break;
+            case qryOpLIKE:
+                pQueryHintMsg->SetLabel(langQRY_LIKE);
+                break;
+            case qryOpBETWEEN:
+                pQueryHintMsg->SetLabel(langQRY_BETWEEN);
+                break;
         }
 
         // Hide the value2 widget
         }
 
         // Hide the value2 widget
@@ -1708,57 +1832,57 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         // Disable the NOT operator for <, <=, >, >=
         switch((qryOp) pQueryOperatorChoice->GetSelection())
         {
         // Disable the NOT operator for <, <=, >, >=
         switch((qryOp) pQueryOperatorChoice->GetSelection())
         {
-        case qryOpLT:
-        case qryOpGT:
-        case qryOpLE:
-        case qryOpGE:
-            pQueryNotCheck->SetValue(0);
-            pQueryNotCheck->Enable(FALSE);
-            break;
-        default:
-            pQueryNotCheck->Enable(TRUE);
-            break;
+            case qryOpLT:
+            case qryOpGT:
+            case qryOpLE:
+            case qryOpGE:
+                pQueryNotCheck->SetValue(0);
+                pQueryNotCheck->Enable(FALSE);
+                break;
+            default:
+                pQueryNotCheck->Enable(TRUE);
+                break;
         }
 
         // Manipulate the dialog to handle the selected operator
         switch((qryOp) pQueryOperatorChoice->GetSelection())
         {
         }
 
         // Manipulate the dialog to handle the selected operator
         switch((qryOp) pQueryOperatorChoice->GetSelection())
         {
-        case qryOpEQ:
-        case qryOpLT:
-        case qryOpGT:
-        case qryOpLE:
-        case qryOpGE:
-            pQueryCol2Choice->Enable(TRUE);
-            if (pQueryCol2Choice->GetSelection())    // Column name is highlighted
-            {
-                pQueryValue1Msg->Show(FALSE);
-                pQueryValue1Txt->Show(FALSE);
-            }
-            else                                                // "Value" is highlighted
-            {
+            case qryOpEQ:
+            case qryOpLT:
+            case qryOpGT:
+            case qryOpLE:
+            case qryOpGE:
+                pQueryCol2Choice->Enable(TRUE);
+                if (pQueryCol2Choice->GetSelection())    // Column name is highlighted
+                {
+                    pQueryValue1Msg->Show(FALSE);
+                    pQueryValue1Txt->Show(FALSE);
+                }
+                else                                                // "Value" is highlighted
+                {
+                    pQueryValue1Msg->Show(TRUE);
+                    pQueryValue1Txt->Show(TRUE);
+                    pQueryValue1Txt->SetFocus();
+                }
+                break;
+            case qryOpBEGINS:
+            case qryOpCONTAINS:
+            case qryOpLIKE:
+                pQueryCol2Choice->SetSelection(0);
+                pQueryCol2Choice->Enable(FALSE);
                 pQueryValue1Msg->Show(TRUE);
                 pQueryValue1Txt->Show(TRUE);
                 pQueryValue1Txt->SetFocus();
                 pQueryValue1Msg->Show(TRUE);
                 pQueryValue1Txt->Show(TRUE);
                 pQueryValue1Txt->SetFocus();
-            }
-            break;
-        case qryOpBEGINS:
-        case qryOpCONTAINS:
-        case qryOpLIKE:
-            pQueryCol2Choice->SetSelection(0);
-            pQueryCol2Choice->Enable(FALSE);
-            pQueryValue1Msg->Show(TRUE);
-            pQueryValue1Txt->Show(TRUE);
-            pQueryValue1Txt->SetFocus();
-            break;
-        case qryOpBETWEEN:
-            pQueryCol2Choice->SetSelection(0);
-            pQueryCol2Choice->Enable(FALSE);
-            pQueryValue2Msg->Show(TRUE);
-            pQueryValue2Txt->Show(TRUE);
-            pQueryValue1Msg->Show(TRUE);
-            pQueryValue1Txt->Show(TRUE);
-            pQueryValue1Txt->SetFocus();
-            break;
+                break;
+            case qryOpBETWEEN:
+                pQueryCol2Choice->SetSelection(0);
+                pQueryCol2Choice->Enable(FALSE);
+                pQueryValue2Msg->Show(TRUE);
+                pQueryValue2Txt->Show(TRUE);
+                pQueryValue1Msg->Show(TRUE);
+                pQueryValue1Txt->Show(TRUE);
+                pQueryValue1Txt->SetFocus();
+                break;
         }
 
         return;
         }
 
         return;
@@ -1780,7 +1904,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
             pQueryValue1Txt->SetFocus();
         }
         return;
             pQueryValue1Txt->SetFocus();
         }
         return;
-
     }  // Column 2 choice
 
     // Add button
     }  // Column 2 choice
 
     // Add button
@@ -1788,7 +1911,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         ProcessAddBtn();
         return;
     {
         ProcessAddBtn();
         return;
-
     }  // Add button
 
     // And button
     }  // Add button
 
     // And button
@@ -1796,7 +1918,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         AppendToWhere(" AND\n");
         return;
     {
         AppendToWhere(" AND\n");
         return;
-
     }  // And button
 
     // Or button
     }  // And button
 
     // Or button
@@ -1804,7 +1925,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         AppendToWhere(" OR\n");
         return;
     {
         AppendToWhere(" OR\n");
         return;
-
     }  // Or button
 
     // Left Paren button
     }  // Or button
 
     // Left Paren button
@@ -1812,7 +1932,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         AppendToWhere("(");
         return;
     {
         AppendToWhere("(");
         return;
-
     }  // Left Paren button
 
     // Right paren button
     }  // Left Paren button
 
     // Right paren button
@@ -1820,14 +1939,13 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
     {
         AppendToWhere(")");
         return;
     {
         AppendToWhere(")");
         return;
-
     }  // Right Paren button
 
     // Done button
     if (widgetName == pQueryDoneBtn->GetName())
     {
         // Be sure the where clause will not overflow the output buffer
     }  // Right Paren button
 
     // Done button
     if (widgetName == pQueryDoneBtn->GetName())
     {
         // Be sure the where clause will not overflow the output buffer
-        if (strlen(pQuerySqlWhereMtxt->GetValue()) > DB_MAX_WHERE_CLAUSE_LEN)
+        if (wxStrlen(pQuerySqlWhereMtxt->GetValue()) > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN)
         {
             wxString s;
             s.Printf("Maximum where clause length exceeded.\nLength must be less than %d", DB_MAX_WHERE_CLAUSE_LEN+1);
         {
             wxString s;
             s.Printf("Maximum where clause length exceeded.\nLength must be less than %d", DB_MAX_WHERE_CLAUSE_LEN+1);
@@ -1838,10 +1956,9 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         if (!ValidateWhereClause())
             return;
         // Copy the where clause to the output buffer and exit
         if (!ValidateWhereClause())
             return;
         // Copy the where clause to the output buffer and exit
-        strcpy(pWhere, pQuerySqlWhereMtxt->GetValue());
+        wxStrcpy(pWhere, pQuerySqlWhereMtxt->GetValue());
         Close();
         return;
         Close();
         return;
-
     }  // Done button
 
     // Clear button
     }  // Done button
 
     // Clear button
@@ -1852,7 +1969,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         if (Ok)
             pQuerySqlWhereMtxt->SetValue("");
         return;
         if (Ok)
             pQuerySqlWhereMtxt->SetValue("");
         return;
-
     }  // Clear button
 
     // Count button
     }  // Clear button
 
     // Count button
@@ -1862,7 +1978,6 @@ void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
         ProcessCountBtn();
         wxEndBusyCursor();
         return;
         ProcessCountBtn();
         wxEndBusyCursor();
         return;
-
     }  // Count button
 
 }  // CqueryDlg::OnCommand
     }  // Count button
 
 }  // CqueryDlg::OnCommand
@@ -1887,17 +2002,18 @@ void CqueryDlg::OnCloseWindow(wxCloseEvent& event)
     while (wxIsBusy())
         wxEndBusyCursor();
 
     while (wxIsBusy())
         wxEndBusyCursor();
 
-    this->Destroy();
+    Show(FALSE);
+    SetReturnCode(1);  // added so BoundsChecker would not report use of uninitialized variable
 
 
+    this->Destroy();
 }  // CqueryDlg::OnCloseWindow()
 
 
 void CqueryDlg::AppendToWhere(char *s)
 {
 }  // CqueryDlg::OnCloseWindow()
 
 
 void CqueryDlg::AppendToWhere(char *s)
 {
-        wxString whereStr = pQuerySqlWhereMtxt->GetValue();
-        whereStr += s;
-        pQuerySqlWhereMtxt->SetValue(whereStr);
-
+    wxString whereStr = pQuerySqlWhereMtxt->GetValue();
+    whereStr += s;
+    pQuerySqlWhereMtxt->SetValue(whereStr);
 }  // CqueryDlg::AppendToWhere()
 
 
 }  // CqueryDlg::AppendToWhere()
 
 
@@ -1909,7 +2025,7 @@ void CqueryDlg::ProcessAddBtn()
     if (pQueryCol2Choice->GetSelection() == 0)            // "Value" is selected
     {
         // Verify that value 1 is filled in
     if (pQueryCol2Choice->GetSelection() == 0)            // "Value" is selected
     {
         // Verify that value 1 is filled in
-        if (strlen(pQueryValue1Txt->GetValue()) == 0)
+        if (wxStrlen(pQueryValue1Txt->GetValue()) == 0)
         {
             wxBell();
             pQueryValue1Txt->SetFocus();
         {
             wxBell();
             pQueryValue1Txt->SetFocus();
@@ -1917,7 +2033,7 @@ void CqueryDlg::ProcessAddBtn()
         }
         // For the BETWEEN operator, value 2 must be filled in as well
         if (oper == qryOpBETWEEN &&
         }
         // For the BETWEEN operator, value 2 must be filled in as well
         if (oper == qryOpBETWEEN &&
-             strlen(pQueryValue2Txt->GetValue()) == 0)
+             wxStrlen(pQueryValue2Txt->GetValue()) == 0)
         {
             wxBell();
             pQueryValue2Txt->SetFocus();
         {
             wxBell();
             pQueryValue2Txt->SetFocus();
@@ -2007,29 +2123,32 @@ void CqueryDlg::ProcessCountBtn()
     if (!ValidateWhereClause())
         return;
 
     if (!ValidateWhereClause())
         return;
 
-    if (dbTable == 0)  // wxTable object needs to be created and opened
+    if (dbTable == 0)  // wxDbTable object needs to be created and opened
     {
     {
-        if (!(dbTable = new wxTable(pDB, masterTableName, 0, NULL, !QUERY_ONLY, DbConnectInf.defaultDir)))
+        if (!(dbTable = new wxDbTable(pDB, masterTableName, 0, NULL, !wxDB_QUERY_ONLY, DbConnectInf.defaultDir)))
         {
         {
-            wxMessageBox("Memory allocation failed creating a wxTable object.","Error...",wxOK | wxICON_EXCLAMATION);
+            wxMessageBox("Memory allocation failed creating a wxDbTable object.","Error...",wxOK | wxICON_EXCLAMATION);
             return;
         }
         if (!dbTable->Open())
         {
             wxString tStr;
             tStr  = "ODBC error during Open()\n\n";
             return;
         }
         if (!dbTable->Open())
         {
             wxString tStr;
             tStr  = "ODBC error during Open()\n\n";
-            tStr += GetExtendedDBErrorMsg(__FILE__,__LINE__);
+            tStr += GetExtendedDBErrorMsg(dbTable->GetDb(),__FILE__,__LINE__);
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
             return;
         }
     }
 
     // Count() with WHERE clause
             wxMessageBox(tStr,"ODBC Error...",wxOK | wxICON_EXCLAMATION);
             return;
         }
     }
 
     // Count() with WHERE clause
-    dbTable->where = (char*) (const char*) pQuerySqlWhereMtxt->GetValue();
+    wxString whereStr;
+
+    whereStr = pQuerySqlWhereMtxt->GetValue();
+    dbTable->SetWhereClause(whereStr.c_str());
     ULONG whereCnt = dbTable->Count();
 
     // Count() of all records in the table
     ULONG whereCnt = dbTable->Count();
 
     // Count() of all records in the table
-    dbTable->where = 0;
+    dbTable->SetWhereClause("");
     ULONG totalCnt = dbTable->Count();
 
     if (whereCnt > 0 || totalCnt == 0)
     ULONG totalCnt = dbTable->Count();
 
     if (whereCnt > 0 || totalCnt == 0)
@@ -2070,3 +2189,29 @@ bool CqueryDlg::ValidateWhereClause()
     return(TRUE);
 
 }  // CqueryDlg::ValidateWhereClause()
     return(TRUE);
 
 }  // CqueryDlg::ValidateWhereClause()
+
+
+
+
+/*
+    TEST CODE FOR TESTING THE wxDbCreateDataSource() FUNCTION
+
+        int result = 0;
+        result = wxDbCreateDataSource("Microsoft Access Driver (*.mdb)","GLT-TEST2","GLT-Descrip",FALSE,"",this);
+        if (!result)
+        {
+            // check for errors caused by ConfigDSN based functions
+            DWORD retcode = 0;
+            WORD cb;
+            wxChar errMsg[500+1];
+            errMsg[0] = '\0';
+
+            SQLInstallerError(1,&retcode,errMsg,500,&cb);
+
+            wxMessageBox("FAILED creating data source","FAILED");
+        }
+        else
+            wxMessageBox("SUCCEEDED creating data source","SUCCESS");
+*/
+
+