git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14703 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			3006 lines
		
	
	
		
			107 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			3006 lines
		
	
	
		
			107 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        dbtest.cpp
 | 
						|
// Purpose:     wxWindows database demo app
 | 
						|
// Author:      George Tasker
 | 
						|
// Modified by:
 | 
						|
// Created:     1998
 | 
						|
// RCS-ID:      $Id$
 | 
						|
// Copyright:   (c) 1998 Remstar International, Inc.
 | 
						|
// Licence:     wxWindows licence
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
/*
 | 
						|
 *  SYNOPSIS START
 | 
						|
 | 
						|
    This sample program demonstrates the cross-platform ODBC database classes
 | 
						|
    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 wxDbTable.
 | 
						|
 | 
						|
 *  SYNOPSIS END
 | 
						|
 */
 | 
						|
 | 
						|
#ifdef __GNUG__
 | 
						|
#pragma implementation "dbtest.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#include  "wx/wxprec.h"
 | 
						|
 | 
						|
#ifdef    __BORLANDC__
 | 
						|
#pragma hdrstop
 | 
						|
#endif  //__BORLANDC__
 | 
						|
 | 
						|
#ifndef WX_PRECOMP
 | 
						|
#include  <wx/wx.h>
 | 
						|
#endif //WX_PRECOMP
 | 
						|
 | 
						|
#if defined(__WXGTK__) || defined(__WXX11__)
 | 
						|
#include "db.xpm"
 | 
						|
#endif
 | 
						|
 | 
						|
#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 wxDbTable object from which all data objects will inherit their data table functionality */
 | 
						|
 | 
						|
//extern wxDbList WXDLLEXPORT *PtrBegDbList;    /* from db.cpp, used in getting back error results from db connections */
 | 
						|
 | 
						|
#if wxUSE_NEW_GRID
 | 
						|
#include <wx/grid.h>
 | 
						|
#include <wx/generic/gridctrl.h>
 | 
						|
#include <wx/dbgrid.h>
 | 
						|
 | 
						|
#define CHOICEINT
 | 
						|
#endif
 | 
						|
 | 
						|
#include "dbtest.h"                 /* Header file for this demonstration program */
 | 
						|
#include "listdb.h"                 /* Code to support the "Lookup" button on the editor dialog */
 | 
						|
 | 
						|
IMPLEMENT_APP(DatabaseDemoApp)
 | 
						|
 | 
						|
extern wxChar ListDB_Selection[];   /* Used to return the first column value for the selected line from the listDB routines */
 | 
						|
extern wxChar ListDB_Selection2[];  /* Used to return the second column value for the selected line from the listDB routines */
 | 
						|
 | 
						|
 | 
						|
#if !wxUSE_ODBC
 | 
						|
  #error Sample cannot be compiled unless setup.h has wxUSE_ODBC set to 1
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
bool DataTypeSupported(wxDb *pDb, SWORD datatype)
 | 
						|
{
 | 
						|
    wxDbSqlTypeInfo sqlTypeInfo;
 | 
						|
 | 
						|
    bool breakpoint = FALSE;
 | 
						|
 | 
						|
    if (pDb->GetDataTypeInfo(datatype, sqlTypeInfo))
 | 
						|
        breakpoint = TRUE;
 | 
						|
 | 
						|
    return breakpoint;
 | 
						|
 | 
						|
}  // GetDataTypesSupported();
 | 
						|
 | 
						|
 | 
						|
 | 
						|
void CheckSupportForAllDataTypes(wxDb *pDb)
 | 
						|
{
 | 
						|
    wxLogMessage("\nThe following datatypes are supported by the\ndatabase you are currently connected to:");
 | 
						|
#ifdef SQL_C_BINARY
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_BINARY))
 | 
						|
        wxLogMessage("SQL_C_BINARY");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_BIT
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_BIT))
 | 
						|
        wxLogMessage("SQL_C_BIT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_BOOKMARK
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_BOOKMARK))
 | 
						|
        wxLogMessage("SQL_C_BOOKMARK");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_CHAR
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_CHAR))
 | 
						|
        wxLogMessage("SQL_C_CHAR");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_DATE
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_DATE))
 | 
						|
        wxLogMessage("SQL_C_DATE");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_DEFAULT
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_DEFAULT))
 | 
						|
        wxLogMessage("SQL_C_DEFAULT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_DOUBLE
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_DOUBLE))
 | 
						|
        wxLogMessage("SQL_C_DOUBLE");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_FLOAT
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_FLOAT))
 | 
						|
        wxLogMessage("SQL_C_FLOAT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_GUID
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_GUID))
 | 
						|
        wxLogMessage("SQL_C_GUID");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_INTERVAL_DAY
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_INTERVAL_DAY))
 | 
						|
        wxLogMessage("SQL_C_INTERVAL_DAY");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_INTERVAL_DAY_TO_HOUR
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_INTERVAL_DAY_TO_HOUR))
 | 
						|
        wxLogMessage("SQL_C_INTERVAL_DAY_TO_HOUR");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_INTERVAL_DAY_TO_MINUTE
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_INTERVAL_DAY_TO_MINUTE))
 | 
						|
        wxLogMessage("SQL_C_INTERVAL_DAY_TO_MINUTE");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_INTERVAL_DAY_TO_SECOND
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_INTERVAL_DAY_TO_SECOND))
 | 
						|
        wxLogMessage("SQL_C_INTERVAL_DAY_TO_SECOND");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_INTERVAL_HOUR
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_INTERVAL_HOUR))
 | 
						|
        wxLogMessage("SQL_C_INTERVAL_HOUR");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_INTERVAL_HOUR_TO_MINUTE
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_INTERVAL_HOUR_TO_MINUTE))
 | 
						|
        wxLogMessage("SQL_C_INTERVAL_HOUR_TO_MINUTE");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_INTERVAL_HOUR_TO_SECOND
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_INTERVAL_HOUR_TO_SECOND))
 | 
						|
        wxLogMessage("SQL_C_INTERVAL_HOUR_TO_SECOND");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_INTERVAL_MINUTE
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_INTERVAL_MINUTE))
 | 
						|
        wxLogMessage("SQL_C_INTERVAL_MINUTE");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_INTERVAL_MINUTE_TO_SECOND
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_INTERVAL_MINUTE_TO_SECOND))
 | 
						|
        wxLogMessage("SQL_C_INTERVAL_MINUTE_TO_SECOND");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_INTERVAL_MONTH
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_INTERVAL_MONTH))
 | 
						|
        wxLogMessage("SQL_C_INTERVAL_MONTH");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_INTERVAL_SECOND
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_INTERVAL_SECOND))
 | 
						|
        wxLogMessage("SQL_C_INTERVAL_SECOND");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_INTERVAL_YEAR
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_INTERVAL_YEAR))
 | 
						|
        wxLogMessage("SQL_C_INTERVAL_YEAR");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_INTERVAL_YEAR_TO_MONTH
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_INTERVAL_YEAR_TO_MONTH))
 | 
						|
        wxLogMessage("SQL_C_INTERVAL_YEAR_TO_MONTH");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_LONG
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_LONG))
 | 
						|
        wxLogMessage("SQL_C_LONG");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_NUMERIC
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_NUMERIC))
 | 
						|
        wxLogMessage("SQL_C_NUMERIC");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_SBIGINT
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_SBIGINT))
 | 
						|
        wxLogMessage("SQL_C_SBIGINT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_SHORT
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_SHORT))
 | 
						|
        wxLogMessage("SQL_C_SHORT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_SLONG
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_SLONG))
 | 
						|
        wxLogMessage("SQL_C_SLONG");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_SSHORT
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_SSHORT))
 | 
						|
        wxLogMessage("SQL_C_SSHORT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_STINYINT
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_STINYINT))
 | 
						|
        wxLogMessage("SQL_C_STINYINT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_TIME
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_TIME))
 | 
						|
        wxLogMessage("SQL_C_TIME");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_TIMESTAMP
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_TIMESTAMP))
 | 
						|
        wxLogMessage("SQL_C_TIMESTAMP");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_TINYINT
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_TINYINT))
 | 
						|
        wxLogMessage("SQL_C_TINYINT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_TYPE_DATE
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_TYPE_DATE))
 | 
						|
        wxLogMessage("SQL_C_TYPE_DATE");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_TYPE_TIME
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_TYPE_TIME))
 | 
						|
        wxLogMessage("SQL_C_TYPE_TIME");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_TYPE_TIMESTAMP
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_TYPE_TIMESTAMP))
 | 
						|
        wxLogMessage("SQL_C_TYPE_TIMESTAMP");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_UBIGINT
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_UBIGINT))
 | 
						|
        wxLogMessage("SQL_C_UBIGINT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_ULONG
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_ULONG))
 | 
						|
        wxLogMessage("SQL_C_ULONG");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_USHORT
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_USHORT))
 | 
						|
        wxLogMessage("SQL_C_USHORT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_UTINYINT
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_UTINYINT))
 | 
						|
        wxLogMessage("SQL_C_UTINYINT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_C_VARBOOKMARK
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_VARBOOKMARK))
 | 
						|
        wxLogMessage("SQL_C_VARBOOKMARK");
 | 
						|
#endif
 | 
						|
 | 
						|
// Extended SQL types
 | 
						|
#ifdef SQL_DATE
 | 
						|
    if (DataTypeSupported(pDb,SQL_DATE))
 | 
						|
        wxLogMessage("SQL_DATE");
 | 
						|
#endif
 | 
						|
#ifdef SQL_INTERVAL
 | 
						|
    if (DataTypeSupported(pDb,SQL_INTERVAL))
 | 
						|
        wxLogMessage("SQL_INTERVAL");
 | 
						|
#endif
 | 
						|
#ifdef SQL_TIME
 | 
						|
    if (DataTypeSupported(pDb,SQL_TIME))
 | 
						|
        wxLogMessage("SQL_TIME");
 | 
						|
#endif
 | 
						|
#ifdef SQL_TIMESTAMP
 | 
						|
    if (DataTypeSupported(pDb,SQL_TIMESTAMP))
 | 
						|
        wxLogMessage("SQL_TIMESTAMP");
 | 
						|
#endif
 | 
						|
#ifdef SQL_LONGVARCHAR
 | 
						|
    if (DataTypeSupported(pDb,SQL_LONGVARCHAR))
 | 
						|
        wxLogMessage("SQL_LONGVARCHAR");
 | 
						|
#endif
 | 
						|
#ifdef SQL_BINARY
 | 
						|
    if (DataTypeSupported(pDb,SQL_BINARY))
 | 
						|
        wxLogMessage("SQL_BINARY");
 | 
						|
#endif
 | 
						|
#ifdef SQL_VARBINARY
 | 
						|
    if (DataTypeSupported(pDb,SQL_VARBINARY))
 | 
						|
        wxLogMessage("SQL_VARBINARY");
 | 
						|
#endif
 | 
						|
#ifdef SQL_LONGVARBINARY
 | 
						|
    if (DataTypeSupported(pDb,SQL_LONGVARBINARY))
 | 
						|
        wxLogMessage("SQL_LONGVARBINARY");
 | 
						|
#endif
 | 
						|
#ifdef SQL_BIGINT
 | 
						|
    if (DataTypeSupported(pDb,SQL_BIGINT))
 | 
						|
        wxLogMessage("SQL_BIGINT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_TINYINT
 | 
						|
    if (DataTypeSupported(pDb,SQL_TINYINT))
 | 
						|
        wxLogMessage("SQL_TINYINT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_BIT
 | 
						|
    if (DataTypeSupported(pDb,SQL_BIT))
 | 
						|
        wxLogMessage("SQL_BIT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_GUID
 | 
						|
    if (DataTypeSupported(pDb,SQL_GUID))
 | 
						|
        wxLogMessage("SQL_GUID");
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef SQL_CHAR
 | 
						|
    if (DataTypeSupported(pDb,SQL_CHAR))
 | 
						|
        wxLogMessage("SQL_CHAR");
 | 
						|
#endif
 | 
						|
#ifdef SQL_INTEGER
 | 
						|
    if (DataTypeSupported(pDb,SQL_INTEGER))
 | 
						|
        wxLogMessage("SQL_INTEGER");
 | 
						|
#endif
 | 
						|
#ifdef SQL_SMALLINT
 | 
						|
    if (DataTypeSupported(pDb,SQL_SMALLINT))
 | 
						|
        wxLogMessage("SQL_SMALLINT");
 | 
						|
#endif
 | 
						|
#ifdef SQL_REAL
 | 
						|
    if (DataTypeSupported(pDb,SQL_REAL))
 | 
						|
        wxLogMessage("SQL_REAL");
 | 
						|
#endif
 | 
						|
#ifdef SQL_DOUBLE
 | 
						|
    if (DataTypeSupported(pDb,SQL_DOUBLE))
 | 
						|
        wxLogMessage("SQL_DOUBLE");
 | 
						|
#endif
 | 
						|
#ifdef SQL_NUMERIC
 | 
						|
    if (DataTypeSupported(pDb,SQL_NUMERIC))
 | 
						|
        wxLogMessage("SQL_NUMERIC");
 | 
						|
#endif
 | 
						|
#ifdef SQL_DATE
 | 
						|
    if (DataTypeSupported(pDb,SQL_DATE))
 | 
						|
        wxLogMessage("SQL_DATE");
 | 
						|
#endif
 | 
						|
#ifdef SQL_TIME
 | 
						|
    if (DataTypeSupported(pDb,SQL_TIME))
 | 
						|
        wxLogMessage("SQL_TIME");
 | 
						|
#endif
 | 
						|
#ifdef SQL_TIMESTAMP
 | 
						|
    if (DataTypeSupported(pDb,SQL_TIMESTAMP))
 | 
						|
        wxLogMessage("SQL_TIMESTAMP");
 | 
						|
#endif
 | 
						|
#ifdef SQL_VARCHAR
 | 
						|
    if (DataTypeSupported(pDb,SQL_VARCHAR))
 | 
						|
        wxLogMessage("SQL_VARCHAR");
 | 
						|
#endif
 | 
						|
 | 
						|
// UNICODE
 | 
						|
#ifdef SQL_C_TCHAR
 | 
						|
    if (DataTypeSupported(pDb,SQL_C_TCHAR))
 | 
						|
        wxLogMessage("SQL_C_TCHAR (Unicode support is possible)");
 | 
						|
#endif
 | 
						|
 | 
						|
    wxLogMessage("\n");
 | 
						|
}  // CheckSupportForAllDataTypes()
 | 
						|
 | 
						|
 | 
						|
bool DatabaseDemoApp::OnInit()
 | 
						|
{
 | 
						|
    DbConnectInf    = NULL;
 | 
						|
    Contact         = NULL;
 | 
						|
 | 
						|
    // Create the main frame window
 | 
						|
    DemoFrame = new DatabaseDemoFrame(NULL, wxT("wxWindows Database Demo"), wxPoint(50, 50), wxSize(537, 480));
 | 
						|
 | 
						|
    // Give it an icon
 | 
						|
    DemoFrame->SetIcon(wxICON(db));
 | 
						|
 | 
						|
    // Make a menubar
 | 
						|
    wxMenu *file_menu = new wxMenu;
 | 
						|
    file_menu->Append(FILE_CREATE, wxT("&Create CONTACT table"));
 | 
						|
    file_menu->Append(FILE_RECREATE_TABLE, wxT("&Recreate CONTACT table"));
 | 
						|
    file_menu->Append(FILE_RECREATE_INDEXES, wxT("&Recreate CONTACT indexes"));
 | 
						|
#if wxUSE_NEW_GRID
 | 
						|
    file_menu->Append(FILE_DBGRID_TABLE,  wxT("&Open DB Grid example"));
 | 
						|
#endif
 | 
						|
    file_menu->Append(FILE_EXIT, wxT("E&xit"));
 | 
						|
 | 
						|
    wxMenu *edit_menu = new wxMenu;
 | 
						|
    edit_menu->Append(EDIT_PARAMETERS, wxT("&Parameters..."));
 | 
						|
 | 
						|
    wxMenu *help_menu = new wxMenu;
 | 
						|
    help_menu->Append(HELP_ABOUT, wxT("&About"));
 | 
						|
 | 
						|
    wxMenuBar *menu_bar = new wxMenuBar;
 | 
						|
    menu_bar->Append(file_menu, wxT("&File"));
 | 
						|
    menu_bar->Append(edit_menu, wxT("&Edit"));
 | 
						|
    menu_bar->Append(help_menu, wxT("&Help"));
 | 
						|
    DemoFrame->SetMenuBar(menu_bar);
 | 
						|
 | 
						|
    params.ODBCSource[0] = 0;
 | 
						|
    params.UserName[0]   = 0;
 | 
						|
    params.Password[0]   = 0;
 | 
						|
    params.DirPath[0]    = 0;
 | 
						|
 | 
						|
    // Show the frame
 | 
						|
    DemoFrame->Show(TRUE);
 | 
						|
 | 
						|
    // Passing NULL for the SQL environment handle causes
 | 
						|
    // the wxDbConnectInf constructor to obtain a handle
 | 
						|
    // for you.
 | 
						|
    //
 | 
						|
    // WARNING: Be certain that you do not free this handle
 | 
						|
    //          directly with SQLFreeEnv().  Use either the
 | 
						|
    //          method ::FreeHenv() or delete the DbConnectInf.
 | 
						|
    DbConnectInf = new wxDbConnectInf(NULL, params.ODBCSource, params.UserName, 
 | 
						|
                                      params.Password, params.DirPath);
 | 
						|
 | 
						|
    if (!DbConnectInf || !DbConnectInf->GetHenv())
 | 
						|
    {
 | 
						|
        wxMessageBox(wxT("Unable to define data source connection info."), wxT("DB CONNECTION ERROR..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        wxDELETE(DbConnectInf);
 | 
						|
    }
 | 
						|
 | 
						|
    if (!ReadParamFile(params))
 | 
						|
        DemoFrame->BuildParameterDialog(NULL);
 | 
						|
 | 
						|
    if (!wxStrlen(params.ODBCSource))
 | 
						|
    {
 | 
						|
        wxDELETE(DbConnectInf);
 | 
						|
        return(FALSE);
 | 
						|
    }
 | 
						|
 | 
						|
    DbConnectInf->SetDsn(params.ODBCSource);
 | 
						|
    DbConnectInf->SetUserID(params.UserName);
 | 
						|
    DbConnectInf->SetPassword(params.Password);
 | 
						|
    DbConnectInf->SetDefaultDir(params.DirPath);
 | 
						|
 | 
						|
    READONLY_DB = wxDbGetConnection(DbConnectInf);
 | 
						|
    if (READONLY_DB == 0)
 | 
						|
    {
 | 
						|
        wxMessageBox(wxT("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)"), wxT("DB CONNECTION ERROR..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        DemoFrame->BuildParameterDialog(NULL);
 | 
						|
        wxDELETE(DbConnectInf);
 | 
						|
        wxMessageBox(wxT("Now exiting program.\n\nRestart program to try any new settings."),wxT("Notice..."),wxOK | wxICON_INFORMATION);
 | 
						|
        return(FALSE);
 | 
						|
    }
 | 
						|
 | 
						|
    DemoFrame->BuildEditorDialog();
 | 
						|
 | 
						|
    // Show the frame
 | 
						|
    DemoFrame->Refresh();
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}  // DatabaseDemoApp::OnInit()
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
* Remove CR or CR/LF from a character string.
 | 
						|
*/
 | 
						|
char* wxRemoveLineTerminator(char* aString)
 | 
						|
{
 | 
						|
    int len = strlen(aString);
 | 
						|
    while (len > 0 && (aString[len-1] == '\r' || aString[len-1] == '\n')) {
 | 
						|
        aString[len-1] = '\0';
 | 
						|
        len--;
 | 
						|
    }
 | 
						|
    return aString;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool DatabaseDemoApp::ReadParamFile(Cparameters ¶ms)
 | 
						|
{
 | 
						|
    FILE *paramFile;
 | 
						|
    if ((paramFile = fopen(PARAM_FILENAME, wxT("r"))) == NULL)
 | 
						|
    {
 | 
						|
        wxString tStr;
 | 
						|
        tStr.Printf(wxT("Unable to open the parameter file '%s' for reading.\n\nYou must specify the data source, user name, and\npassword that will be used and save those settings."),PARAM_FILENAME);
 | 
						|
        wxMessageBox(tStr,wxT("File I/O Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    wxChar buffer[1000+1];
 | 
						|
    fgets(buffer, sizeof(params.ODBCSource), paramFile);
 | 
						|
    wxRemoveLineTerminator(buffer);
 | 
						|
    wxStrcpy(params.ODBCSource,buffer);
 | 
						|
 | 
						|
    fgets(buffer, sizeof(params.UserName), paramFile);
 | 
						|
    wxRemoveLineTerminator(buffer);
 | 
						|
    wxStrcpy(params.UserName,buffer);
 | 
						|
 | 
						|
    fgets(buffer, sizeof(params.Password), paramFile);
 | 
						|
    wxRemoveLineTerminator(buffer);
 | 
						|
    wxStrcpy(params.Password,buffer);
 | 
						|
 | 
						|
    fgets(buffer, sizeof(params.DirPath), paramFile);
 | 
						|
    wxRemoveLineTerminator(buffer);
 | 
						|
    wxStrcpy(params.DirPath,buffer);
 | 
						|
 | 
						|
    fclose(paramFile);
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}  // DatabaseDemoApp::ReadParamFile()
 | 
						|
 | 
						|
 | 
						|
bool DatabaseDemoApp::WriteParamFile(Cparameters ¶ms)
 | 
						|
{
 | 
						|
    FILE *paramFile;
 | 
						|
    if ((paramFile = fopen(PARAM_FILENAME, wxT("wt"))) == NULL)
 | 
						|
    {
 | 
						|
        wxString tStr;
 | 
						|
        tStr.Printf(wxT("Unable to write/overwrite '%s'."),PARAM_FILENAME);
 | 
						|
        wxMessageBox(tStr,wxT("File I/O Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    fputs(wxGetApp().params.ODBCSource, paramFile);
 | 
						|
    fputc(wxT('\n'), paramFile);
 | 
						|
    fputs(wxGetApp().params.UserName, paramFile);
 | 
						|
    fputc(wxT('\n'), paramFile);
 | 
						|
    fputs(wxGetApp().params.Password, paramFile);
 | 
						|
    fputc(wxT('\n'), paramFile);
 | 
						|
    fputs(wxGetApp().params.DirPath, paramFile);
 | 
						|
    fputc(wxT('\n'), paramFile);
 | 
						|
    fclose(paramFile);
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}  // DatabaseDemoApp::WriteParamFile()
 | 
						|
 | 
						|
 | 
						|
void DatabaseDemoApp::CreateDataTable(bool recreate)
 | 
						|
{
 | 
						|
    bool Ok = TRUE;
 | 
						|
    if (recreate)
 | 
						|
       Ok = (wxMessageBox(wxT("Any data currently residing in the table will be erased.\n\nAre you sure?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
 | 
						|
 | 
						|
    if (!Ok)
 | 
						|
        return;
 | 
						|
 | 
						|
    wxBeginBusyCursor();
 | 
						|
 | 
						|
    bool success = TRUE;
 | 
						|
 | 
						|
    Contact->GetDb()->RollbackTrans();  // Make sure the current cursor is in a known/stable state
 | 
						|
 | 
						|
    if (!Contact->CreateTable(recreate))
 | 
						|
    {
 | 
						|
        wxEndBusyCursor();
 | 
						|
        wxString tStr;
 | 
						|
        tStr = wxT("Error creating CONTACTS table.\nTable was not created.\n\n");
 | 
						|
        wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                     wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
 | 
						|
        success = FALSE;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        if (!Contact->CreateIndexes(recreate))
 | 
						|
        {
 | 
						|
            wxEndBusyCursor();
 | 
						|
            wxString tStr;
 | 
						|
            tStr = wxT("Error creating CONTACTS indexes.\nIndexes will be unavailable.\n\n");
 | 
						|
            wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                         wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
 | 
						|
            success = FALSE;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    while (wxIsBusy())
 | 
						|
        wxEndBusyCursor();
 | 
						|
 | 
						|
    if (success)
 | 
						|
        wxMessageBox(wxT("Table and index(es) were successfully created."),wxT("Notice..."),wxOK | wxICON_INFORMATION);
 | 
						|
}  // DatabaseDemoApp::CreateDataTable()
 | 
						|
 | 
						|
 | 
						|
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)
 | 
						|
#if wxUSE_NEW_GRID
 | 
						|
    EVT_MENU(FILE_DBGRID_TABLE, DatabaseDemoFrame::OnDbGridTable)
 | 
						|
#endif
 | 
						|
    EVT_MENU(FILE_EXIT, DatabaseDemoFrame::OnExit)
 | 
						|
    EVT_MENU(EDIT_PARAMETERS, DatabaseDemoFrame::OnEditParameters)
 | 
						|
    EVT_MENU(HELP_ABOUT, DatabaseDemoFrame::OnAbout)
 | 
						|
    EVT_CLOSE(DatabaseDemoFrame::OnCloseWindow)
 | 
						|
END_EVENT_TABLE()
 | 
						|
 | 
						|
 | 
						|
// DatabaseDemoFrame constructor
 | 
						|
DatabaseDemoFrame::DatabaseDemoFrame(wxFrame *frame, const wxString& title,
 | 
						|
                                     const wxPoint& pos, const wxSize& size):
 | 
						|
                                        wxFrame(frame, -1, title, pos, size)
 | 
						|
{
 | 
						|
    // Put any code in necessary for initializing the main frame here
 | 
						|
    pEditorDlg = NULL;
 | 
						|
    pParamDlg  = NULL;
 | 
						|
 | 
						|
    delete wxLog::SetActiveTarget(new wxLogStderr);
 | 
						|
 | 
						|
}  // DatabaseDemoFrame constructor
 | 
						|
 | 
						|
DatabaseDemoFrame::~DatabaseDemoFrame()
 | 
						|
{
 | 
						|
    delete wxLog::SetActiveTarget(NULL);
 | 
						|
}  // DatabaseDemoFrame destructor
 | 
						|
 | 
						|
 | 
						|
void DatabaseDemoFrame::OnCreate(wxCommandEvent& event)
 | 
						|
{
 | 
						|
    wxGetApp().CreateDataTable(FALSE);
 | 
						|
}  // DatabaseDemoFrame::OnCreate()
 | 
						|
 | 
						|
 | 
						|
void DatabaseDemoFrame::OnRecreateTable(wxCommandEvent& event)
 | 
						|
{
 | 
						|
    wxGetApp().CreateDataTable(TRUE);
 | 
						|
}  // DatabaseDemoFrame::OnRecreate()
 | 
						|
 | 
						|
 | 
						|
void DatabaseDemoFrame::OnRecreateIndexes(wxCommandEvent& event)
 | 
						|
{
 | 
						|
    wxGetApp().Contact->GetDb()->RollbackTrans();  // Make sure the current cursor is in a known/stable state
 | 
						|
 | 
						|
    if (!wxGetApp().Contact->CreateIndexes(TRUE))
 | 
						|
    {
 | 
						|
        while (wxIsBusy())
 | 
						|
            wxEndBusyCursor();
 | 
						|
        wxString tStr;
 | 
						|
        tStr = wxT("Error creating CONTACTS indexes.\nNew indexes will be unavailable.\n\n");
 | 
						|
        wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                     wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
 | 
						|
    }
 | 
						|
     else
 | 
						|
        wxMessageBox(wxT("Index(es) were successfully recreated."),wxT("Notice..."),wxOK | wxICON_INFORMATION);
 | 
						|
 | 
						|
}  // DatabaseDemoFrame::OnRecreateIndexes()
 | 
						|
 | 
						|
 | 
						|
#if wxUSE_NEW_GRID
 | 
						|
void DatabaseDemoFrame::OnDbGridTable(wxCommandEvent& )
 | 
						|
{
 | 
						|
    DbGridFrame *frame = new DbGridFrame(this);
 | 
						|
    if (frame->Initialize())
 | 
						|
    {
 | 
						|
        frame->Show();
 | 
						|
    }
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
void DatabaseDemoFrame::OnExit(wxCommandEvent& event)
 | 
						|
{
 | 
						|
    Close();
 | 
						|
}  // DatabaseDemoFrame::OnExit()
 | 
						|
 | 
						|
 | 
						|
void DatabaseDemoFrame::OnEditParameters(wxCommandEvent& event)
 | 
						|
{
 | 
						|
    if ((pEditorDlg->mode != mCreate) && (pEditorDlg->mode != mEdit))
 | 
						|
        BuildParameterDialog(this);
 | 
						|
    else
 | 
						|
        wxMessageBox(wxT("Cannot change database parameters while creating or editing a record"),wxT("Notice..."),wxOK | wxICON_INFORMATION);
 | 
						|
}  // DatabaseDemoFrame::OnEditParameters()
 | 
						|
 | 
						|
 | 
						|
void DatabaseDemoFrame::OnAbout(wxCommandEvent& event)
 | 
						|
{
 | 
						|
    wxMessageBox(wxT("wxWindows sample program for database classes\n\nContributed on 27 July 1998"),wxT("About..."),wxOK | wxICON_INFORMATION);
 | 
						|
}  // DatabaseDemoFrame::OnAbout()
 | 
						|
 | 
						|
 | 
						|
// 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)
 | 
						|
{
 | 
						|
    // Clean up time
 | 
						|
    if (pEditorDlg && pEditorDlg->Close())
 | 
						|
        pEditorDlg = NULL;
 | 
						|
    else
 | 
						|
    {
 | 
						|
        if (pEditorDlg)
 | 
						|
        {
 | 
						|
            event.Veto();
 | 
						|
            return;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    wxDELETE(wxGetApp().Contact);
 | 
						|
 | 
						|
    // This function will close all the connections to the database that have been
 | 
						|
    // previously cached.
 | 
						|
    wxDbCloseConnections();
 | 
						|
 | 
						|
    // Deletion of the wxDbConnectInf instance must be the LAST thing done that
 | 
						|
    // has anything to do with the database.  Deleting this before disconnecting,
 | 
						|
    // freeing/closing connections, etc will result in a crash!
 | 
						|
    wxDELETE(wxGetApp().DbConnectInf);
 | 
						|
 | 
						|
    this->Destroy();
 | 
						|
 | 
						|
}  // DatabaseDemoFrame::OnCloseWindow()
 | 
						|
 | 
						|
 | 
						|
void DatabaseDemoFrame::BuildEditorDialog()
 | 
						|
{
 | 
						|
    pEditorDlg = NULL;
 | 
						|
    pEditorDlg = new CeditorDlg(this);
 | 
						|
    if (pEditorDlg)
 | 
						|
    {
 | 
						|
        pEditorDlg->Initialize();
 | 
						|
        if (!pEditorDlg->initialized)
 | 
						|
        {
 | 
						|
            pEditorDlg->Close();
 | 
						|
            pEditorDlg = NULL;
 | 
						|
            wxMessageBox(wxT("Unable to initialize the editor dialog for some reason"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
            Close();
 | 
						|
        }
 | 
						|
    } 
 | 
						|
    else
 | 
						|
    {
 | 
						|
        wxMessageBox(wxT("Unable to create the editor dialog for some reason"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        Close();
 | 
						|
    }
 | 
						|
}  // DatabaseDemoFrame::BuildEditorDialog()
 | 
						|
 | 
						|
 | 
						|
void DatabaseDemoFrame::BuildParameterDialog(wxWindow *parent)
 | 
						|
{
 | 
						|
    pParamDlg = new CparameterDlg(parent);
 | 
						|
 | 
						|
    if (!pParamDlg)
 | 
						|
        wxMessageBox(wxT("Unable to create the parameter dialog for some reason"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
}  // DatabaseDemoFrame::BuildParameterDialog()
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * 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.  
 | 
						|
 *
 | 
						|
 * 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.
 | 
						|
 */
 | 
						|
Ccontact::Ccontact (wxDb *pwxDb) : wxDbTable(pwxDb ? pwxDb : wxDbGetConnection(wxGetApp().DbConnectInf),
 | 
						|
                                             CONTACT_TABLE_NAME, CONTACT_NO_COLS, wxT(""),
 | 
						|
                                             !wxDB_QUERY_ONLY, wxGetApp().DbConnectInf->GetDefaultDir())
 | 
						|
{
 | 
						|
    // 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;
 | 
						|
    
 | 
						|
    if (GetDb())
 | 
						|
        GetDb()->SetSqlLogging(sqlLogON);
 | 
						|
 | 
						|
    SetupColumns();
 | 
						|
 | 
						|
}  // Ccontact Constructor
 | 
						|
 | 
						|
 | 
						|
void Ccontact::Initialize()
 | 
						|
{
 | 
						|
    Name[0]            = 0;
 | 
						|
    Addr1[0]           = 0;
 | 
						|
    Addr2[0]           = 0;
 | 
						|
    City[0]            = 0;
 | 
						|
    State[0]           = 0;
 | 
						|
    PostalCode[0]      = 0;
 | 
						|
    Country[0]         = 0;
 | 
						|
    JoinDate.year      = 1980;
 | 
						|
    JoinDate.month     = 1;
 | 
						|
    JoinDate.day       = 1;
 | 
						|
    JoinDate.hour      = 0;
 | 
						|
    JoinDate.minute    = 0;
 | 
						|
    JoinDate.second    = 0;
 | 
						|
    JoinDate.fraction  = 0;
 | 
						|
    NativeLanguage     = langENGLISH;
 | 
						|
    IsDeveloper        = FALSE;
 | 
						|
    Contributions      = 0;
 | 
						|
    LinesOfCode        = 0L;
 | 
						|
}  // Ccontact::Initialize
 | 
						|
 | 
						|
 | 
						|
Ccontact::~Ccontact()
 | 
						|
{
 | 
						|
    if (freeDbConn)
 | 
						|
    {
 | 
						|
        if (!wxDbFreeConnection(GetDb()))
 | 
						|
        {
 | 
						|
            wxString tStr;
 | 
						|
            tStr = wxT("Unable to Free the Ccontact data table handle\n\n");
 | 
						|
 | 
						|
            wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                         wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}  // Ccontract destructor
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * 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
 | 
						|
 */
 | 
						|
void Ccontact::SetupColumns()
 | 
						|
{
 | 
						|
    // NOTE: Columns now are 8 character names, as that is all dBase can support.  Longer
 | 
						|
    //       names can be used for other database engines
 | 
						|
    SetColDefs ( 0,wxT("NAME"),       DB_DATA_TYPE_VARCHAR,     Name,           SQL_C_CHAR,                 sizeof(Name),           TRUE, TRUE);  // Primary index
 | 
						|
    SetColDefs ( 1,wxT("ADDRESS1"),   DB_DATA_TYPE_VARCHAR,     Addr1,          SQL_C_CHAR,                 sizeof(Addr1),          FALSE,TRUE);
 | 
						|
    SetColDefs ( 2,wxT("ADDRESS2"),   DB_DATA_TYPE_VARCHAR,     Addr2,          SQL_C_CHAR,                 sizeof(Addr2),          FALSE,TRUE);
 | 
						|
    SetColDefs ( 3,wxT("CITY"),       DB_DATA_TYPE_VARCHAR,     City,           SQL_C_CHAR,                 sizeof(City),           FALSE,TRUE);
 | 
						|
    SetColDefs ( 4,wxT("STATE"),      DB_DATA_TYPE_VARCHAR,     State,          SQL_C_CHAR,                 sizeof(State),          FALSE,TRUE);
 | 
						|
    SetColDefs ( 5,wxT("POSTCODE"),   DB_DATA_TYPE_VARCHAR,     PostalCode,     SQL_C_CHAR,                 sizeof(PostalCode),     FALSE,TRUE);
 | 
						|
    SetColDefs ( 6,wxT("COUNTRY"),    DB_DATA_TYPE_VARCHAR,     Country,        SQL_C_CHAR,                 sizeof(Country),        FALSE,TRUE);
 | 
						|
    SetColDefs ( 7,wxT("JOINDATE"),   DB_DATA_TYPE_DATE,       &JoinDate,       SQL_C_TIMESTAMP,            sizeof(JoinDate),       FALSE,TRUE);
 | 
						|
    SetColDefs ( 8,wxT("IS_DEV"),     DB_DATA_TYPE_INTEGER,    &IsDeveloper,    SQL_C_BOOLEAN(IsDeveloper), sizeof(IsDeveloper),    FALSE,TRUE);
 | 
						|
    SetColDefs ( 9,wxT("CONTRIBS"),   DB_DATA_TYPE_INTEGER,    &Contributions,  SQL_C_UTINYINT,             sizeof(Contributions),  FALSE,TRUE);
 | 
						|
    SetColDefs (10,wxT("LINE_CNT"),   DB_DATA_TYPE_INTEGER,    &LinesOfCode,    SQL_C_ULONG,                sizeof(LinesOfCode),    FALSE,TRUE);
 | 
						|
    SetColDefs (11,wxT("LANGUAGE"),   DB_DATA_TYPE_INTEGER,    &NativeLanguage, SQL_C_ENUM,                 sizeof(NativeLanguage), FALSE,TRUE);
 | 
						|
#if wxODBC_BLOB_EXPERIMENT > 0
 | 
						|
    SetColDefs (12,wxT("PICTURE"),    DB_DATA_TYPE_BLOB,        Picture,        SQL_LONGVARBINARY,          sizeof(Picture),        FALSE,TRUE);
 | 
						|
#endif
 | 
						|
}  // Ccontact::SetupColumns
 | 
						|
 | 
						|
 | 
						|
bool Ccontact::CreateIndexes(bool recreate)
 | 
						|
{
 | 
						|
    // This index could easily be accomplished with an "orderBy" clause, 
 | 
						|
    // but is done to show how to construct a non-primary index.
 | 
						|
    wxString    indexName;
 | 
						|
    wxDbIdxDef  idxDef[2];
 | 
						|
 | 
						|
    bool        Ok = TRUE;
 | 
						|
 | 
						|
    wxStrcpy(idxDef[0].ColName, "IS_DEV");
 | 
						|
    idxDef[0].Ascending = TRUE;
 | 
						|
 | 
						|
    wxStrcpy(idxDef[1].ColName, "NAME");
 | 
						|
    idxDef[1].Ascending = TRUE;
 | 
						|
 | 
						|
    indexName = GetTableName();
 | 
						|
    indexName += "_IDX1";
 | 
						|
    Ok = CreateIndex(indexName.c_str(), TRUE, 2, idxDef, recreate);
 | 
						|
 | 
						|
    return Ok;
 | 
						|
}  // Ccontact::CreateIndexes()
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Having a function to do a query on the primary key (and possibly others) is
 | 
						|
 * very efficient and tighter coding so that it is available where ever the object
 | 
						|
 * is.  Great for use with multiple tables when not using views or outer joins
 | 
						|
 */
 | 
						|
bool Ccontact::FetchByName(const wxString &name)
 | 
						|
{
 | 
						|
    whereStr.Printf(wxT("NAME = '%s'"),name.c_str());
 | 
						|
    SetWhereClause(whereStr.c_str());
 | 
						|
    SetOrderByClause(wxT(""));
 | 
						|
 | 
						|
    if (!Query())
 | 
						|
        return(FALSE);
 | 
						|
 | 
						|
    // Fetch the record
 | 
						|
    return(GetNext());
 | 
						|
 | 
						|
}  // Ccontact::FetchByName()
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *
 | 
						|
 *  ************* DIALOGS ***************
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
/* CeditorDlg constructor
 | 
						|
 *
 | 
						|
 * Creates the dialog used for creating/editing/deleting/copying a Ccontact object.
 | 
						|
 * This dialog actually is drawn in the main frame of the program
 | 
						|
 *
 | 
						|
 * An instance of Ccontact is created - "Contact" - which is used to hold the Ccontact
 | 
						|
 * object that is currently being worked with.
 | 
						|
 */
 | 
						|
 
 | 
						|
BEGIN_EVENT_TABLE(CeditorDlg, wxPanel)
 | 
						|
    EVT_BUTTON(-1,  CeditorDlg::OnButton)
 | 
						|
    EVT_CLOSE(CeditorDlg::OnCloseWindow)
 | 
						|
END_EVENT_TABLE()
 | 
						|
 
 | 
						|
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;
 | 
						|
 | 
						|
    initialized = FALSE;
 | 
						|
 | 
						|
    SetMode(mView);
 | 
						|
 | 
						|
    Show(FALSE);
 | 
						|
}  // CeditorDlg constructor
 | 
						|
 | 
						|
 | 
						|
void CeditorDlg::OnCloseWindow(wxCloseEvent& event)
 | 
						|
{
 | 
						|
    // Clean up time
 | 
						|
    if ((mode != mCreate) && (mode != mEdit))
 | 
						|
    {
 | 
						|
        this->Destroy();
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        wxMessageBox(wxT("Must finish processing the current record being created/modified before exiting"),wxT("Notice..."),wxOK | wxICON_INFORMATION);
 | 
						|
        event.Veto();
 | 
						|
    }
 | 
						|
}  // CeditorDlg::OnCloseWindow()
 | 
						|
 | 
						|
 | 
						|
void CeditorDlg::OnButton(wxCommandEvent &event)
 | 
						|
{
 | 
						|
    wxWindow *win = (wxWindow*) event.GetEventObject();
 | 
						|
    OnCommand( *win, event );
 | 
						|
}  // CeditorDlg::OnButton()
 | 
						|
 | 
						|
 | 
						|
void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
 | 
						|
{
 | 
						|
    wxString widgetName;
 | 
						|
    
 | 
						|
    widgetName = win.GetName();
 | 
						|
 | 
						|
    if (!widgetPtrsSet)
 | 
						|
        return;
 | 
						|
 | 
						|
    if (widgetName == pCreateBtn->GetName())
 | 
						|
    {
 | 
						|
        wxGetApp().Contact->Initialize();
 | 
						|
        PutData();
 | 
						|
        SetMode( mCreate );
 | 
						|
        pNameTxt->SetValue(wxT(""));
 | 
						|
        pNameTxt->SetFocus();
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (widgetName == pEditBtn->GetName())
 | 
						|
    {
 | 
						|
        saveName = wxGetApp().Contact->Name;
 | 
						|
        SetMode( mEdit );
 | 
						|
        pNameTxt->SetFocus();
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (widgetName == pCopyBtn->GetName())
 | 
						|
    {
 | 
						|
        SetMode(mCreate);
 | 
						|
        pNameTxt->SetValue(wxT(""));
 | 
						|
        pNameTxt->SetFocus();
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (widgetName == pDeleteBtn->GetName())
 | 
						|
    {
 | 
						|
        bool Ok = (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
 | 
						|
 | 
						|
        if (!Ok)
 | 
						|
            return;
 | 
						|
 | 
						|
        if (Ok && wxGetApp().Contact->Delete())
 | 
						|
        {
 | 
						|
            // NOTE: Deletions are not finalized until a CommitTrans() is performed.  
 | 
						|
            //       If the commit were not performed, the program will continue to 
 | 
						|
            //       show the table contents as if they were deleted until this instance
 | 
						|
            //       of Ccontact is deleted.  If the Commit wasn't performed, the 
 | 
						|
            //       database will automatically Rollback the changes when the database
 | 
						|
            //       connection is terminated
 | 
						|
            wxGetApp().Contact->GetDb()->CommitTrans();
 | 
						|
 | 
						|
            // Try to get the row that followed the just deleted row in the orderBy sequence
 | 
						|
            if (!GetNextRec())
 | 
						|
            {
 | 
						|
                // There was now row (in sequence) after the just deleted row, so get the
 | 
						|
                // row which preceded the just deleted row
 | 
						|
                if (!GetPrevRec())
 | 
						|
                {
 | 
						|
                    // There are now no rows remaining, so clear the dialog widgets
 | 
						|
                    wxGetApp().Contact->Initialize();
 | 
						|
                    PutData();
 | 
						|
                }
 | 
						|
            }
 | 
						|
            SetMode(mode);    // force reset of button enable/disable
 | 
						|
        }
 | 
						|
        else
 | 
						|
            // Delete failed
 | 
						|
            wxGetApp().Contact->GetDb()->RollbackTrans();
 | 
						|
 | 
						|
        SetMode(mView);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (widgetName == pSaveBtn->GetName())
 | 
						|
    {
 | 
						|
        Save();
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (widgetName == pCancelBtn->GetName())
 | 
						|
    {
 | 
						|
        bool Ok = (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
 | 
						|
 | 
						|
        if (!Ok)
 | 
						|
            return;
 | 
						|
 | 
						|
        if (saveName.IsEmpty())
 | 
						|
        {
 | 
						|
            wxGetApp().Contact->Initialize();
 | 
						|
            PutData();
 | 
						|
            SetMode(mView);
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            // Requery previous record
 | 
						|
            if (wxGetApp().Contact->FetchByName(saveName))
 | 
						|
            {
 | 
						|
                PutData();
 | 
						|
                SetMode(mView);
 | 
						|
                return;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // Previous record not available, retrieve first record in table
 | 
						|
        if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
 | 
						|
            wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
 | 
						|
        {
 | 
						|
            wxGetApp().Contact->whereStr  = wxT("NAME = (SELECT MIN(NAME) FROM ");
 | 
						|
            wxGetApp().Contact->whereStr += wxGetApp().Contact->GetTableName();
 | 
						|
            wxGetApp().Contact->whereStr += wxT(")");
 | 
						|
            wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr.c_str());
 | 
						|
        }
 | 
						|
        else
 | 
						|
            wxGetApp().Contact->SetWhereClause(wxT(""));
 | 
						|
 | 
						|
        if (!wxGetApp().Contact->Query())
 | 
						|
        {
 | 
						|
            wxString tStr;
 | 
						|
            tStr = wxT("ODBC error during Query()\n\n");
 | 
						|
            wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                         wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
            
 | 
						|
            SetMode(mView);
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        if (wxGetApp().Contact->GetNext())  // Successfully read first record
 | 
						|
        {
 | 
						|
            PutData();
 | 
						|
            SetMode(mView);
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        // No contacts are available, clear dialog
 | 
						|
        wxGetApp().Contact->Initialize();
 | 
						|
        PutData();
 | 
						|
        SetMode(mView);
 | 
						|
        return;
 | 
						|
    }  // Cancel Button
 | 
						|
 | 
						|
    if (widgetName == pPrevBtn->GetName())
 | 
						|
    {
 | 
						|
        if (!GetPrevRec())
 | 
						|
            wxBell();
 | 
						|
        return;
 | 
						|
    }  // Prev Button
 | 
						|
 | 
						|
    if (widgetName == pNextBtn->GetName())
 | 
						|
    {
 | 
						|
        if (!GetNextRec())
 | 
						|
            wxBell();
 | 
						|
        return;
 | 
						|
    }  // Next Button
 | 
						|
 | 
						|
    if (widgetName == pQueryBtn->GetName())
 | 
						|
    {
 | 
						|
        // Display the query dialog box
 | 
						|
        wxChar qryWhere[DB_MAX_WHERE_CLAUSE_LEN+1];
 | 
						|
        wxStrcpy(qryWhere, (const wxChar*) wxGetApp().Contact->qryWhereStr);
 | 
						|
        wxChar *tblName[] = {(wxChar *)CONTACT_TABLE_NAME, 0};
 | 
						|
        new CqueryDlg(GetParent(), wxGetApp().Contact->GetDb(), tblName, qryWhere);
 | 
						|
 | 
						|
        // Query the first record in the new record set and
 | 
						|
        // display it, if the query string has changed.
 | 
						|
        if (wxStrcmp(qryWhere, (const wxChar*) wxGetApp().Contact->qryWhereStr))
 | 
						|
        {
 | 
						|
            wxGetApp().Contact->whereStr.Empty();
 | 
						|
            wxGetApp().Contact->SetOrderByClause("NAME");
 | 
						|
 | 
						|
            if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
 | 
						|
                wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
 | 
						|
            {
 | 
						|
                wxGetApp().Contact->whereStr  = wxT("NAME = (SELECT MIN(NAME) FROM ");
 | 
						|
                wxGetApp().Contact->whereStr += CONTACT_TABLE_NAME;
 | 
						|
            }
 | 
						|
            
 | 
						|
            // Append the query where string (if there is one)
 | 
						|
            wxGetApp().Contact->qryWhereStr  = qryWhere;
 | 
						|
            if (wxStrlen(qryWhere))
 | 
						|
            {
 | 
						|
                wxGetApp().Contact->whereStr += wxT(" WHERE ");
 | 
						|
                wxGetApp().Contact->whereStr += wxGetApp().Contact->qryWhereStr;
 | 
						|
            }
 | 
						|
            // Close the expression with a right paren
 | 
						|
            wxGetApp().Contact->whereStr += wxT(")");
 | 
						|
            // Requery the table
 | 
						|
            wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr.c_str());
 | 
						|
            if (!wxGetApp().Contact->Query())
 | 
						|
            {
 | 
						|
                wxString tStr;
 | 
						|
                tStr = wxT("ODBC error during Query()\n\n");
 | 
						|
                wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                             wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
 | 
						|
                return;
 | 
						|
            }
 | 
						|
            // Display the first record from the query set
 | 
						|
            if (!wxGetApp().Contact->GetNext())
 | 
						|
                wxGetApp().Contact->Initialize();
 | 
						|
            PutData();
 | 
						|
        }
 | 
						|
 | 
						|
        // Enable/Disable the reset button
 | 
						|
        pResetBtn->Enable(!wxGetApp().Contact->qryWhereStr.IsEmpty());
 | 
						|
 | 
						|
        return;
 | 
						|
    }  // Query button
 | 
						|
 | 
						|
 | 
						|
    if (widgetName == pResetBtn->GetName())
 | 
						|
    {
 | 
						|
        // Clear the additional where criteria established by the query feature
 | 
						|
        wxGetApp().Contact->qryWhereStr = wxT("");
 | 
						|
        wxGetApp().Contact->SetOrderByClause(wxT("NAME"));
 | 
						|
 | 
						|
        if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
 | 
						|
            wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
 | 
						|
        {
 | 
						|
            wxGetApp().Contact->whereStr  = wxT("NAME = (SELECT MIN(NAME) FROM ");
 | 
						|
            wxGetApp().Contact->whereStr += CONTACT_TABLE_NAME;
 | 
						|
            wxGetApp().Contact->whereStr += wxT(")");
 | 
						|
        }
 | 
						|
 | 
						|
        wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr.c_str());
 | 
						|
        if (!wxGetApp().Contact->Query())
 | 
						|
        {
 | 
						|
            wxString tStr;
 | 
						|
            tStr = wxT("ODBC error during Query()\n\n");
 | 
						|
            wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                         wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        if (!wxGetApp().Contact->GetNext())
 | 
						|
            wxGetApp().Contact->Initialize();
 | 
						|
        PutData();
 | 
						|
        pResetBtn->Enable(FALSE);
 | 
						|
 | 
						|
        return;
 | 
						|
    }  // Reset button
 | 
						|
 | 
						|
 | 
						|
    if (widgetName == pNameListBtn->GetName())
 | 
						|
    {
 | 
						|
        new ClookUpDlg(/* wxWindow    *parent        */ this,
 | 
						|
                       /* wxChar      *windowTitle   */ wxT("Select contact name"),
 | 
						|
                       /* wxChar      *tableName     */ (wxChar *) CONTACT_TABLE_NAME,
 | 
						|
                       /* wxChar      *dispCol1      */ wxT("NAME"),
 | 
						|
                       /* wxChar      *dispCol2      */ wxT("JOINDATE"),
 | 
						|
                       /* wxChar      *where         */ wxT(""),
 | 
						|
                       /* wxChar      *orderBy       */ wxT("NAME"),
 | 
						|
                       /* wxDb        *pDb           */ wxGetApp().READONLY_DB,
 | 
						|
                       /* const wxString &defDir     */ wxGetApp().DbConnectInf->GetDefaultDir(),
 | 
						|
                       /* bool        distinctValues */ TRUE);
 | 
						|
 | 
						|
        if (ListDB_Selection && wxStrlen(ListDB_Selection))
 | 
						|
        {
 | 
						|
            wxString w = wxT("NAME = '");
 | 
						|
            w += ListDB_Selection;
 | 
						|
            w += wxT("'");
 | 
						|
            GetRec(w);
 | 
						|
        }
 | 
						|
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (widgetName == pDataTypesBtn->GetName())
 | 
						|
    {
 | 
						|
        CheckSupportForAllDataTypes(wxGetApp().READONLY_DB);
 | 
						|
        wxMessageBox("Support datatypes was dumped to stdout.");
 | 
						|
        return;
 | 
						|
    }  // Data types Button
 | 
						|
 | 
						|
    if (widgetName == pDbDiagsBtn->GetName())
 | 
						|
    {
 | 
						|
        DisplayDbDiagnostics(wxGetApp().READONLY_DB);
 | 
						|
        wxMessageBox("Diagnostics info was dumped to stdout.");
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (widgetName == pCatalogBtn->GetName())
 | 
						|
    {
 | 
						|
        if (wxGetApp().Contact->GetDb()->Catalog("","catalog.txt"))
 | 
						|
            wxMessageBox("The file 'catalog.txt' was created.");
 | 
						|
        else
 | 
						|
            wxMessageBox("Creation of the file 'catalog.txt' was failed.");
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
}  // 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)
 | 
						|
    wxGetApp().Contact = new Ccontact();
 | 
						|
 | 
						|
    if (!wxGetApp().Contact)
 | 
						|
    {
 | 
						|
        wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"),wxT("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 (!wxGetApp().Contact->GetDb()->TableExists((wxChar *)CONTACT_TABLE_NAME, 
 | 
						|
                                          wxGetApp().DbConnectInf->GetUserID(), 
 | 
						|
                                          wxGetApp().DbConnectInf->GetDefaultDir()))
 | 
						|
    {
 | 
						|
        wxString tStr;
 | 
						|
        tStr.Printf(wxT("Unable to open the table '%s'.  The table may\nneed to be created.\n\nDo you wish to try to create/clear the table?\n\n"),CONTACT_TABLE_NAME);
 | 
						|
        bool createTable = (wxMessageBox(tStr.c_str(),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
 | 
						|
 | 
						|
        if (!createTable)
 | 
						|
        {
 | 
						|
//            Close();
 | 
						|
            return FALSE;
 | 
						|
        }
 | 
						|
        else
 | 
						|
            wxGetApp().CreateDataTable(FALSE);
 | 
						|
    }
 | 
						|
 | 
						|
    // Tables must be "opened" before anything other than creating/deleting table can be done
 | 
						|
    if (!wxGetApp().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 1
 | 
						|
// 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 (!wxGetApp().Contact->GetDb()->TablePrivileges(CONTACT_TABLE_NAME, wxT("SELECT"),
 | 
						|
                                                wxGetApp().Contact->GetDb()->GetUsername(),
 | 
						|
                                                wxGetApp().Contact->GetDb()->GetUsername(),
 | 
						|
                                                wxGetApp().DbConnectInf->GetDefaultDir()))
 | 
						|
        {
 | 
						|
            wxString tStr;
 | 
						|
            tStr.Printf(wxT("Unable to open the table '%s' (likely due to\ninsufficient privileges of the logged in user).\n\n"),CONTACT_TABLE_NAME);
 | 
						|
 | 
						|
            wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                         wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        }
 | 
						|
        else 
 | 
						|
#endif
 | 
						|
        if (!wxGetApp().Contact->GetDb()->TableExists(CONTACT_TABLE_NAME,
 | 
						|
                                           wxGetApp().Contact->GetDb()->GetUsername(),
 | 
						|
                                           wxGetApp().DbConnectInf->GetDefaultDir()))
 | 
						|
        {
 | 
						|
            wxString tStr;
 | 
						|
            tStr.Printf(wxT("Unable to open the table '%s' as the table\ndoes not appear to exist in the tablespace available\nto the currently logged in user.\n\n"),CONTACT_TABLE_NAME);
 | 
						|
            wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                         wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        }
 | 
						|
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    // Build the dialog
 | 
						|
 | 
						|
    (void)new wxStaticBox(this, EDITOR_DIALOG_FN_GROUP, wxT(""),  wxPoint(15, 1), wxSize(497,  69), 0, wxT("FunctionGrp"));
 | 
						|
    (void)new wxStaticBox(this, EDITOR_DIALOG_SEARCH_GROUP, wxT(""), wxPoint(417, 1), wxSize(95, 242), 0, wxT("SearchGrp"));
 | 
						|
 | 
						|
    pCreateBtn      = new wxButton(this, EDITOR_DIALOG_CREATE,           wxT("&Create"),     wxPoint( 25,  21), wxSize( 70,  35), 0, wxDefaultValidator, wxT("CreateBtn"));
 | 
						|
    pEditBtn        = new wxButton(this, EDITOR_DIALOG_EDIT,             wxT("&Edit"),       wxPoint(102,  21), wxSize( 70,  35), 0, wxDefaultValidator, wxT("EditBtn"));
 | 
						|
    pDeleteBtn      = new wxButton(this, EDITOR_DIALOG_DELETE,           wxT("&Delete"),     wxPoint(179,  21), wxSize( 70,  35), 0, wxDefaultValidator, wxT("DeleteBtn"));
 | 
						|
    pCopyBtn        = new wxButton(this, EDITOR_DIALOG_COPY,             wxT("Cop&y"),       wxPoint(256,  21), wxSize( 70,  35), 0, wxDefaultValidator, wxT("CopyBtn"));
 | 
						|
    pSaveBtn        = new wxButton(this, EDITOR_DIALOG_SAVE,             wxT("&Save"),       wxPoint(333,  21), wxSize( 70,  35), 0, wxDefaultValidator, wxT("SaveBtn"));
 | 
						|
    pCancelBtn      = new wxButton(this, EDITOR_DIALOG_CANCEL,           wxT("C&ancel"),     wxPoint(430,  21), wxSize( 70,  35), 0, wxDefaultValidator, wxT("CancelBtn"));
 | 
						|
    pPrevBtn        = new wxButton(this, EDITOR_DIALOG_PREV,             wxT("<< &Prev"),    wxPoint(430,  81), wxSize( 70,  35), 0, wxDefaultValidator, wxT("PrevBtn"));
 | 
						|
    pNextBtn        = new wxButton(this, EDITOR_DIALOG_NEXT,             wxT("&Next >>"),    wxPoint(430, 121), wxSize( 70,  35), 0, wxDefaultValidator, wxT("NextBtn"));
 | 
						|
    pQueryBtn       = new wxButton(this, EDITOR_DIALOG_QUERY,            wxT("&Query"),      wxPoint(430, 161), wxSize( 70,  35), 0, wxDefaultValidator, wxT("QueryBtn"));
 | 
						|
    pResetBtn       = new wxButton(this, EDITOR_DIALOG_RESET,            wxT("&Reset"),      wxPoint(430, 200), wxSize( 70,  35), 0, wxDefaultValidator, wxT("ResetBtn"));
 | 
						|
    pNameMsg        = new wxStaticText(this, EDITOR_DIALOG_NAME_MSG,     wxT("Name:"),       wxPoint( 17,  80), wxSize( -1,  -1), 0, wxT("NameMsg"));
 | 
						|
    pNameTxt        = new wxTextCtrl(this, EDITOR_DIALOG_NAME_TEXT,      wxT(""),            wxPoint( 17,  97), wxSize(308,  25), 0, wxDefaultValidator, wxT("NameTxt"));
 | 
						|
    pNameListBtn    = new wxButton(this, EDITOR_DIALOG_LOOKUP,           wxT("&Lookup"),     wxPoint(333,  97), wxSize( 70,  24), 0, wxDefaultValidator, wxT("LookupBtn"));
 | 
						|
    pAddress1Msg    = new wxStaticText(this, EDITOR_DIALOG_ADDRESS1_MSG, wxT("Address:"),    wxPoint( 17, 130), wxSize( -1,  -1), 0, wxT("Address1Msg"));
 | 
						|
    pAddress1Txt    = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT,  wxT(""),            wxPoint( 17, 147), wxSize(308,  25), 0, wxDefaultValidator, wxT("Address1Txt"));
 | 
						|
    pAddress2Msg    = new wxStaticText(this, EDITOR_DIALOG_ADDRESS2_MSG, wxT("Address:"),    wxPoint( 17, 180), wxSize( -1,  -1), 0, wxT("Address2Msg"));
 | 
						|
    pAddress2Txt    = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT,  wxT(""),            wxPoint( 17, 197), wxSize(308,  25), 0, wxDefaultValidator, wxT("Address2Txt"));
 | 
						|
    pCityMsg        = new wxStaticText(this, EDITOR_DIALOG_CITY_MSG,     wxT("City:"),       wxPoint( 17, 230), wxSize( -1,  -1), 0, wxT("CityMsg"));
 | 
						|
    pCityTxt        = new wxTextCtrl(this, EDITOR_DIALOG_CITY_TEXT,      wxT(""),            wxPoint( 17, 247), wxSize(225,  25), 0, wxDefaultValidator, wxT("CityTxt"));
 | 
						|
    pStateMsg       = new wxStaticText(this, EDITOR_DIALOG_STATE_MSG,    wxT("State:"),      wxPoint(250, 230), wxSize( -1,  -1), 0, wxT("StateMsg"));
 | 
						|
    pStateTxt       = new wxTextCtrl(this, EDITOR_DIALOG_STATE_TEXT,     wxT(""),            wxPoint(250, 247), wxSize(153,  25), 0, wxDefaultValidator, wxT("StateTxt"));
 | 
						|
    pCountryMsg     = new wxStaticText(this, EDITOR_DIALOG_COUNTRY_MSG,  wxT("Country:"),    wxPoint( 17, 280), wxSize( -1,  -1), 0, wxT("CountryMsg"));
 | 
						|
    pCountryTxt     = new wxTextCtrl(this, EDITOR_DIALOG_COUNTRY_TEXT,   wxT(""),            wxPoint( 17, 297), wxSize(225,  25), 0, wxDefaultValidator, wxT("CountryTxt"));
 | 
						|
    pPostalCodeMsg  = new wxStaticText(this, EDITOR_DIALOG_POSTAL_MSG,   wxT("Postal Code:"),wxPoint(250, 280), wxSize( -1,  -1), 0, wxT("PostalCodeMsg"));
 | 
						|
    pPostalCodeTxt  = new wxTextCtrl(this, EDITOR_DIALOG_POSTAL_TEXT,    wxT(""),            wxPoint(250, 297), wxSize(153,  25), 0, wxDefaultValidator, wxT("PostalCodeTxt"));
 | 
						|
 | 
						|
    wxString choice_strings[5];
 | 
						|
    choice_strings[0] = wxT("English");
 | 
						|
    choice_strings[1] = wxT("French");
 | 
						|
    choice_strings[2] = wxT("German");
 | 
						|
    choice_strings[3] = wxT("Spanish");
 | 
						|
    choice_strings[4] = wxT("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,   wxT("Native language:"), wxPoint( 17, 330), wxSize( -1,  -1), 0, wxT("NativeLangMsg"));
 | 
						|
 | 
						|
    wxString radio_strings[2];
 | 
						|
    radio_strings[0]  = wxT("No");
 | 
						|
    radio_strings[1]  = wxT("Yes");
 | 
						|
    pDeveloperRadio   = new wxRadioBox(this,EDITOR_DIALOG_DEVELOPER,     wxT("Developer:"),       wxPoint(303, 330), wxSize( -1,  -1), 2, radio_strings, 2, wxHORIZONTAL);
 | 
						|
    pJoinDateMsg      = new wxStaticText(this, EDITOR_DIALOG_JOIN_MSG,   wxT("Date joined:"),     wxPoint( 17, 380), wxSize( -1,  -1), 0, wxT("JoinDateMsg"));
 | 
						|
    pJoinDateTxt      = new wxTextCtrl(this, EDITOR_DIALOG_JOIN_TEXT,    wxT(""),                 wxPoint( 17, 397), wxSize(150,  25), 0, wxDefaultValidator, wxT("JoinDateTxt"));
 | 
						|
    pContribMsg       = new wxStaticText(this, EDITOR_DIALOG_CONTRIB_MSG,wxT("Contributions:"),   wxPoint(175, 380), wxSize( -1,  -1), 0, wxT("ContribMsg"));
 | 
						|
    pContribTxt       = new wxTextCtrl(this, EDITOR_DIALOG_CONTRIB_TEXT, wxT(""),                 wxPoint(175, 397), wxSize(120,  25), 0, wxDefaultValidator, wxT("ContribTxt"));
 | 
						|
    pLinesMsg         = new wxStaticText(this, EDITOR_DIALOG_LINES_MSG,  wxT("Lines of code:"),   wxPoint(303, 380), wxSize( -1,  -1), 0, wxT("LinesMsg"));
 | 
						|
    pLinesTxt         = new wxTextCtrl(this, EDITOR_DIALOG_LINES_TEXT,   wxT(""),                 wxPoint(303, 397), wxSize(100,  25), 0, wxDefaultValidator, wxT("LinesTxt"));
 | 
						|
 | 
						|
    pCatalogBtn       = new wxButton(this, EDITOR_DIALOG_CATALOG,        wxT("Catalo&g"),         wxPoint(430, 287), wxSize( 70,  35), 0, wxDefaultValidator, wxT("CatalogBtn"));
 | 
						|
    pDataTypesBtn     = new wxButton(this, EDITOR_DIALOG_DATATYPES,      wxT("Data&types"),       wxPoint(430, 337), wxSize( 70,  35), 0, wxDefaultValidator, wxT("DataTypesBtn"));
 | 
						|
    pDbDiagsBtn       = new wxButton(this, EDITOR_DIALOG_DB_DIAGS,       wxT("DB Dia&gs"),        wxPoint(430, 387), wxSize( 70,  35), 0, wxDefaultValidator, wxT("DbDiagsBtn"));
 | 
						|
 | 
						|
    // 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
 | 
						|
    
 | 
						|
    wxGetApp().Contact->SetOrderByClause(wxT("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 (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
 | 
						|
        wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
 | 
						|
    {
 | 
						|
        wxGetApp().Contact->whereStr.Printf(wxT("NAME = (SELECT MIN(NAME) FROM %s)"),
 | 
						|
                                            wxGetApp().Contact->GetTableName().c_str());
 | 
						|
        // NOTE: (const wxChar*) returns a pointer which may not be valid later, so this is short term use only
 | 
						|
        wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr);
 | 
						|
    }
 | 
						|
    else
 | 
						|
       wxGetApp().Contact->SetWhereClause(wxT(""));
 | 
						|
 | 
						|
    // 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 (!wxGetApp().Contact->Query())
 | 
						|
    {
 | 
						|
        wxString tStr;
 | 
						|
        tStr = wxT("ODBC error during Query()\n\n");
 | 
						|
        wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                     wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    // Since Query succeeded, now get the row that was returned
 | 
						|
    if (!wxGetApp().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
 | 
						|
        wxGetApp().Contact->Initialize();
 | 
						|
/*
 | 
						|
    wxGetApp().Contact->GetDb()->RollbackTrans();
 | 
						|
*/
 | 
						|
    SetMode(mView);
 | 
						|
    PutData();
 | 
						|
 | 
						|
    Show(TRUE);
 | 
						|
 | 
						|
    initialized = TRUE;
 | 
						|
    return TRUE;
 | 
						|
}  // CeditorDlg::Initialize()
 | 
						|
 | 
						|
 | 
						|
void CeditorDlg::FieldsEditable()
 | 
						|
{
 | 
						|
    if (!widgetPtrsSet)
 | 
						|
        return;
 | 
						|
 | 
						|
    pNameTxt->Enable((mode == mCreate) || (mode == mEdit));
 | 
						|
    pAddress1Txt->Enable((mode == mCreate) || (mode == mEdit));
 | 
						|
    pAddress2Txt->Enable((mode == mCreate) || (mode == mEdit));
 | 
						|
    pCityTxt->Enable((mode == mCreate) || (mode == mEdit));
 | 
						|
    pStateTxt->Enable((mode == mCreate) || (mode == mEdit));
 | 
						|
    pPostalCodeTxt->Enable((mode == mCreate) || (mode == mEdit));
 | 
						|
    pCountryTxt->Enable((mode == mCreate) || (mode == mEdit));
 | 
						|
 | 
						|
    pJoinDateTxt->Enable((mode == mCreate) || (mode == mEdit));
 | 
						|
    pContribTxt->Enable((mode == mCreate) || (mode == mEdit));
 | 
						|
    pLinesTxt->Enable((mode == mCreate) || (mode == mEdit));
 | 
						|
    pNativeLangChoice->Enable((mode == mCreate) || (mode == mEdit));
 | 
						|
    pDeveloperRadio->Enable((mode == mCreate) || (mode == mEdit));
 | 
						|
 | 
						|
}  // CeditorDlg::FieldsEditable()
 | 
						|
 | 
						|
 | 
						|
void CeditorDlg::SetMode(enum DialogModes m)
 | 
						|
{
 | 
						|
    bool edit = FALSE;
 | 
						|
 | 
						|
    mode = m;
 | 
						|
    switch (mode)
 | 
						|
    {
 | 
						|
        case mCreate:
 | 
						|
        case mEdit:
 | 
						|
            edit = TRUE;
 | 
						|
            break;
 | 
						|
        case mView:
 | 
						|
        case mSearch:
 | 
						|
            edit = FALSE;
 | 
						|
            break;
 | 
						|
        default:
 | 
						|
                break;
 | 
						|
    };
 | 
						|
 | 
						|
    if (widgetPtrsSet)
 | 
						|
    {
 | 
						|
        pCreateBtn->Enable( !edit );
 | 
						|
        pEditBtn->Enable( !edit && (wxStrcmp(wxGetApp().Contact->Name,wxT(""))!=0) );
 | 
						|
        pDeleteBtn->Enable( !edit && (wxStrcmp(wxGetApp().Contact->Name,wxT(""))!=0) );
 | 
						|
        pCopyBtn->Enable( !edit && (wxStrcmp(wxGetApp().Contact->Name,wxT(""))!=0) );
 | 
						|
        pSaveBtn->Enable( edit );
 | 
						|
        pCancelBtn->Enable( edit );
 | 
						|
        pPrevBtn->Enable( !edit );
 | 
						|
        pNextBtn->Enable( !edit );
 | 
						|
        pQueryBtn->Enable( !edit );
 | 
						|
        pResetBtn->Enable( !edit && !wxGetApp().Contact->qryWhereStr.IsEmpty() );
 | 
						|
        pNameListBtn->Enable( !edit );
 | 
						|
    }
 | 
						|
 | 
						|
    FieldsEditable();
 | 
						|
}  // CeditorDlg::SetMode()
 | 
						|
 | 
						|
 | 
						|
bool CeditorDlg::PutData()
 | 
						|
{
 | 
						|
    wxString tStr;
 | 
						|
 | 
						|
    pNameTxt->SetValue(wxGetApp().Contact->Name);
 | 
						|
    pAddress1Txt->SetValue(wxGetApp().Contact->Addr1);
 | 
						|
    pAddress2Txt->SetValue(wxGetApp().Contact->Addr2);
 | 
						|
    pCityTxt->SetValue(wxGetApp().Contact->City);
 | 
						|
    pStateTxt->SetValue(wxGetApp().Contact->State);
 | 
						|
    pCountryTxt->SetValue(wxGetApp().Contact->Country);
 | 
						|
    pPostalCodeTxt->SetValue(wxGetApp().Contact->PostalCode);
 | 
						|
 | 
						|
    tStr.Printf(wxT("%d/%d/%d"),wxGetApp().Contact->JoinDate.month,wxGetApp().Contact->JoinDate.day,wxGetApp().Contact->JoinDate.year);
 | 
						|
    pJoinDateTxt->SetValue(tStr);
 | 
						|
 | 
						|
    tStr.Printf(wxT("%d"),wxGetApp().Contact->Contributions);
 | 
						|
    pContribTxt->SetValue(tStr);
 | 
						|
 | 
						|
    tStr.Printf(wxT("%lu"),wxGetApp().Contact->LinesOfCode);
 | 
						|
    pLinesTxt->SetValue(tStr);
 | 
						|
 | 
						|
    pNativeLangChoice->SetSelection(wxGetApp().Contact->NativeLanguage);
 | 
						|
 | 
						|
    pDeveloperRadio->SetSelection(wxGetApp().Contact->IsDeveloper);
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}  // Ceditor::PutData()
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Reads the data out of all the widgets on the dialog.  Some data evaluation is done
 | 
						|
 * to ensure that there is a name entered and that the date field is valid.
 | 
						|
 *
 | 
						|
 * A return value of TRUE means that valid data was retrieved from the dialog, otherwise
 | 
						|
 * invalid data was found (and a message was displayed telling the user what to fix), and
 | 
						|
 * the data was not placed into the appropraite fields of Ccontact
 | 
						|
 */
 | 
						|
bool CeditorDlg::GetData()
 | 
						|
{
 | 
						|
    // Validate that the data currently entered into the widgets is valid data
 | 
						|
 | 
						|
    wxString tStr;
 | 
						|
    tStr = pNameTxt->GetValue();
 | 
						|
    if (!wxStrcmp((const wxChar*) tStr,wxT("")))
 | 
						|
    {
 | 
						|
        wxMessageBox(wxT("A name is required for entry into the contact table"),wxT("Notice..."),wxOK | wxICON_INFORMATION);
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    bool   invalid = FALSE;
 | 
						|
    int    mm = 1,dd = 1,yyyy = 2001;
 | 
						|
    int    first, second;
 | 
						|
 | 
						|
    tStr = pJoinDateTxt->GetValue();
 | 
						|
    if (tStr.Freq(wxT('/')) != 2)
 | 
						|
        invalid = TRUE;
 | 
						|
 | 
						|
    // Find the month, day, and year tokens
 | 
						|
    if (!invalid)
 | 
						|
    {
 | 
						|
        first   = tStr.First(wxT('/'));
 | 
						|
        second  = tStr.Last(wxT('/'));
 | 
						|
 | 
						|
        mm      = atoi(tStr.SubString(0,first));
 | 
						|
        dd      = atoi(tStr.SubString(first+1,second));
 | 
						|
        yyyy    = atoi(tStr.SubString(second+1,tStr.Length()-1));
 | 
						|
 | 
						|
        invalid = !(mm && dd && yyyy);
 | 
						|
    }
 | 
						|
 | 
						|
    // Force Year 2000 compliance
 | 
						|
    if (!invalid && (yyyy < 1000))
 | 
						|
        invalid = TRUE;
 | 
						|
 | 
						|
    // Check the token ranges for validity
 | 
						|
    if (!invalid)
 | 
						|
    {
 | 
						|
        if (yyyy > 9999)
 | 
						|
            invalid = TRUE;
 | 
						|
        else if ((mm < 1) || (mm > 12))
 | 
						|
            invalid = TRUE;
 | 
						|
        else
 | 
						|
        {
 | 
						|
            if (dd < 1)
 | 
						|
                invalid = TRUE;
 | 
						|
            else
 | 
						|
            {
 | 
						|
                int days[12] = {31,28,31,30,31,30,
 | 
						|
                                31,31,30,31,30,31};
 | 
						|
                if (dd > days[mm-1])
 | 
						|
                {
 | 
						|
                    invalid = TRUE;
 | 
						|
                    if ((dd == 29) && (mm == 2))
 | 
						|
                    {
 | 
						|
                        if (((yyyy % 4) == 0) && (((yyyy % 100) != 0) || ((yyyy % 400) == 0)))
 | 
						|
                            invalid = FALSE;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (!invalid)
 | 
						|
    {
 | 
						|
        wxGetApp().Contact->JoinDate.month = mm;
 | 
						|
        wxGetApp().Contact->JoinDate.day   = dd;
 | 
						|
        wxGetApp().Contact->JoinDate.year  = yyyy;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        wxMessageBox(wxT("Improper date format.  Please check the date\nspecified and try again.\n\nNOTE: Dates are in american format (MM/DD/YYYY)"),wxT("Notice..."),wxOK | wxICON_INFORMATION);
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    tStr = pNameTxt->GetValue();
 | 
						|
    wxStrcpy(wxGetApp().Contact->Name,(const wxChar*) tStr);
 | 
						|
    wxStrcpy(wxGetApp().Contact->Addr1,pAddress1Txt->GetValue());
 | 
						|
    wxStrcpy(wxGetApp().Contact->Addr2,pAddress2Txt->GetValue());
 | 
						|
    wxStrcpy(wxGetApp().Contact->City,pCityTxt->GetValue());
 | 
						|
    wxStrcpy(wxGetApp().Contact->State,pStateTxt->GetValue());
 | 
						|
    wxStrcpy(wxGetApp().Contact->Country,pCountryTxt->GetValue());
 | 
						|
    wxStrcpy(wxGetApp().Contact->PostalCode,pPostalCodeTxt->GetValue());
 | 
						|
 | 
						|
    wxGetApp().Contact->Contributions = atoi(pContribTxt->GetValue());
 | 
						|
    wxGetApp().Contact->LinesOfCode = atol(pLinesTxt->GetValue());
 | 
						|
 | 
						|
    wxGetApp().Contact->NativeLanguage = (enum Language) pNativeLangChoice->GetSelection();
 | 
						|
    wxGetApp().Contact->IsDeveloper = pDeveloperRadio->GetSelection() > 0;
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}  // CeditorDlg::GetData()
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Retrieve data from the dialog, verify the validity of the data, and if it is valid,
 | 
						|
 * try to insert/update the data to the table based on the current 'mode' the dialog
 | 
						|
 * is set to.
 | 
						|
 *
 | 
						|
 * A return value of TRUE means the insert/update was completed successfully, a return
 | 
						|
 * value of FALSE means that Save() failed.  If returning FALSE, then this function
 | 
						|
 * has displayed a detailed error message for the user.
 | 
						|
 */
 | 
						|
bool CeditorDlg::Save()
 | 
						|
{
 | 
						|
    bool failed = FALSE;
 | 
						|
 | 
						|
    // Read the data in the widgets of the dialog to get the user's data
 | 
						|
    if (!GetData())
 | 
						|
        failed = TRUE;
 | 
						|
 | 
						|
    // Perform any other required validations necessary before saving
 | 
						|
    if (!failed)
 | 
						|
    {
 | 
						|
        wxBeginBusyCursor();
 | 
						|
 | 
						|
        if (mode == mCreate)
 | 
						|
        {
 | 
						|
            RETCODE result = wxGetApp().Contact->Insert();
 | 
						|
 | 
						|
            failed = (result != DB_SUCCESS);
 | 
						|
            if (failed)
 | 
						|
            {
 | 
						|
                // Some errors may be expected, like a duplicate key, so handle those instances with
 | 
						|
                // specific error messages.
 | 
						|
                if (result == DB_ERR_INTEGRITY_CONSTRAINT_VIOL)
 | 
						|
                {
 | 
						|
                    wxString tStr;
 | 
						|
                    tStr = wxT("A duplicate key value already exists in the table.\nUnable to save record\n\n");
 | 
						|
                    wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                                 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    // Some other unexpected error occurred
 | 
						|
                    wxString tStr;
 | 
						|
                    tStr = wxT("Database insert failed\n\n");
 | 
						|
                    wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                                 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else  // mode == mEdit
 | 
						|
        {
 | 
						|
            wxGetApp().Contact->GetDb()->RollbackTrans();
 | 
						|
            wxGetApp().Contact->whereStr.Printf("NAME = '%s'",saveName.c_str());
 | 
						|
            if (!wxGetApp().Contact->UpdateWhere(wxGetApp().Contact->whereStr))
 | 
						|
            {
 | 
						|
                wxString tStr;
 | 
						|
                tStr = wxT("Database update failed\n\n");
 | 
						|
                wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                             wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
                failed = TRUE;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (!failed)
 | 
						|
        {
 | 
						|
            wxGetApp().Contact->GetDb()->CommitTrans();
 | 
						|
            SetMode(mView);  // Sets the dialog mode back to viewing after save is successful
 | 
						|
        }
 | 
						|
        else
 | 
						|
            wxGetApp().Contact->GetDb()->RollbackTrans();
 | 
						|
 | 
						|
        wxEndBusyCursor();
 | 
						|
    }
 | 
						|
 | 
						|
    return !failed;
 | 
						|
}  // CeditorDlg::Save()
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Where this program is only showing a single row at a time in the dialog,
 | 
						|
 * a special where clause must be built to find just the single row which,
 | 
						|
 * in sequence, would follow the currently displayed row.
 | 
						|
 */
 | 
						|
bool CeditorDlg::GetNextRec()
 | 
						|
{
 | 
						|
    wxString w;
 | 
						|
 | 
						|
    if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
 | 
						|
        wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
 | 
						|
    {
 | 
						|
        w  = wxT("NAME = (SELECT MIN(NAME) FROM ");
 | 
						|
        w += wxGetApp().Contact->GetTableName();
 | 
						|
        w += wxT(" WHERE NAME > '");
 | 
						|
    }
 | 
						|
    else
 | 
						|
        w = wxT("(NAME > '");
 | 
						|
 | 
						|
    w += wxGetApp().Contact->Name;
 | 
						|
    w += wxT("'");
 | 
						|
 | 
						|
    // If a query where string is currently set, append that criteria
 | 
						|
    if (!wxGetApp().Contact->qryWhereStr.IsEmpty())
 | 
						|
    {
 | 
						|
        w += wxT(" AND (");
 | 
						|
        w += wxGetApp().Contact->qryWhereStr;
 | 
						|
        w += wxT(")");
 | 
						|
    }
 | 
						|
 | 
						|
    w += wxT(")");
 | 
						|
    return(GetRec(w));
 | 
						|
 | 
						|
}  // CeditorDlg::GetNextRec()
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Where this program is only showing a single row at a time in the dialog,
 | 
						|
 * a special where clause must be built to find just the single row which,
 | 
						|
 * in sequence, would precede the currently displayed row.
 | 
						|
 */
 | 
						|
bool CeditorDlg::GetPrevRec()
 | 
						|
{
 | 
						|
    wxString w;
 | 
						|
 | 
						|
    if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
 | 
						|
        wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
 | 
						|
    {
 | 
						|
        w  = wxT("NAME = (SELECT MAX(NAME) FROM ");
 | 
						|
        w += wxGetApp().Contact->GetTableName();
 | 
						|
        w += wxT(" WHERE NAME < '");
 | 
						|
    }
 | 
						|
    else
 | 
						|
        w = wxT("(NAME < '");
 | 
						|
 | 
						|
    w += wxGetApp().Contact->Name;
 | 
						|
    w += wxT("'");
 | 
						|
 | 
						|
    // If a query where string is currently set, append that criteria
 | 
						|
    if (!wxGetApp().Contact->qryWhereStr.IsEmpty())
 | 
						|
    {
 | 
						|
        w += wxT(" AND (");
 | 
						|
        w += wxGetApp().Contact->qryWhereStr;
 | 
						|
        w += wxT(")");
 | 
						|
    }
 | 
						|
 | 
						|
    w += wxT(")");
 | 
						|
 | 
						|
    return(GetRec(w));
 | 
						|
 | 
						|
}  // CeditorDlg::GetPrevRec()
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * This function is here to avoid duplicating this same code in both the
 | 
						|
 * GetPrevRec() and GetNextRec() functions
 | 
						|
 */
 | 
						|
bool CeditorDlg::GetRec(const wxString &whereStr)
 | 
						|
{
 | 
						|
    wxGetApp().Contact->SetWhereClause(whereStr);
 | 
						|
    wxGetApp().Contact->SetOrderByClause(wxT("NAME"));
 | 
						|
 | 
						|
    if (!wxGetApp().Contact->Query())
 | 
						|
    {
 | 
						|
        wxString tStr;
 | 
						|
        tStr = wxT("ODBC error during Query()\n\n");
 | 
						|
        wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                     wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
 | 
						|
        return(FALSE);
 | 
						|
    }
 | 
						|
 | 
						|
    if (wxGetApp().Contact->GetNext())
 | 
						|
    {
 | 
						|
        PutData();
 | 
						|
        return(TRUE);
 | 
						|
    }
 | 
						|
    else
 | 
						|
        return(FALSE);
 | 
						|
}  // CeditorDlg::GetRec()
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * CparameterDlg constructor
 | 
						|
 */
 | 
						|
 | 
						|
BEGIN_EVENT_TABLE(CparameterDlg, wxDialog)
 | 
						|
    EVT_BUTTON(PARAMETER_DIALOG_SAVE,  CparameterDlg::OnButton)
 | 
						|
    EVT_BUTTON(PARAMETER_DIALOG_CANCEL,  CparameterDlg::OnButton)
 | 
						|
    EVT_CLOSE(CparameterDlg::OnCloseWindow)
 | 
						|
END_EVENT_TABLE()
 | 
						|
 | 
						|
CparameterDlg::CparameterDlg(wxWindow *parent) : wxDialog (parent, PARAMETER_DIALOG, wxT("ODBC parameter settings"), wxPoint(-1, -1), wxSize(400, 325))
 | 
						|
{
 | 
						|
    // 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;
 | 
						|
 | 
						|
    pParamODBCSourceMsg  = new wxStaticText(this, PARAMETER_DIALOG_SOURCE_MSG,   wxT("ODBC data sources:"),   wxPoint( 10, 10),    wxSize( -1,  -1), 0, wxT("ParamODBCSourceMsg"));
 | 
						|
    pParamODBCSourceList = new wxListBox(this, PARAMETER_DIALOG_SOURCE_LISTBOX,                          wxPoint( 10, 29),    wxSize(285, 150), 0, 0, wxLB_SINGLE|wxLB_ALWAYS_SB, wxDefaultValidator, wxT("ParamODBCSourceList"));
 | 
						|
    pParamUserNameMsg    = new wxStaticText(this, PARAMETER_DIALOG_NAME_MSG,     wxT("Database user name:"),  wxPoint( 10, 193),   wxSize( -1,  -1), 0, wxT("ParamUserNameMsg"));
 | 
						|
    pParamUserNameTxt    = new wxTextCtrl(this, PARAMETER_DIALOG_NAME_TEXT,      wxT(""), wxPoint(10, 209),   wxSize( 140, 25),    0, wxDefaultValidator, wxT("ParamUserNameTxt"));
 | 
						|
    pParamPasswordMsg    = new wxStaticText(this, PARAMETER_DIALOG_PASSWORD_MSG, wxT("Password:"),            wxPoint(156, 193),   wxSize( -1,  -1), 0, wxT("ParamPasswordMsg"));
 | 
						|
    pParamPasswordTxt    = new wxTextCtrl(this, PARAMETER_DIALOG_PASSWORD_TEXT,  wxT(""), wxPoint(156, 209),  wxSize( 140,  25),   0, wxDefaultValidator, wxT("ParamPasswordTxt"));
 | 
						|
    pParamDirPathMsg     = new wxStaticText(this, PARAMETER_DIALOG_DIRPATH_MSG,  wxT("Directory:"),           wxPoint( 10, 243),   wxSize( -1,  -1), 0, wxT("ParamDirPathMsg"));
 | 
						|
    pParamDirPathTxt     = new wxTextCtrl(this, PARAMETER_DIALOG_DIRPATH_TEXT,   wxT(""),                     wxPoint( 10, 259),   wxSize(140,  25), 0, wxDefaultValidator, wxT("ParamDirPathTxt"));
 | 
						|
    pParamSaveBtn        = new wxButton(this, PARAMETER_DIALOG_SAVE,             wxT("&Save"),                wxPoint(310,  21),   wxSize( 70,  35), 0, wxDefaultValidator, wxT("ParamSaveBtn"));
 | 
						|
    pParamCancelBtn      = new wxButton(this, PARAMETER_DIALOG_CANCEL,           wxT("C&ancel"),              wxPoint(310,  66),   wxSize( 70,  35), 0, wxDefaultValidator, wxT("ParamCancelBtn"));
 | 
						|
 | 
						|
    // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to 
 | 
						|
    // handle all widget processing
 | 
						|
    widgetPtrsSet = TRUE;
 | 
						|
 | 
						|
    saved = FALSE;
 | 
						|
    savedParamSettings = wxGetApp().params;
 | 
						|
 | 
						|
    Centre(wxBOTH);
 | 
						|
    PutData();
 | 
						|
    ShowModal();
 | 
						|
}  // CparameterDlg constructor
 | 
						|
 | 
						|
 | 
						|
void CparameterDlg::OnCloseWindow(wxCloseEvent& event)
 | 
						|
{
 | 
						|
    // Put any additional checking necessary to make certain it is alright
 | 
						|
    // to close the program here that is not done elsewhere
 | 
						|
    if (!saved)
 | 
						|
    {
 | 
						|
        bool Ok = (wxMessageBox(wxT("No changes have been saved.\n\nAre you sure you wish exit the parameter screen?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
 | 
						|
        
 | 
						|
        if (!Ok)
 | 
						|
        {
 | 
						|
            event.Veto();
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        
 | 
						|
        wxGetApp().params = savedParamSettings;
 | 
						|
    }
 | 
						|
 | 
						|
    if (GetParent() != NULL)
 | 
						|
        GetParent()->SetFocus();
 | 
						|
 | 
						|
    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 )
 | 
						|
{
 | 
						|
    wxWindow *win = (wxWindow*) event.GetEventObject();
 | 
						|
    OnCommand( *win, event );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void CparameterDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
 | 
						|
{
 | 
						|
    wxString widgetName;
 | 
						|
    
 | 
						|
    widgetName = win.GetName();
 | 
						|
 | 
						|
    if (!widgetPtrsSet)
 | 
						|
        return;
 | 
						|
 | 
						|
    if (widgetName == pParamSaveBtn->GetName())
 | 
						|
    {
 | 
						|
        if (Save())
 | 
						|
        {
 | 
						|
            wxString tStr;
 | 
						|
            tStr = wxT("Database parameters have been saved.");
 | 
						|
            if (GetParent() != NULL)  // The parameter dialog was not called during startup due to a missing cfg file
 | 
						|
                tStr += wxT("\nNew parameters will take effect the next time the program is started.");
 | 
						|
            wxMessageBox(tStr,wxT("Notice..."),wxOK | wxICON_INFORMATION);
 | 
						|
            saved = TRUE;
 | 
						|
            Close();
 | 
						|
        }
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (widgetName == pParamCancelBtn->GetName())
 | 
						|
    {
 | 
						|
        Close();
 | 
						|
        return;
 | 
						|
    }
 | 
						|
}  // CparameterDlg::OnCommand()
 | 
						|
 | 
						|
 | 
						|
bool CparameterDlg::PutData()
 | 
						|
{
 | 
						|
    // Fill the data source list box
 | 
						|
    FillDataSourceList();
 | 
						|
 | 
						|
    // Fill in the fields from the params object
 | 
						|
    if (wxGetApp().params.ODBCSource && wxStrlen(wxGetApp().params.ODBCSource))
 | 
						|
    {
 | 
						|
        int index = pParamODBCSourceList->FindString(wxGetApp().params.ODBCSource);
 | 
						|
        if (index != -1)
 | 
						|
            pParamODBCSourceList->SetSelection(index);
 | 
						|
    }
 | 
						|
    pParamUserNameTxt->SetValue(wxGetApp().params.UserName);
 | 
						|
    pParamPasswordTxt->SetValue(wxGetApp().params.Password);
 | 
						|
    pParamDirPathTxt->SetValue(wxGetApp().params.DirPath);
 | 
						|
    return TRUE;
 | 
						|
}  // CparameterDlg::PutData()
 | 
						|
 | 
						|
 | 
						|
bool CparameterDlg::GetData()
 | 
						|
{
 | 
						|
    wxString tStr;
 | 
						|
    if (pParamODBCSourceList->GetStringSelection() != wxT(""))
 | 
						|
    {
 | 
						|
        tStr = pParamODBCSourceList->GetStringSelection();
 | 
						|
        if (tStr.Length() > (sizeof(wxGetApp().params.ODBCSource)-1))
 | 
						|
        {
 | 
						|
            wxString errmsg;
 | 
						|
            errmsg.Printf(wxT("ODBC Data source name is longer than the data structure to hold it.\n'Cparameter.ODBCSource' must have a larger character array\nto handle a data source with this long of a name\n\nThe data source currently selected is %d characters long."),tStr.Length());
 | 
						|
            wxMessageBox(errmsg,wxT("Internal program error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
            return FALSE;
 | 
						|
        }
 | 
						|
        wxStrcpy(wxGetApp().params.ODBCSource, tStr);
 | 
						|
    }
 | 
						|
    else
 | 
						|
        return FALSE;
 | 
						|
    
 | 
						|
    tStr = pParamUserNameTxt->GetValue();
 | 
						|
    if (tStr.Length() > (sizeof(wxGetApp().params.UserName)-1))
 | 
						|
    {
 | 
						|
        wxString errmsg;
 | 
						|
        errmsg.Printf(wxT("User name is longer than the data structure to hold it.\n'Cparameter.UserName' must have a larger character array\nto handle a data source with this long of a name\n\nThe user name currently specified is %d characters long."),tStr.Length());
 | 
						|
        wxMessageBox(errmsg,wxT("Internal program error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
    wxStrcpy(wxGetApp().params.UserName, tStr);
 | 
						|
 | 
						|
    tStr = pParamPasswordTxt->GetValue();
 | 
						|
    if (tStr.Length() > (sizeof(wxGetApp().params.Password)-1))
 | 
						|
    {
 | 
						|
        wxString errmsg;
 | 
						|
        errmsg.Printf(wxT("Password is longer than the data structure to hold it.\n'Cparameter.Password' must have a larger character array\nto handle a data source with this long of a name\n\nThe password currently specified is %d characters long."),tStr.Length());
 | 
						|
        wxMessageBox(errmsg,wxT("Internal program error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
    wxStrcpy(wxGetApp().params.Password,tStr);
 | 
						|
 | 
						|
    tStr = pParamDirPathTxt->GetValue();
 | 
						|
    tStr.Replace(wxT("\\"),wxT("/"));
 | 
						|
    if (tStr.Length() > (sizeof(wxGetApp().params.DirPath)-1))
 | 
						|
    {
 | 
						|
        wxString errmsg;
 | 
						|
        errmsg.Printf(wxT("DirPath is longer than the data structure to hold it.\n'Cparameter.DirPath' must have a larger character array\nto handle a data source with this long of a name\n\nThe password currently specified is %d characters long."),tStr.Length());
 | 
						|
        wxMessageBox(errmsg,wxT("Internal program error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
    wxStrcpy(wxGetApp().params.DirPath,tStr);
 | 
						|
    return TRUE;
 | 
						|
}  // CparameterDlg::GetData()
 | 
						|
 | 
						|
 | 
						|
bool CparameterDlg::Save()
 | 
						|
{
 | 
						|
    // Copy the current params in case user cancels changing
 | 
						|
    // the params, so that we can reset them.
 | 
						|
    if (!GetData())
 | 
						|
    {
 | 
						|
        wxGetApp().params = savedParamSettings;
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    wxGetApp().WriteParamFile(wxGetApp().params);
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}  // CparameterDlg::Save()
 | 
						|
 | 
						|
 | 
						|
void CparameterDlg::FillDataSourceList()
 | 
						|
{
 | 
						|
    wxChar Dsn[SQL_MAX_DSN_LENGTH + 1];
 | 
						|
    wxChar DsDesc[255];
 | 
						|
    wxStringList strList;
 | 
						|
 | 
						|
    while (wxDbGetDataSource(wxGetApp().DbConnectInf->GetHenv(), Dsn,
 | 
						|
                             SQL_MAX_DSN_LENGTH+1, DsDesc, 255))
 | 
						|
        strList.Add(Dsn);
 | 
						|
 | 
						|
    strList.Sort();
 | 
						|
    strList.Add(wxT(""));
 | 
						|
    wxChar **p = strList.ListToArray();
 | 
						|
 | 
						|
    int i;
 | 
						|
    for (i = 0; wxStrlen(p[i]); i++)
 | 
						|
        pParamODBCSourceList->Append(p[i]);
 | 
						|
 | 
						|
    wxDELETEA(p);
 | 
						|
}  // CparameterDlg::FillDataSourceList()
 | 
						|
 | 
						|
 | 
						|
BEGIN_EVENT_TABLE(CqueryDlg, wxDialog)
 | 
						|
    EVT_BUTTON(-1,  CqueryDlg::OnButton)
 | 
						|
    EVT_CLOSE(CqueryDlg::OnCloseWindow)
 | 
						|
END_EVENT_TABLE()
 | 
						|
 | 
						|
 
 | 
						|
// CqueryDlg() constructor
 | 
						|
CqueryDlg::CqueryDlg(wxWindow *parent, wxDb *pDb, wxChar *tblName[], 
 | 
						|
                     const wxString &pWhereArg) :
 | 
						|
    wxDialog (parent, QUERY_DIALOG, wxT("Query"), wxPoint(-1, -1), wxSize(480, 360))
 | 
						|
{
 | 
						|
    wxBeginBusyCursor();
 | 
						|
 | 
						|
    colInf = 0;
 | 
						|
    dbTable = 0;
 | 
						|
    masterTableName = tblName[0];
 | 
						|
    widgetPtrsSet = FALSE;
 | 
						|
    pDB = pDb;
 | 
						|
 | 
						|
    // Initialize the WHERE clause from the string passed in
 | 
						|
    pWhere = pWhereArg;                                           // Save a pointer to the output buffer
 | 
						|
    if (pWhere.Length() > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN)  // Check the length of the buffer passed in
 | 
						|
    {
 | 
						|
        wxString s;
 | 
						|
        s.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN+1);
 | 
						|
        wxMessageBox(s,wxT("Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        Close();
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    pQueryCol1Msg           = new wxStaticText(this, QUERY_DIALOG_COL_MSG,    wxT("Column 1:"),   wxPoint( 10,  10), wxSize( 69,  16), 0, wxT("QueryCol1Msg"));
 | 
						|
    pQueryCol1Choice        = new wxChoice(this, QUERY_DIALOG_COL_CHOICE,                    wxPoint( 10,  27), wxSize(250,  27), 0, 0, 0, wxDefaultValidator, wxT("QueryCol1Choice"));
 | 
						|
    pQueryNotMsg            = new wxStaticText(this, QUERY_DIALOG_NOT_MSG,    wxT("NOT"),         wxPoint(268,  10), wxSize( -1,  -1), 0, wxT("QueryNotMsg"));
 | 
						|
    pQueryNotCheck          = new wxCheckBox(this, QUERY_DIALOG_NOT_CHECKBOX, wxT(""),            wxPoint(275,  37), wxSize( 20,  20), 0, wxDefaultValidator, wxT("QueryNotCheck"));
 | 
						|
 | 
						|
    wxString choice_strings[9];
 | 
						|
    choice_strings[0] = wxT("=");
 | 
						|
    choice_strings[1] = wxT("<");
 | 
						|
    choice_strings[2] = wxT(">");
 | 
						|
    choice_strings[3] = wxT("<=");
 | 
						|
    choice_strings[4] = wxT(">=");
 | 
						|
    choice_strings[5] = wxT("Begins");
 | 
						|
    choice_strings[6] = wxT("Contains");
 | 
						|
    choice_strings[7] = wxT("Like");
 | 
						|
    choice_strings[8] = wxT("Between");
 | 
						|
 | 
						|
    pQueryOperatorMsg       = new wxStaticText(this, QUERY_DIALOG_OP_MSG,       wxT("Operator:"),         wxPoint(305,  10), wxSize( -1,  -1), 0, wxT("QueryOperatorMsg"));
 | 
						|
    pQueryOperatorChoice    = new wxChoice(this, QUERY_DIALOG_OP_CHOICE,                                  wxPoint(305,  27), wxSize( 80,  27), 9, choice_strings, 0, wxDefaultValidator, wxT("QueryOperatorChoice"));
 | 
						|
    pQueryCol2Msg           = new wxStaticText(this, QUERY_DIALOG_COL2_MSG,     wxT("Column 2:"),         wxPoint( 10,  65), wxSize( 69,  16), 0, wxT("QueryCol2Msg"));
 | 
						|
    pQueryCol2Choice        = new wxChoice(this, QUERY_DIALOG_COL2_CHOICE,                                wxPoint( 10,  82), wxSize(250,  27), 0, 0, 0, wxDefaultValidator, wxT("QueryCol2Choice"));
 | 
						|
    pQuerySqlWhereMsg       = new wxStaticText(this, QUERY_DIALOG_WHERE_MSG,    wxT("SQL where clause:"), wxPoint( 10, 141), wxSize( -1,  -1), 0, wxT("QuerySqlWhereMsg"));
 | 
						|
    pQuerySqlWhereMtxt      = new wxTextCtrl(this, QUERY_DIALOG_WHERE_TEXT,     wxT(""),                  wxPoint( 10, 159), wxSize(377, 134), wxTE_MULTILINE, wxDefaultValidator, wxT("QuerySqlWhereMtxt"));
 | 
						|
    pQueryAddBtn            = new wxButton(this, QUERY_DIALOG_ADD,              wxT("&Add"),              wxPoint(406,  24), wxSize( 56,  26), 0, wxDefaultValidator, wxT("QueryAddBtn"));
 | 
						|
    pQueryAndBtn            = new wxButton(this, QUERY_DIALOG_AND,              wxT("A&nd"),              wxPoint(406,  58), wxSize( 56,  26), 0, wxDefaultValidator, wxT("QueryAndBtn"));
 | 
						|
    pQueryOrBtn             = new wxButton(this, QUERY_DIALOG_OR,               wxT("&Or"),               wxPoint(406,  92), wxSize( 56,  26), 0, wxDefaultValidator, wxT("QueryOrBtn"));
 | 
						|
    pQueryLParenBtn         = new wxButton(this, QUERY_DIALOG_LPAREN,           wxT("("),                 wxPoint(406, 126), wxSize( 26,  26), 0, wxDefaultValidator, wxT("QueryLParenBtn"));
 | 
						|
    pQueryRParenBtn         = new wxButton(this, QUERY_DIALOG_RPAREN,           wxT(")"),                 wxPoint(436, 126), wxSize( 26,  26), 0, wxDefaultValidator, wxT("QueryRParenBtn"));
 | 
						|
    pQueryDoneBtn           = new wxButton(this, QUERY_DIALOG_DONE,             wxT("&Done"),             wxPoint(406, 185), wxSize( 56,  26), 0, wxDefaultValidator, wxT("QueryDoneBtn"));
 | 
						|
    pQueryClearBtn          = new wxButton(this, QUERY_DIALOG_CLEAR,            wxT("C&lear"),            wxPoint(406, 218), wxSize( 56,  26), 0, wxDefaultValidator, wxT("QueryClearBtn"));
 | 
						|
    pQueryCountBtn          = new wxButton(this, QUERY_DIALOG_COUNT,            wxT("&Count"),            wxPoint(406, 252), wxSize( 56,  26), 0, wxDefaultValidator, wxT("QueryCountBtn"));
 | 
						|
    pQueryValue1Msg         = new wxStaticText(this, QUERY_DIALOG_VALUE1_MSG,   wxT("Value:"),            wxPoint(277,  66), wxSize( -1,  -1), 0, wxT("QueryValue1Msg"));
 | 
						|
    pQueryValue1Txt         = new wxTextCtrl(this, QUERY_DIALOG_VALUE1_TEXT,    wxT(""),                  wxPoint(277,  83), wxSize(108,  25), 0, wxDefaultValidator, wxT("QueryValue1Txt"));
 | 
						|
    pQueryValue2Msg         = new wxStaticText(this, QUERY_DIALOG_VALUE2_MSG,   wxT("AND"),               wxPoint(238, 126), wxSize( -1,  -1), 0, wxT("QueryValue2Msg"));
 | 
						|
    pQueryValue2Txt         = new wxTextCtrl(this, QUERY_DIALOG_VALUE2_TEXT,    wxT(""),                  wxPoint(277, 120), wxSize(108,  25), 0, wxDefaultValidator, wxT("QueryValue2Txt"));
 | 
						|
    pQueryHintGrp           = new wxStaticBox(this, QUERY_DIALOG_HINT_GROUP,    wxT(""),                  wxPoint( 10, 291), wxSize(377,  40), 0, wxT("QueryHintGrp"));
 | 
						|
    pQueryHintMsg           = new wxStaticText(this, QUERY_DIALOG_HINT_MSG,     wxT(""),                  wxPoint( 16, 306), wxSize( -1,  -1), 0, wxT("QueryHintMsg"));
 | 
						|
 | 
						|
    widgetPtrsSet = TRUE;
 | 
						|
    // Initialize the dialog
 | 
						|
    wxString qualName;
 | 
						|
    pQueryCol2Choice->Append(wxT("VALUE -->"));
 | 
						|
    colInf = pDB->GetColumns(tblName);
 | 
						|
 | 
						|
    if (!colInf)
 | 
						|
    {
 | 
						|
        wxEndBusyCursor();
 | 
						|
        wxString tStr;
 | 
						|
        tStr = wxT("ODBC error during GetColumns()\n\n");
 | 
						|
        wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                     wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    int 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 (tblName[1] && wxStrlen(tblName[1]))
 | 
						|
        {
 | 
						|
            qualName.Printf(wxT("%s.%s"), colInf[i].tableName, colInf[i].colName);
 | 
						|
            pQueryCol1Choice->Append(qualName);
 | 
						|
            pQueryCol2Choice->Append(qualName);
 | 
						|
        }
 | 
						|
        else  // Single table query, append just the column names
 | 
						|
        {
 | 
						|
            pQueryCol1Choice->Append(colInf[i].colName);
 | 
						|
            pQueryCol2Choice->Append(colInf[i].colName);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    pQueryCol1Choice->SetSelection(0);
 | 
						|
    pQueryCol2Choice->SetSelection(0);
 | 
						|
    pQueryOperatorChoice->SetSelection(0);
 | 
						|
 | 
						|
    pQueryValue2Msg->Show(FALSE);
 | 
						|
    pQueryValue2Txt->Show(FALSE);
 | 
						|
 | 
						|
    pQueryHintMsg->SetLabel(langQRY_EQ);
 | 
						|
 | 
						|
    pQuerySqlWhereMtxt->SetValue(pWhere.c_str());
 | 
						|
 | 
						|
    wxEndBusyCursor();
 | 
						|
 | 
						|
    // Display the dialog window
 | 
						|
    Centre(wxBOTH);
 | 
						|
    ShowModal();
 | 
						|
}  // CqueryDlg() constructor
 | 
						|
 | 
						|
 | 
						|
CqueryDlg::~CqueryDlg()
 | 
						|
{
 | 
						|
}  // CqueryDlg::~CqueryDlg() destructor
 | 
						|
 | 
						|
 | 
						|
void CqueryDlg::OnButton(wxCommandEvent &event)
 | 
						|
{
 | 
						|
  wxWindow *win = (wxWindow*) event.GetEventObject();
 | 
						|
  OnCommand( *win, event );
 | 
						|
}  // CqueryDlg::OnButton()
 | 
						|
 | 
						|
 | 
						|
void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
 | 
						|
{
 | 
						|
    // Widget pointers won't be set when the dialog is constructed.
 | 
						|
    // Control is passed through this function once for each widget on
 | 
						|
    // a dialog as the dialog is constructed.
 | 
						|
    if (!widgetPtrsSet)
 | 
						|
        return;
 | 
						|
 | 
						|
    wxString widgetName = win.GetName();
 | 
						|
 | 
						|
    // Operator choice box
 | 
						|
    if (widgetName == pQueryOperatorChoice->GetName())
 | 
						|
    {
 | 
						|
        // 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;
 | 
						|
        }
 | 
						|
 | 
						|
        // Hide the value2 widget
 | 
						|
        pQueryValue2Msg->Show(FALSE);  // BETWEEN will show this widget
 | 
						|
        pQueryValue2Txt->Show(FALSE);  // BETWEEN will show this widget
 | 
						|
 | 
						|
        // 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;
 | 
						|
        }
 | 
						|
 | 
						|
        // 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
 | 
						|
                {
 | 
						|
                    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;
 | 
						|
        }
 | 
						|
 | 
						|
        return;
 | 
						|
 | 
						|
    }  // Operator choice box
 | 
						|
 | 
						|
    // Column 2 choice
 | 
						|
    if (widgetName == pQueryCol2Choice->GetName())
 | 
						|
    {
 | 
						|
        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();
 | 
						|
        }
 | 
						|
        return;
 | 
						|
    }  // Column 2 choice
 | 
						|
 | 
						|
    // Add button
 | 
						|
    if (widgetName == pQueryAddBtn->GetName())
 | 
						|
    {
 | 
						|
        ProcessAddBtn();
 | 
						|
        return;
 | 
						|
    }  // Add button
 | 
						|
 | 
						|
    // And button
 | 
						|
    if (widgetName == pQueryAndBtn->GetName())
 | 
						|
    {
 | 
						|
        AppendToWhere(wxT(" AND\n"));
 | 
						|
        return;
 | 
						|
    }  // And button
 | 
						|
 | 
						|
    // Or button
 | 
						|
    if (widgetName == pQueryOrBtn->GetName())
 | 
						|
    {
 | 
						|
        AppendToWhere(wxT(" OR\n"));
 | 
						|
        return;
 | 
						|
    }  // Or button
 | 
						|
 | 
						|
    // Left Paren button
 | 
						|
    if (widgetName == pQueryLParenBtn->GetName())
 | 
						|
    {
 | 
						|
        AppendToWhere(wxT("("));
 | 
						|
        return;
 | 
						|
    }  // Left Paren button
 | 
						|
 | 
						|
    // Right paren button
 | 
						|
    if (widgetName == pQueryRParenBtn->GetName())
 | 
						|
    {
 | 
						|
        AppendToWhere(wxT(")"));
 | 
						|
        return;
 | 
						|
    }  // Right Paren button
 | 
						|
 | 
						|
    // Done button
 | 
						|
    if (widgetName == pQueryDoneBtn->GetName())
 | 
						|
    {
 | 
						|
        // Be sure the where clause will not overflow the output buffer
 | 
						|
        if (wxStrlen(pQuerySqlWhereMtxt->GetValue()) > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN)
 | 
						|
        {
 | 
						|
            wxString s;
 | 
						|
            s.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN+1);
 | 
						|
            wxMessageBox(s,wxT("Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        // Validate the where clause for things such as matching parens
 | 
						|
        if (!ValidateWhereClause())
 | 
						|
            return;
 | 
						|
        // Copy the where clause to the output buffer and exit
 | 
						|
        pWhere = pQuerySqlWhereMtxt->GetValue();
 | 
						|
        Close();
 | 
						|
        return;
 | 
						|
    }  // Done button
 | 
						|
 | 
						|
    // Clear button
 | 
						|
    if (widgetName == pQueryClearBtn->GetName())
 | 
						|
    {
 | 
						|
        bool Ok = (wxMessageBox(wxT("Are you sure you wish to clear the Query?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
 | 
						|
 | 
						|
        if (Ok)
 | 
						|
            pQuerySqlWhereMtxt->SetValue(wxT(""));
 | 
						|
        return;
 | 
						|
    }  // Clear button
 | 
						|
 | 
						|
    // Count button
 | 
						|
    if (widgetName == pQueryCountBtn->GetName())
 | 
						|
    {
 | 
						|
        wxBeginBusyCursor();
 | 
						|
        ProcessCountBtn();
 | 
						|
        wxEndBusyCursor();
 | 
						|
        return;
 | 
						|
    }  // Count button
 | 
						|
 | 
						|
}  // CqueryDlg::OnCommand
 | 
						|
 | 
						|
 | 
						|
void CqueryDlg::OnCloseWindow(wxCloseEvent& event)
 | 
						|
{
 | 
						|
    // Clean up
 | 
						|
    wxDELETEA(colInf);
 | 
						|
 | 
						|
    wxDELETE(dbTable);
 | 
						|
 | 
						|
    GetParent()->SetFocus();
 | 
						|
    while (wxIsBusy())
 | 
						|
        wxEndBusyCursor();
 | 
						|
 | 
						|
    Show(FALSE);
 | 
						|
    SetReturnCode(1);  // added so BoundsChecker would not report use of uninitialized variable
 | 
						|
 | 
						|
    this->Destroy();
 | 
						|
}  // CqueryDlg::OnCloseWindow()
 | 
						|
 | 
						|
 | 
						|
void CqueryDlg::AppendToWhere(wxChar *s)
 | 
						|
{
 | 
						|
    wxString whereStr = pQuerySqlWhereMtxt->GetValue();
 | 
						|
    whereStr += s;
 | 
						|
    pQuerySqlWhereMtxt->SetValue(whereStr);
 | 
						|
}  // CqueryDlg::AppendToWhere()
 | 
						|
 | 
						|
 | 
						|
void CqueryDlg::ProcessAddBtn()
 | 
						|
{
 | 
						|
    qryOp oper = (qryOp) pQueryOperatorChoice->GetSelection();
 | 
						|
 | 
						|
    // Verify that eveything is filled in correctly
 | 
						|
    if (pQueryCol2Choice->GetSelection() == 0)            // "Value" is selected
 | 
						|
    {
 | 
						|
        // Verify that value 1 is filled in
 | 
						|
        if (wxStrlen(pQueryValue1Txt->GetValue()) == 0)
 | 
						|
        {
 | 
						|
            wxBell();
 | 
						|
            pQueryValue1Txt->SetFocus();
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        // For the BETWEEN operator, value 2 must be filled in as well
 | 
						|
        if (oper == qryOpBETWEEN &&
 | 
						|
             wxStrlen(pQueryValue2Txt->GetValue()) == 0)
 | 
						|
        {
 | 
						|
            wxBell();
 | 
						|
            pQueryValue2Txt->SetFocus();
 | 
						|
            return;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // Build the expression and append it to the where clause window
 | 
						|
    wxString s = pQueryCol1Choice->GetStringSelection();
 | 
						|
    
 | 
						|
    if (pQueryNotCheck->GetValue() && (oper != qryOpEQ))
 | 
						|
        s += wxT(" NOT");
 | 
						|
    
 | 
						|
    switch(oper)
 | 
						|
    {
 | 
						|
    case qryOpEQ:
 | 
						|
        if (pQueryNotCheck->GetValue())    // NOT box is checked
 | 
						|
            s += wxT(" <>");
 | 
						|
        else
 | 
						|
            s += wxT(" =");
 | 
						|
        break;
 | 
						|
    case qryOpLT:
 | 
						|
        s += wxT(" <");
 | 
						|
        break;
 | 
						|
    case qryOpGT:
 | 
						|
        s += wxT(" >");
 | 
						|
        break;
 | 
						|
    case qryOpLE:
 | 
						|
        s += wxT(" <=");
 | 
						|
        break;
 | 
						|
    case qryOpGE:
 | 
						|
        s += wxT(" >=");
 | 
						|
        break;
 | 
						|
    case qryOpBEGINS:
 | 
						|
    case qryOpCONTAINS:
 | 
						|
    case qryOpLIKE:
 | 
						|
        s += wxT(" LIKE");
 | 
						|
        break;
 | 
						|
    case qryOpBETWEEN:
 | 
						|
        s += wxT(" BETWEEN");
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    s += wxT(" ");
 | 
						|
 | 
						|
    int col1Idx = pQueryCol1Choice->GetSelection();
 | 
						|
 | 
						|
    bool quote = FALSE;
 | 
						|
    if (colInf[col1Idx].sqlDataType == SQL_VARCHAR  ||
 | 
						|
        oper == qryOpBEGINS                         ||
 | 
						|
        oper == qryOpCONTAINS                       ||
 | 
						|
        oper == qryOpLIKE)
 | 
						|
        quote = TRUE;
 | 
						|
 | 
						|
    if (pQueryCol2Choice->GetSelection())    // Column name
 | 
						|
        s += pQueryCol2Choice->GetStringSelection();
 | 
						|
    else  // Column 2 is a "value"
 | 
						|
    {
 | 
						|
        if (quote)
 | 
						|
            s += wxT("'");
 | 
						|
        if (oper == qryOpCONTAINS)
 | 
						|
            s += wxT("%");
 | 
						|
        s += pQueryValue1Txt->GetValue();
 | 
						|
        if (oper == qryOpCONTAINS || oper == qryOpBEGINS)
 | 
						|
            s += wxT("%");
 | 
						|
        if (quote)
 | 
						|
            s += wxT("'");
 | 
						|
    }
 | 
						|
 | 
						|
    if (oper == qryOpBETWEEN)
 | 
						|
    {
 | 
						|
        s += wxT(" AND ");
 | 
						|
        if (quote)
 | 
						|
            s += wxT("'");
 | 
						|
        s += pQueryValue2Txt->GetValue();
 | 
						|
        if (quote)
 | 
						|
            s += wxT("'");
 | 
						|
    }
 | 
						|
 | 
						|
    AppendToWhere((wxChar*) (const wxChar*) s);
 | 
						|
 | 
						|
}  // CqueryDlg::ProcessAddBtn()
 | 
						|
 | 
						|
 | 
						|
void CqueryDlg::ProcessCountBtn()
 | 
						|
{
 | 
						|
    if (!ValidateWhereClause())
 | 
						|
        return;
 | 
						|
 | 
						|
    if (!dbTable)  // wxDbTable object needs to be created and opened
 | 
						|
    {
 | 
						|
        dbTable = new wxDbTable(pDB, masterTableName, 0, wxT(""),
 | 
						|
                                !wxDB_QUERY_ONLY, 
 | 
						|
                                wxGetApp().DbConnectInf->GetDefaultDir());
 | 
						|
        if (!dbTable)
 | 
						|
        {
 | 
						|
            wxMessageBox(wxT("Memory allocation failed creating a wxDbTable object."),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        if (!dbTable->Open())
 | 
						|
        {
 | 
						|
            wxString tStr;
 | 
						|
            tStr = wxT("ODBC error during Open()\n\n");
 | 
						|
            wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                         wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
            return;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // Count() with WHERE clause
 | 
						|
    wxString whereStr;
 | 
						|
 | 
						|
    whereStr = pQuerySqlWhereMtxt->GetValue();
 | 
						|
    dbTable->SetWhereClause(whereStr.c_str());
 | 
						|
 | 
						|
    ULONG whereCnt = dbTable->Count();
 | 
						|
 | 
						|
    // Count() of all records in the table
 | 
						|
    dbTable->SetWhereClause(wxT(""));
 | 
						|
    ULONG totalCnt = dbTable->Count();
 | 
						|
 | 
						|
    if (whereCnt > 0 || totalCnt == 0)
 | 
						|
    {
 | 
						|
        wxString tStr;
 | 
						|
        tStr.Printf(wxT("%lu of %lu records match the query criteria."),whereCnt,totalCnt);
 | 
						|
        wxMessageBox(tStr,wxT("Notice..."),wxOK | wxICON_INFORMATION);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        wxString tStr;
 | 
						|
        tStr.Printf(wxT("%lu of %lu records match the query criteria.\n\nEither the criteria entered produced a result set\nwith no records, or there was a syntactical error\nin the clause you entered.\n\nPress the details button to see if any database errors were reported."),whereCnt,totalCnt);
 | 
						|
        wxMessageBox(tStr,wxT("Notice..."),wxOK | wxICON_INFORMATION);
 | 
						|
    }
 | 
						|
 | 
						|
    // After a wxMessageBox, the focus does not necessarily return to the
 | 
						|
    // window which was the focus when the message box popped up, so return
 | 
						|
    // focus to the Query dialog for certain
 | 
						|
    SetFocus();
 | 
						|
 | 
						|
}  // CqueryDlg::ProcessCountBtn()
 | 
						|
 | 
						|
 | 
						|
bool CqueryDlg::ValidateWhereClause()
 | 
						|
{
 | 
						|
    wxString where = pQuerySqlWhereMtxt->GetValue();
 | 
						|
 | 
						|
    if (where.Freq(wxT('(')) != where.Freq(wxT(')')))
 | 
						|
    {
 | 
						|
        wxMessageBox(wxT("There are mismatched parenthesis in the constructed where clause"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        return(FALSE);
 | 
						|
    }
 | 
						|
    // After a wxMessageBox, the focus does not necessarily return to the
 | 
						|
    // window which was the focus when the message box popped up, so return
 | 
						|
    // focus to the Query dialog for certain
 | 
						|
    SetFocus();
 | 
						|
 | 
						|
    return(TRUE);
 | 
						|
 | 
						|
}  // CqueryDlg::ValidateWhereClause()
 | 
						|
 | 
						|
 | 
						|
 | 
						|
void DisplayDbDiagnostics(wxDb *pDb)
 | 
						|
{
 | 
						|
    wxString s, t;
 | 
						|
    bool comma = FALSE;
 | 
						|
 | 
						|
    s = langDBINF_DB_NAME;
 | 
						|
    s += pDb->dbInf.dbmsName;
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_DB_VER;
 | 
						|
    s += pDb->dbInf.dbmsVer;
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_DRIVER_NAME;
 | 
						|
    s += pDb->dbInf.driverName;
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_DRIVER_ODBC_VER;
 | 
						|
    s += pDb->dbInf.odbcVer;
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_DRIVER_MGR_ODBC_VER;
 | 
						|
    s += pDb->dbInf.drvMgrOdbcVer;
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_DRIVER_VER;
 | 
						|
    s += pDb->dbInf.driverVer;
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_SERVER_NAME;
 | 
						|
    s += pDb->dbInf.serverName;
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_FILENAME;
 | 
						|
    s += pDb->dbInf.databaseName;
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_OUTER_JOINS;
 | 
						|
    s += pDb->dbInf.outerJoins;
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_STORED_PROC;
 | 
						|
    s += pDb->dbInf.procedureSupport;
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    if (pDb->dbInf.maxConnections)
 | 
						|
        t.sprintf("%s%d\n", langDBINF_MAX_HDBC, pDb->dbInf.maxConnections);
 | 
						|
    else
 | 
						|
        t.sprintf("%s%s\n", langDBINF_MAX_HDBC, langDBINF_UNLIMITED);
 | 
						|
    s += t;
 | 
						|
 | 
						|
    if (pDb->dbInf.maxStmts)
 | 
						|
        t.sprintf("%s%d\n", langDBINF_MAX_HSTMT, pDb->dbInf.maxStmts);
 | 
						|
    else
 | 
						|
        t.sprintf("%s%s\n", langDBINF_MAX_HSTMT, langDBINF_UNLIMITED);
 | 
						|
    s += t;
 | 
						|
 | 
						|
    s += langDBINF_API_LVL;
 | 
						|
    switch(pDb->dbInf.apiConfLvl)
 | 
						|
    {
 | 
						|
        case SQL_OAC_NONE:  s += langDBINF_NONE;        break;
 | 
						|
        case SQL_OAC_LEVEL1:    s += langDBINF_LEVEL1;  break;
 | 
						|
        case SQL_OAC_LEVEL2:    s += langDBINF_LEVEL2;  break;
 | 
						|
    }
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_CLI_LVL;
 | 
						|
    switch(pDb->dbInf.cliConfLvl)
 | 
						|
    {
 | 
						|
        case SQL_OSCC_NOT_COMPLIANT:    s += langDBINF_NOT_COMPLIANT;   break;
 | 
						|
        case SQL_OSCC_COMPLIANT:        s += langDBINF_COMPLIANT;           break;
 | 
						|
    }
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_SQL_LVL;
 | 
						|
    switch(pDb->dbInf.sqlConfLvl)
 | 
						|
    {
 | 
						|
        case SQL_OSC_MINIMUM:   s += langDBINF_MIN_GRAMMAR; break;
 | 
						|
        case SQL_OSC_CORE:      s += langDBINF_CORE_GRAMMAR;    break;
 | 
						|
        case SQL_OSC_EXTENDED:  s += langDBINF_EXT_GRAMMAR; break;
 | 
						|
    }
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_COMMIT_BEHAVIOR;
 | 
						|
    switch(pDb->dbInf.cursorCommitBehavior)
 | 
						|
    {
 | 
						|
        case SQL_CB_DELETE:     s += langDBINF_DELETE_CURSORS;  break;
 | 
						|
        case SQL_CB_CLOSE:      s += langDBINF_CLOSE_CURSORS;       break;
 | 
						|
        case SQL_CB_PRESERVE:   s += langDBINF_PRESERVE_CURSORS;    break;
 | 
						|
    }
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_ROLLBACK_BEHAVIOR;
 | 
						|
    switch(pDb->dbInf.cursorRollbackBehavior)
 | 
						|
    {
 | 
						|
        case SQL_CB_DELETE:     s += langDBINF_DELETE_CURSORS;  break;
 | 
						|
        case SQL_CB_CLOSE:      s += langDBINF_CLOSE_CURSORS;       break;
 | 
						|
        case SQL_CB_PRESERVE:   s += langDBINF_PRESERVE_CURSORS;    break;
 | 
						|
    }
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_SUPP_NOT_NULL;
 | 
						|
    switch(pDb->dbInf.supportNotNullClause)
 | 
						|
    {
 | 
						|
        case SQL_NNC_NULL:      s += langNO;    break;
 | 
						|
        case SQL_NNC_NON_NULL:  s += langYES;   break;
 | 
						|
    }
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    s += langDBINF_SUPP_IEF;
 | 
						|
    s += pDb->dbInf.supportIEF;
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    // DEFAULT setting for "Transaction Isolation Level"
 | 
						|
    s += langDBINF_TXN_ISOLATION;
 | 
						|
    switch(pDb->dbInf.txnIsolation)
 | 
						|
    {
 | 
						|
        case SQL_TXN_READ_UNCOMMITTED:  s += langDBINF_READ_UNCOMMITTED;    break;
 | 
						|
        case SQL_TXN_READ_COMMITTED:        s += langDBINF_READ_COMMITTED;  break;
 | 
						|
        case SQL_TXN_REPEATABLE_READ:       s += langDBINF_REPEATABLE_READ; break;
 | 
						|
        case SQL_TXN_SERIALIZABLE:          s += langDBINF_SERIALIZABLE;        break;
 | 
						|
#ifdef ODBC_V20
 | 
						|
        case SQL_TXN_VERSIONING:            s += langDBINF_VERSIONING;          break;
 | 
						|
#endif
 | 
						|
    }
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    // CURRENT setting for "Transaction Isolation Level"
 | 
						|
    long txnIsoLvl;
 | 
						|
    s += langDBINF_TXN_ISOLATION_CURR;
 | 
						|
    if (SQLGetConnectOption(pDb->GetHDBC(),SQL_TXN_ISOLATION,&txnIsoLvl) == SQL_SUCCESS)
 | 
						|
    {
 | 
						|
        switch(txnIsoLvl)
 | 
						|
        {
 | 
						|
            case SQL_TXN_READ_UNCOMMITTED:  s += langDBINF_READ_UNCOMMITTED;    break;
 | 
						|
            case SQL_TXN_READ_COMMITTED:        s += langDBINF_READ_COMMITTED;  break;
 | 
						|
            case SQL_TXN_REPEATABLE_READ:       s += langDBINF_REPEATABLE_READ; break;
 | 
						|
            case SQL_TXN_SERIALIZABLE:          s += langDBINF_SERIALIZABLE;        break;
 | 
						|
#ifdef ODBC_V20
 | 
						|
            case SQL_TXN_VERSIONING:            s += langDBINF_VERSIONING;          break;
 | 
						|
#endif
 | 
						|
        }
 | 
						|
    }
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
#ifdef __VMS__
 | 
						|
#pragma message disable incboodep
 | 
						|
#endif
 | 
						|
    comma = FALSE;
 | 
						|
    s += langDBINF_TXN_ISOLATION_OPTS;
 | 
						|
    if (pDb->dbInf.txnIsolationOptions & SQL_TXN_READ_UNCOMMITTED)
 | 
						|
        {s += langDBINF_READ_UNCOMMITTED; comma++;}
 | 
						|
    if (pDb->dbInf.txnIsolationOptions & SQL_TXN_READ_COMMITTED)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_READ_COMMITTED;}
 | 
						|
    if (pDb->dbInf.txnIsolationOptions & SQL_TXN_REPEATABLE_READ)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_REPEATABLE_READ;}
 | 
						|
    if (pDb->dbInf.txnIsolationOptions & SQL_TXN_SERIALIZABLE)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_SERIALIZABLE;}
 | 
						|
#ifdef ODBC_V20
 | 
						|
    if (pDb->dbInf.txnIsolationOptions & SQL_TXN_VERSIONING)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_VERSIONING;}
 | 
						|
#endif
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    comma = FALSE;
 | 
						|
    s += langDBINF_FETCH_DIRS;
 | 
						|
    if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_NEXT)
 | 
						|
        {s += langDBINF_NEXT; comma++;}
 | 
						|
    if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_PRIOR)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_PREV;}
 | 
						|
    if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_FIRST)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_FIRST;}
 | 
						|
    if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_LAST)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_LAST;}
 | 
						|
    if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_ABSOLUTE)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_ABSOLUTE;}
 | 
						|
    if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_RELATIVE)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_RELATIVE;}
 | 
						|
#ifdef ODBC_V20
 | 
						|
    if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_RESUME)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_RESUME;}
 | 
						|
#endif
 | 
						|
    if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_BOOKMARK)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_BOOKMARK;}
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    comma = FALSE;
 | 
						|
    s += langDBINF_LOCK_TYPES;
 | 
						|
    if (pDb->dbInf.lockTypes & SQL_LCK_NO_CHANGE)
 | 
						|
        {s += langDBINF_NO_CHANGE; comma++;}
 | 
						|
    if (pDb->dbInf.lockTypes & SQL_LCK_EXCLUSIVE)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_EXCLUSIVE;}
 | 
						|
    if (pDb->dbInf.lockTypes & SQL_LCK_UNLOCK)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_UNLOCK;}
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    comma = FALSE;
 | 
						|
    s += langDBINF_POS_OPERS;
 | 
						|
    if (pDb->dbInf.posOperations & SQL_POS_POSITION)
 | 
						|
        {s += langDBINF_POSITION; comma++;}
 | 
						|
    if (pDb->dbInf.posOperations & SQL_POS_REFRESH)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_REFRESH;}
 | 
						|
    if (pDb->dbInf.posOperations & SQL_POS_UPDATE)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_UPD;}
 | 
						|
    if (pDb->dbInf.posOperations & SQL_POS_DELETE)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_DEL;}
 | 
						|
    if (pDb->dbInf.posOperations & SQL_POS_ADD)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_ADD;}
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    comma = FALSE;
 | 
						|
    s += langDBINF_POS_STMTS;
 | 
						|
    if (pDb->dbInf.posStmts & SQL_PS_POSITIONED_DELETE)
 | 
						|
        {s += langDBINF_POS_DEL; comma++;}
 | 
						|
    if (pDb->dbInf.posStmts & SQL_PS_POSITIONED_UPDATE)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_POS_UPD;}
 | 
						|
    if (pDb->dbInf.posStmts & SQL_PS_SELECT_FOR_UPDATE)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_SELECT_FOR_UPD;}
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    comma = FALSE;
 | 
						|
    s += langDBINF_SCROLL_CONCURR;
 | 
						|
    if (pDb->dbInf.scrollConcurrency & SQL_SCCO_READ_ONLY)
 | 
						|
        {s += langDBINF_READ_ONLY; comma++;}
 | 
						|
    if (pDb->dbInf.scrollConcurrency & SQL_SCCO_LOCK)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_LOCK;}
 | 
						|
    if (pDb->dbInf.scrollConcurrency & SQL_SCCO_OPT_ROWVER)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_OPT_ROWVER;}
 | 
						|
    if (pDb->dbInf.scrollConcurrency & SQL_SCCO_OPT_VALUES)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_OPT_VALUES;}
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    comma = FALSE;
 | 
						|
    s += langDBINF_SCROLL_OPTS;
 | 
						|
    if (pDb->dbInf.scrollOptions & SQL_SO_FORWARD_ONLY)
 | 
						|
        {s += langDBINF_FWD_ONLY; comma++;}
 | 
						|
    if (pDb->dbInf.scrollOptions & SQL_SO_STATIC)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_STATIC;}
 | 
						|
    if (pDb->dbInf.scrollOptions & SQL_SO_KEYSET_DRIVEN)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_KEYSET_DRIVEN;}
 | 
						|
    if (pDb->dbInf.scrollOptions & SQL_SO_DYNAMIC)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_DYNAMIC;}
 | 
						|
    if (pDb->dbInf.scrollOptions & SQL_SO_MIXED)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_MIXED;}
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    comma = FALSE;
 | 
						|
    s += langDBINF_STATIC_SENS;
 | 
						|
    if (pDb->dbInf.staticSensitivity & SQL_SS_ADDITIONS)
 | 
						|
        {s += langDBINF_ADDITIONS; comma++;}
 | 
						|
    if (pDb->dbInf.staticSensitivity & SQL_SS_DELETIONS)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_DELETIONS;}
 | 
						|
    if (pDb->dbInf.staticSensitivity & SQL_SS_UPDATES)
 | 
						|
        {if (comma++) s += ", "; s += langDBINF_UPDATES;}
 | 
						|
    s += "\n";
 | 
						|
#ifdef __VMS__
 | 
						|
#pragma message enable incboodep
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
    s += langDBINF_TXN_CAPABLE;
 | 
						|
    switch(pDb->dbInf.txnCapable)
 | 
						|
    {
 | 
						|
        case SQL_TC_NONE:           s += langNO;                        break;
 | 
						|
        case SQL_TC_DML:            s += langDBINF_DML_ONLY;        break;
 | 
						|
        case SQL_TC_DDL_COMMIT: s += langDBINF_DDL_COMMIT;      break;
 | 
						|
        case SQL_TC_DDL_IGNORE: s += langDBINF_DDL_IGNORE;      break;
 | 
						|
        case SQL_TC_ALL:            s += langDBINF_DDL_AND_DML; break;
 | 
						|
    }
 | 
						|
    s += "\n";
 | 
						|
 | 
						|
    t.sprintf("%s%d\n", langDBINF_LOGIN_TIMEOUT, pDb->dbInf.loginTimeout);
 | 
						|
    s += t;
 | 
						|
 | 
						|
    // Oracle specific information
 | 
						|
    if (pDb->Dbms() == dbmsORACLE)
 | 
						|
    {
 | 
						|
        s += "\n";
 | 
						|
        s += langDBINF_ORACLE_BANNER;
 | 
						|
        s += "\n";
 | 
						|
 | 
						|
        // Oracle cache hit ratio
 | 
						|
        SDWORD cb;
 | 
						|
        ULONG dbBlockGets;
 | 
						|
        pDb->ExecSql("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'db block gets'");
 | 
						|
        pDb->GetNext();
 | 
						|
        if (pDb->GetData(1, SQL_C_ULONG, &dbBlockGets, 0, &cb))
 | 
						|
        {
 | 
						|
            t.sprintf("%s: %lu\n", langDBINF_DB_BLOCK_GETS, dbBlockGets);
 | 
						|
            s += t;
 | 
						|
        }
 | 
						|
 | 
						|
        ULONG consistentGets;
 | 
						|
        pDb->ExecSql("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'consistent gets'");
 | 
						|
        pDb->GetNext();
 | 
						|
        if (pDb->GetData(1, SQL_C_ULONG, &consistentGets, 0, &cb))
 | 
						|
        {
 | 
						|
            t.sprintf("%s: %lu\n", langDBINF_CONSISTENT_GETS, consistentGets);
 | 
						|
            s += t;
 | 
						|
        }
 | 
						|
 | 
						|
        ULONG physReads;
 | 
						|
        pDb->ExecSql("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'physical reads'");
 | 
						|
        pDb->GetNext();
 | 
						|
        if (pDb->GetData(1, SQL_C_ULONG, &physReads, 0, &cb))
 | 
						|
        {
 | 
						|
            t.sprintf("%s: %lu\n", langDBINF_PHYSICAL_READS, physReads);
 | 
						|
            s += t;
 | 
						|
        }
 | 
						|
 | 
						|
        ULONG hitRatio = (ULONG)((1.00 - ((float)physReads / (float)(dbBlockGets + consistentGets))) * 100.00);
 | 
						|
        t.sprintf("*** %s: %lu%%\n", langDBINF_CACHE_HIT_RATIO, hitRatio);
 | 
						|
        s += t;
 | 
						|
 | 
						|
        // Tablespace information
 | 
						|
        s += "\n";
 | 
						|
        s += langDBINF_TABLESPACE_IO;
 | 
						|
        s += "\n";
 | 
						|
        ULONG physWrites;
 | 
						|
        char tablespaceName[257];
 | 
						|
        pDb->ExecSql("SELECT NAME,PHYRDS,PHYWRTS FROM V$DATAFILE, V$FILESTAT WHERE V$DATAFILE.FILE# = V$FILESTAT.FILE#");
 | 
						|
        while (pDb->GetNext())
 | 
						|
        {
 | 
						|
            pDb->GetData(1, SQL_C_CHAR,  tablespaceName, 257, &cb);
 | 
						|
            pDb->GetData(2, SQL_C_ULONG, &physReads,     0,   &cb);
 | 
						|
            pDb->GetData(3, SQL_C_ULONG, &physWrites,    0,   &cb);
 | 
						|
            t.sprintf("%s\n\t%s: %lu\t%s: %lu\n", tablespaceName,
 | 
						|
                langDBINF_PHYSICAL_READS, physReads, langDBINF_PHYSICAL_WRITES, physWrites);
 | 
						|
            s += t;
 | 
						|
        }
 | 
						|
 | 
						|
        s += "\n";
 | 
						|
    }
 | 
						|
 | 
						|
    wxLogMessage(s);
 | 
						|
 | 
						|
}  // DisplayDbDiagnostics()
 | 
						|
 | 
						|
#if wxUSE_NEW_GRID
 | 
						|
 | 
						|
BEGIN_EVENT_TABLE(DbGridFrame, wxFrame)
 | 
						|
 //   EVT_CLOSE(DbGridFrame::OnCloseWindow)
 | 
						|
END_EVENT_TABLE()
 | 
						|
 | 
						|
 | 
						|
DbGridFrame::DbGridFrame(wxWindow *parent)
 | 
						|
    : wxFrame (parent, -1, wxT("Database Table"),
 | 
						|
               wxDefaultPosition, wxSize(400, 325))
 | 
						|
{
 | 
						|
    initialized = FALSE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void DbGridFrame::OnCloseWindow(wxCloseEvent& event)
 | 
						|
{
 | 
						|
    this->Destroy();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool DbGridFrame::Initialize()
 | 
						|
{
 | 
						|
    wxGrid *grid = new wxGrid(this, -1, wxDefaultPosition);
 | 
						|
 | 
						|
    grid->RegisterDataType(wxGRID_VALUE_DATETIME,
 | 
						|
                             new wxGridCellDateTimeRenderer(_T("%d %b %Y")),
 | 
						|
                             new wxGridCellTextEditor);
 | 
						|
#ifdef CHOICEINT
 | 
						|
    grid->RegisterDataType(wxGRID_VALUE_CHOICEINT,
 | 
						|
                             new wxGridCellEnumRenderer,
 | 
						|
                             new wxGridCellEnumEditor);
 | 
						|
                             
 | 
						|
    wxString NativeLangChoice( wxString::Format("%s:%s,%s,%s,%s,%s",wxGRID_VALUE_CHOICEINT, 
 | 
						|
                            wxT("English"),
 | 
						|
                            wxT("French"),
 | 
						|
                            wxT("German"),
 | 
						|
                            wxT("Spanish"),
 | 
						|
                            wxT("Other") )); 
 | 
						|
#endif
 | 
						|
 | 
						|
    // Columns must match the sequence specified in SetColDef() calls
 | 
						|
    wxDbGridColInfo* cols =
 | 
						|
        new wxDbGridColInfo( 0,wxGRID_VALUE_STRING,wxT("Name"),
 | 
						|
        new wxDbGridColInfo( 1,wxGRID_VALUE_STRING,wxT("Address 1"),
 | 
						|
        new wxDbGridColInfo( 2,wxGRID_VALUE_STRING,wxT("Address 2"),
 | 
						|
        new wxDbGridColInfo( 3,wxGRID_VALUE_STRING,wxT("City"),
 | 
						|
        new wxDbGridColInfo( 4,wxGRID_VALUE_STRING,wxT("State"),
 | 
						|
        new wxDbGridColInfo( 5,wxGRID_VALUE_STRING,wxT("PostCode"),
 | 
						|
        new wxDbGridColInfo( 6,wxGRID_VALUE_STRING,wxT("Country"),
 | 
						|
        new wxDbGridColInfo( 7,wxGRID_VALUE_DBAUTO,wxT("Join Date"),
 | 
						|
        new wxDbGridColInfo( 8,wxGRID_VALUE_BOOL,  wxT("Developer"),
 | 
						|
        new wxDbGridColInfo( 9,wxGRID_VALUE_NUMBER,wxT("Contributions"),
 | 
						|
        new wxDbGridColInfo(10,wxGRID_VALUE_NUMBER,wxT("Lines Of Code"),
 | 
						|
#ifdef CHOICEINT
 | 
						|
        new wxDbGridColInfo(11,NativeLangChoice,   wxT("Native Language"),NULL))))))))))));
 | 
						|
#else        
 | 
						|
        new wxDbGridColInfo(11,wxGRID_VALUE_NUMBER,wxT("Native Language"),NULL))))))))))));
 | 
						|
#endif
 | 
						|
 | 
						|
    Ccontact *Contact = new Ccontact();
 | 
						|
    //wxGetApp().Contact
 | 
						|
 | 
						|
    if (!Contact)
 | 
						|
    {
 | 
						|
        wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"), wxT("Error..."), wxOK | wxICON_EXCLAMATION);
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!Contact->Open())
 | 
						|
    {
 | 
						|
        if (Contact->GetDb()->TableExists(CONTACT_TABLE_NAME, Contact->GetDb()->GetUsername(),
 | 
						|
                                          wxGetApp().DbConnectInf->GetDefaultDir()))
 | 
						|
        {
 | 
						|
            wxString tStr;
 | 
						|
            tStr.Printf(wxT("Unable to open the table '%s'.\n\n"),CONTACT_TABLE_NAME);
 | 
						|
            wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                         wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        }
 | 
						|
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    // Execute the following query using the cursor designated
 | 
						|
    // for full table query
 | 
						|
    Contact->SetRowMode(wxDbTable::WX_ROW_MODE_QUERY);
 | 
						|
 | 
						|
    if (!Contact->Query())
 | 
						|
    {
 | 
						|
        wxString tStr;
 | 
						|
        tStr = wxT("ODBC error during Query()\n\n");
 | 
						|
        wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__FILE__,__LINE__),
 | 
						|
                     wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    // No data has been read in from the database yet, so
 | 
						|
    // we need to initialize the data members to valid values
 | 
						|
    // so Fit() can correctly size the grid
 | 
						|
    Contact->Initialize();
 | 
						|
 | 
						|
    wxDbGridTableBase* db = new wxDbGridTableBase(Contact, cols, wxUSE_QUERY, TRUE);
 | 
						|
 | 
						|
    delete cols;
 | 
						|
 | 
						|
    grid->SetTable(db,TRUE);
 | 
						|
    grid->SetMargins(0, 0);
 | 
						|
 | 
						|
    grid->Fit();
 | 
						|
    wxSize size = grid->GetSize();
 | 
						|
    size.x += 10;
 | 
						|
    size.y += 10;
 | 
						|
    SetClientSize(size);
 | 
						|
    initialized = TRUE;
 | 
						|
    return TRUE;
 | 
						|
}  // DbGridFrame::Initialize()
 | 
						|
 | 
						|
#endif // #if wxUSE_NEW_GRID
 | 
						|
 | 
						|
/*
 | 
						|
    TEST CODE FOR TESTING THE wxDbCreateDataSource() FUNCTION
 | 
						|
 | 
						|
        int result = 0;
 | 
						|
        result = wxDbCreateDataSource(wxT("Microsoft Access Driver (*.mdb)"),wxT("GLT-TEST2"),wxT("GLT-Descrip"),FALSE,wxT(""),this);
 | 
						|
        if (!result)
 | 
						|
        {
 | 
						|
            // check for errors caused by ConfigDSN based functions
 | 
						|
            DWORD retcode = 0;
 | 
						|
            WORD cb;
 | 
						|
            wxChar errMsg[500+1];
 | 
						|
            errMsg[0] = wxT('\0');
 | 
						|
 | 
						|
            SQLInstallerError(1,&retcode,errMsg,500,&cb);
 | 
						|
 | 
						|
            wxMessageBox(wxT("FAILED creating data source"),wxT("FAILED"));
 | 
						|
        }
 | 
						|
        else
 | 
						|
            wxMessageBox(wxT("SUCCEEDED creating data source"),wxT("SUCCESS"));
 | 
						|
*/
 | 
						|
 | 
						|
 |