1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxWindows database demo app
4 // Author: George Tasker
8 // Copyright: (c) 1998 Remstar International, Inc.
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
15 This sample program demonstrates the cross-platform ODBC database classes
16 donated by the development team at Remstar International.
18 The table this sample is based on is developer contact table, and shows
19 some of the simple uses of the database classes wxDb and wxDbTable.
25 #pragma implementation "dbtest.h"
28 #include "wx/wxprec.h"
42 #include <stdio.h> /* Included strictly for reading the text file with the database parameters */
44 //#include <wx/db.h> /* Required in the file which will get the data source connection */
45 //#include <wx/dbtable.h> /* Has the wxDbTable object from which all data objects will inherit their data table functionality */
47 //extern wxDbList WXDLLEXPORT *PtrBegDbList; /* from db.cpp, used in getting back error results from db connections */
51 #include <wx/generic/gridctrl.h>
52 #include <wx/dbgrid.h>
57 #include "dbtest.h" /* Header file for this demonstration program */
58 #include "listdb.h" /* Code to support the "Lookup" button on the editor dialog */
60 IMPLEMENT_APP(DatabaseDemoApp
)
62 extern wxChar ListDB_Selection
[]; /* Used to return the first column value for the selected line from the listDB routines */
63 extern wxChar ListDB_Selection2
[]; /* Used to return the second column value for the selected line from the listDB routines */
67 #error Sample cannot be compiled unless setup.h has wxUSE_ODBC set to 1
71 bool DataTypeSupported(wxDb
*pDb
, SWORD datatype
)
73 wxDbSqlTypeInfo sqlTypeInfo
;
75 bool breakpoint
= FALSE
;
77 if (pDb
->GetDataTypeInfo(datatype
, sqlTypeInfo
))
82 } // GetDataTypesSupported();
86 void CheckSupportForAllDataTypes(wxDb
*pDb
)
88 wxLogMessage("\nThe following datatypes are supported by the\ndatabase you are currently connected to:");
90 if (DataTypeSupported(pDb
,SQL_C_BINARY
))
91 wxLogMessage("SQL_C_BINARY");
94 if (DataTypeSupported(pDb
,SQL_C_BIT
))
95 wxLogMessage("SQL_C_BIT");
98 if (DataTypeSupported(pDb
,SQL_C_BOOKMARK
))
99 wxLogMessage("SQL_C_BOOKMARK");
102 if (DataTypeSupported(pDb
,SQL_C_CHAR
))
103 wxLogMessage("SQL_C_CHAR");
106 if (DataTypeSupported(pDb
,SQL_C_DATE
))
107 wxLogMessage("SQL_C_DATE");
110 if (DataTypeSupported(pDb
,SQL_C_DEFAULT
))
111 wxLogMessage("SQL_C_DEFAULT");
114 if (DataTypeSupported(pDb
,SQL_C_DOUBLE
))
115 wxLogMessage("SQL_C_DOUBLE");
118 if (DataTypeSupported(pDb
,SQL_C_FLOAT
))
119 wxLogMessage("SQL_C_FLOAT");
122 if (DataTypeSupported(pDb
,SQL_C_GUID
))
123 wxLogMessage("SQL_C_GUID");
125 #ifdef SQL_C_INTERVAL_DAY
126 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_DAY
))
127 wxLogMessage("SQL_C_INTERVAL_DAY");
129 #ifdef SQL_C_INTERVAL_DAY_TO_HOUR
130 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_DAY_TO_HOUR
))
131 wxLogMessage("SQL_C_INTERVAL_DAY_TO_HOUR");
133 #ifdef SQL_C_INTERVAL_DAY_TO_MINUTE
134 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_DAY_TO_MINUTE
))
135 wxLogMessage("SQL_C_INTERVAL_DAY_TO_MINUTE");
137 #ifdef SQL_C_INTERVAL_DAY_TO_SECOND
138 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_DAY_TO_SECOND
))
139 wxLogMessage("SQL_C_INTERVAL_DAY_TO_SECOND");
141 #ifdef SQL_C_INTERVAL_HOUR
142 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_HOUR
))
143 wxLogMessage("SQL_C_INTERVAL_HOUR");
145 #ifdef SQL_C_INTERVAL_HOUR_TO_MINUTE
146 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_HOUR_TO_MINUTE
))
147 wxLogMessage("SQL_C_INTERVAL_HOUR_TO_MINUTE");
149 #ifdef SQL_C_INTERVAL_HOUR_TO_SECOND
150 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_HOUR_TO_SECOND
))
151 wxLogMessage("SQL_C_INTERVAL_HOUR_TO_SECOND");
153 #ifdef SQL_C_INTERVAL_MINUTE
154 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_MINUTE
))
155 wxLogMessage("SQL_C_INTERVAL_MINUTE");
157 #ifdef SQL_C_INTERVAL_MINUTE_TO_SECOND
158 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_MINUTE_TO_SECOND
))
159 wxLogMessage("SQL_C_INTERVAL_MINUTE_TO_SECOND");
161 #ifdef SQL_C_INTERVAL_MONTH
162 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_MONTH
))
163 wxLogMessage("SQL_C_INTERVAL_MONTH");
165 #ifdef SQL_C_INTERVAL_SECOND
166 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_SECOND
))
167 wxLogMessage("SQL_C_INTERVAL_SECOND");
169 #ifdef SQL_C_INTERVAL_YEAR
170 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_YEAR
))
171 wxLogMessage("SQL_C_INTERVAL_YEAR");
173 #ifdef SQL_C_INTERVAL_YEAR_TO_MONTH
174 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_YEAR_TO_MONTH
))
175 wxLogMessage("SQL_C_INTERVAL_YEAR_TO_MONTH");
178 if (DataTypeSupported(pDb
,SQL_C_LONG
))
179 wxLogMessage("SQL_C_LONG");
182 if (DataTypeSupported(pDb
,SQL_C_NUMERIC
))
183 wxLogMessage("SQL_C_NUMERIC");
186 if (DataTypeSupported(pDb
,SQL_C_SBIGINT
))
187 wxLogMessage("SQL_C_SBIGINT");
190 if (DataTypeSupported(pDb
,SQL_C_SHORT
))
191 wxLogMessage("SQL_C_SHORT");
194 if (DataTypeSupported(pDb
,SQL_C_SLONG
))
195 wxLogMessage("SQL_C_SLONG");
198 if (DataTypeSupported(pDb
,SQL_C_SSHORT
))
199 wxLogMessage("SQL_C_SSHORT");
201 #ifdef SQL_C_STINYINT
202 if (DataTypeSupported(pDb
,SQL_C_STINYINT
))
203 wxLogMessage("SQL_C_STINYINT");
206 if (DataTypeSupported(pDb
,SQL_C_TIME
))
207 wxLogMessage("SQL_C_TIME");
209 #ifdef SQL_C_TIMESTAMP
210 if (DataTypeSupported(pDb
,SQL_C_TIMESTAMP
))
211 wxLogMessage("SQL_C_TIMESTAMP");
214 if (DataTypeSupported(pDb
,SQL_C_TINYINT
))
215 wxLogMessage("SQL_C_TINYINT");
217 #ifdef SQL_C_TYPE_DATE
218 if (DataTypeSupported(pDb
,SQL_C_TYPE_DATE
))
219 wxLogMessage("SQL_C_TYPE_DATE");
221 #ifdef SQL_C_TYPE_TIME
222 if (DataTypeSupported(pDb
,SQL_C_TYPE_TIME
))
223 wxLogMessage("SQL_C_TYPE_TIME");
225 #ifdef SQL_C_TYPE_TIMESTAMP
226 if (DataTypeSupported(pDb
,SQL_C_TYPE_TIMESTAMP
))
227 wxLogMessage("SQL_C_TYPE_TIMESTAMP");
230 if (DataTypeSupported(pDb
,SQL_C_UBIGINT
))
231 wxLogMessage("SQL_C_UBIGINT");
234 if (DataTypeSupported(pDb
,SQL_C_ULONG
))
235 wxLogMessage("SQL_C_ULONG");
238 if (DataTypeSupported(pDb
,SQL_C_USHORT
))
239 wxLogMessage("SQL_C_USHORT");
241 #ifdef SQL_C_UTINYINT
242 if (DataTypeSupported(pDb
,SQL_C_UTINYINT
))
243 wxLogMessage("SQL_C_UTINYINT");
245 #ifdef SQL_C_VARBOOKMARK
246 if (DataTypeSupported(pDb
,SQL_C_VARBOOKMARK
))
247 wxLogMessage("SQL_C_VARBOOKMARK");
250 // Extended SQL types
252 if (DataTypeSupported(pDb
,SQL_DATE
))
253 wxLogMessage("SQL_DATE");
256 if (DataTypeSupported(pDb
,SQL_INTERVAL
))
257 wxLogMessage("SQL_INTERVAL");
260 if (DataTypeSupported(pDb
,SQL_TIME
))
261 wxLogMessage("SQL_TIME");
264 if (DataTypeSupported(pDb
,SQL_TIMESTAMP
))
265 wxLogMessage("SQL_TIMESTAMP");
267 #ifdef SQL_LONGVARCHAR
268 if (DataTypeSupported(pDb
,SQL_LONGVARCHAR
))
269 wxLogMessage("SQL_LONGVARCHAR");
272 if (DataTypeSupported(pDb
,SQL_BINARY
))
273 wxLogMessage("SQL_BINARY");
276 if (DataTypeSupported(pDb
,SQL_VARBINARY
))
277 wxLogMessage("SQL_VARBINARY");
279 #ifdef SQL_LONGVARBINARY
280 if (DataTypeSupported(pDb
,SQL_LONGVARBINARY
))
281 wxLogMessage("SQL_LONGVARBINARY");
284 if (DataTypeSupported(pDb
,SQL_BIGINT
))
285 wxLogMessage("SQL_BIGINT");
288 if (DataTypeSupported(pDb
,SQL_TINYINT
))
289 wxLogMessage("SQL_TINYINT");
292 if (DataTypeSupported(pDb
,SQL_BIT
))
293 wxLogMessage("SQL_BIT");
296 if (DataTypeSupported(pDb
,SQL_GUID
))
297 wxLogMessage("SQL_GUID");
301 if (DataTypeSupported(pDb
,SQL_CHAR
))
302 wxLogMessage("SQL_CHAR");
305 if (DataTypeSupported(pDb
,SQL_INTEGER
))
306 wxLogMessage("SQL_INTEGER");
309 if (DataTypeSupported(pDb
,SQL_SMALLINT
))
310 wxLogMessage("SQL_SMALLINT");
313 if (DataTypeSupported(pDb
,SQL_REAL
))
314 wxLogMessage("SQL_REAL");
317 if (DataTypeSupported(pDb
,SQL_DOUBLE
))
318 wxLogMessage("SQL_DOUBLE");
321 if (DataTypeSupported(pDb
,SQL_NUMERIC
))
322 wxLogMessage("SQL_NUMERIC");
325 if (DataTypeSupported(pDb
,SQL_DATE
))
326 wxLogMessage("SQL_DATE");
329 if (DataTypeSupported(pDb
,SQL_TIME
))
330 wxLogMessage("SQL_TIME");
333 if (DataTypeSupported(pDb
,SQL_TIMESTAMP
))
334 wxLogMessage("SQL_TIMESTAMP");
337 if (DataTypeSupported(pDb
,SQL_VARCHAR
))
338 wxLogMessage("SQL_VARCHAR");
343 if (DataTypeSupported(pDb
,SQL_C_TCHAR
))
344 wxLogMessage("SQL_C_TCHAR (Unicode support is possible)");
348 } // CheckSupportForAllDataTypes()
351 bool DatabaseDemoApp::OnInit()
356 // Create the main frame window
357 DemoFrame
= new DatabaseDemoFrame(NULL
, wxT("wxWindows Database Demo"), wxPoint(50, 50), wxSize(537, 480));
360 DemoFrame
->SetIcon(wxICON(db
));
363 wxMenu
*file_menu
= new wxMenu
;
364 file_menu
->Append(FILE_CREATE
, wxT("&Create CONTACT table"));
365 file_menu
->Append(FILE_RECREATE_TABLE
, wxT("&Recreate CONTACT table"));
366 file_menu
->Append(FILE_RECREATE_INDEXES
, wxT("&Recreate CONTACT indexes"));
368 file_menu
->Append(FILE_DBGRID_TABLE
, wxT("&Open DB Grid example"));
370 file_menu
->Append(FILE_EXIT
, wxT("E&xit"));
372 wxMenu
*edit_menu
= new wxMenu
;
373 edit_menu
->Append(EDIT_PARAMETERS
, wxT("&Parameters..."));
375 wxMenu
*help_menu
= new wxMenu
;
376 help_menu
->Append(HELP_ABOUT
, wxT("&About"));
378 wxMenuBar
*menu_bar
= new wxMenuBar
;
379 menu_bar
->Append(file_menu
, wxT("&File"));
380 menu_bar
->Append(edit_menu
, wxT("&Edit"));
381 menu_bar
->Append(help_menu
, wxT("&Help"));
382 DemoFrame
->SetMenuBar(menu_bar
);
384 params
.ODBCSource
[0] = 0;
385 params
.UserName
[0] = 0;
386 params
.Password
[0] = 0;
387 params
.DirPath
[0] = 0;
390 DemoFrame
->Show(TRUE
);
392 // Passing NULL for the SQL environment handle causes
393 // the wxDbConnectInf constructor to obtain a handle
396 // WARNING: Be certain that you do not free this handle
397 // directly with SQLFreeEnv(). Use either the
398 // method ::FreeHenv() or delete the DbConnectInf.
399 DbConnectInf
= new wxDbConnectInf(NULL
, params
.ODBCSource
, params
.UserName
,
400 params
.Password
, params
.DirPath
);
402 if (!DbConnectInf
|| !DbConnectInf
->GetHenv())
404 wxMessageBox(wxT("Unable to define data source connection info."), wxT("DB CONNECTION ERROR..."),wxOK
| wxICON_EXCLAMATION
);
405 wxDELETE(DbConnectInf
);
408 if (!ReadParamFile(params
))
409 DemoFrame
->BuildParameterDialog(NULL
);
411 if (!wxStrlen(params
.ODBCSource
))
413 wxDELETE(DbConnectInf
);
417 DbConnectInf
->SetDsn(params
.ODBCSource
);
418 DbConnectInf
->SetUserID(params
.UserName
);
419 DbConnectInf
->SetPassword(params
.Password
);
420 DbConnectInf
->SetDefaultDir(params
.DirPath
);
422 READONLY_DB
= wxDbGetConnection(DbConnectInf
);
423 if (READONLY_DB
== 0)
425 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
);
426 DemoFrame
->BuildParameterDialog(NULL
);
427 wxDELETE(DbConnectInf
);
428 wxMessageBox(wxT("Now exiting program.\n\nRestart program to try any new settings."),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
432 DemoFrame
->BuildEditorDialog();
435 DemoFrame
->Refresh();
438 } // DatabaseDemoApp::OnInit()
441 bool DatabaseDemoApp::ReadParamFile(Cparameters
¶ms
)
444 if ((paramFile
= fopen(PARAM_FILENAME
, wxT("r"))) == NULL
)
447 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
);
448 wxMessageBox(tStr
,wxT("File I/O Error..."),wxOK
| wxICON_EXCLAMATION
);
453 wxChar buffer
[1000+1];
454 fgets(buffer
, sizeof(params
.ODBCSource
), paramFile
);
455 buffer
[wxStrlen(buffer
)-1] = wxT('\0');
456 wxStrcpy(params
.ODBCSource
,buffer
);
458 fgets(buffer
, sizeof(params
.UserName
), paramFile
);
459 buffer
[wxStrlen(buffer
)-1] = wxT('\0');
460 wxStrcpy(params
.UserName
,buffer
);
462 fgets(buffer
, sizeof(params
.Password
), paramFile
);
463 buffer
[wxStrlen(buffer
)-1] = wxT('\0');
464 wxStrcpy(params
.Password
,buffer
);
466 fgets(buffer
, sizeof(params
.DirPath
), paramFile
);
467 buffer
[wxStrlen(buffer
)-1] = wxT('\0');
468 wxStrcpy(params
.DirPath
,buffer
);
473 } // DatabaseDemoApp::ReadParamFile()
476 bool DatabaseDemoApp::WriteParamFile(Cparameters
¶ms
)
479 if ((paramFile
= fopen(PARAM_FILENAME
, wxT("wt"))) == NULL
)
482 tStr
.Printf(wxT("Unable to write/overwrite '%s'."),PARAM_FILENAME
);
483 wxMessageBox(tStr
,wxT("File I/O Error..."),wxOK
| wxICON_EXCLAMATION
);
487 fputs(wxGetApp().params
.ODBCSource
, paramFile
);
488 fputc(wxT('\n'), paramFile
);
489 fputs(wxGetApp().params
.UserName
, paramFile
);
490 fputc(wxT('\n'), paramFile
);
491 fputs(wxGetApp().params
.Password
, paramFile
);
492 fputc(wxT('\n'), paramFile
);
493 fputs(wxGetApp().params
.DirPath
, paramFile
);
494 fputc(wxT('\n'), paramFile
);
498 } // DatabaseDemoApp::WriteParamFile()
501 void DatabaseDemoApp::CreateDataTable(bool recreate
)
505 Ok
= (wxMessageBox(wxT("Any data currently residing in the table will be erased.\n\nAre you sure?"),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
514 Contact
->GetDb()->RollbackTrans(); // Make sure the current cursor is in a known/stable state
516 if (!Contact
->CreateTable(recreate
))
520 tStr
= wxT("Error creating CONTACTS table.\nTable was not created.\n\n");
521 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),Contact
->GetDb(),__FILE__
,__LINE__
),
522 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
528 if (!Contact
->CreateIndexes(recreate
))
532 tStr
= wxT("Error creating CONTACTS indexes.\nIndexes will be unavailable.\n\n");
533 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),Contact
->GetDb(),__FILE__
,__LINE__
),
534 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
543 wxMessageBox(wxT("Table and index(es) were successfully created."),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
544 } // DatabaseDemoApp::CreateDataTable()
547 BEGIN_EVENT_TABLE(DatabaseDemoFrame
, wxFrame
)
548 EVT_MENU(FILE_CREATE
, DatabaseDemoFrame::OnCreate
)
549 EVT_MENU(FILE_RECREATE_TABLE
, DatabaseDemoFrame::OnRecreateTable
)
550 EVT_MENU(FILE_RECREATE_INDEXES
, DatabaseDemoFrame::OnRecreateIndexes
)
552 EVT_MENU(FILE_DBGRID_TABLE
, DatabaseDemoFrame::OnDbGridTable
)
554 EVT_MENU(FILE_EXIT
, DatabaseDemoFrame::OnExit
)
555 EVT_MENU(EDIT_PARAMETERS
, DatabaseDemoFrame::OnEditParameters
)
556 EVT_MENU(HELP_ABOUT
, DatabaseDemoFrame::OnAbout
)
557 EVT_CLOSE(DatabaseDemoFrame::OnCloseWindow
)
561 // DatabaseDemoFrame constructor
562 DatabaseDemoFrame::DatabaseDemoFrame(wxFrame
*frame
, const wxString
& title
,
563 const wxPoint
& pos
, const wxSize
& size
):
564 wxFrame(frame
, -1, title
, pos
, size
)
566 // Put any code in necessary for initializing the main frame here
570 delete wxLog::SetActiveTarget(new wxLogStderr
);
572 } // DatabaseDemoFrame constructor
574 DatabaseDemoFrame::~DatabaseDemoFrame()
576 delete wxLog::SetActiveTarget(NULL
);
577 } // DatabaseDemoFrame destructor
580 void DatabaseDemoFrame::OnCreate(wxCommandEvent
& event
)
582 wxGetApp().CreateDataTable(FALSE
);
583 } // DatabaseDemoFrame::OnCreate()
586 void DatabaseDemoFrame::OnRecreateTable(wxCommandEvent
& event
)
588 wxGetApp().CreateDataTable(TRUE
);
589 } // DatabaseDemoFrame::OnRecreate()
592 void DatabaseDemoFrame::OnRecreateIndexes(wxCommandEvent
& event
)
594 wxGetApp().Contact
->GetDb()->RollbackTrans(); // Make sure the current cursor is in a known/stable state
596 if (!wxGetApp().Contact
->CreateIndexes(TRUE
))
601 tStr
= wxT("Error creating CONTACTS indexes.\nNew indexes will be unavailable.\n\n");
602 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
603 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
607 wxMessageBox(wxT("Index(es) were successfully recreated."),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
609 } // DatabaseDemoFrame::OnRecreateIndexes()
613 void DatabaseDemoFrame::OnDbGridTable(wxCommandEvent
& )
615 DbGridFrame
*frame
= new DbGridFrame(this);
616 if (frame
->Initialize())
623 void DatabaseDemoFrame::OnExit(wxCommandEvent
& event
)
626 } // DatabaseDemoFrame::OnExit()
629 void DatabaseDemoFrame::OnEditParameters(wxCommandEvent
& event
)
631 if ((pEditorDlg
->mode
!= mCreate
) && (pEditorDlg
->mode
!= mEdit
))
632 BuildParameterDialog(this);
634 wxMessageBox(wxT("Cannot change database parameters while creating or editing a record"),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
635 } // DatabaseDemoFrame::OnEditParameters()
638 void DatabaseDemoFrame::OnAbout(wxCommandEvent
& event
)
640 wxMessageBox(wxT("wxWindows sample program for database classes\n\nContributed on 27 July 1998"),wxT("About..."),wxOK
| wxICON_INFORMATION
);
641 } // DatabaseDemoFrame::OnAbout()
644 // Put any additional checking necessary to make certain it is alright
645 // to close the program here that is not done elsewhere
646 void DatabaseDemoFrame::OnCloseWindow(wxCloseEvent
& event
)
649 if (pEditorDlg
&& pEditorDlg
->Close())
660 wxDELETE(wxGetApp().Contact
);
662 // This function will close all the connections to the database that have been
663 // previously cached.
664 wxDbCloseConnections();
666 // Deletion of the wxDbConnectInf instance must be the LAST thing done that
667 // has anything to do with the database. Deleting this before disconnecting,
668 // freeing/closing connections, etc will result in a crash!
669 wxDELETE(wxGetApp().DbConnectInf
);
673 } // DatabaseDemoFrame::OnCloseWindow()
676 void DatabaseDemoFrame::BuildEditorDialog()
679 pEditorDlg
= new CeditorDlg(this);
682 pEditorDlg
->Initialize();
683 if (!pEditorDlg
->initialized
)
687 wxMessageBox(wxT("Unable to initialize the editor dialog for some reason"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
693 wxMessageBox(wxT("Unable to create the editor dialog for some reason"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
696 } // DatabaseDemoFrame::BuildEditorDialog()
699 void DatabaseDemoFrame::BuildParameterDialog(wxWindow
*parent
)
701 pParamDlg
= new CparameterDlg(parent
);
704 wxMessageBox(wxT("Unable to create the parameter dialog for some reason"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
705 } // DatabaseDemoFrame::BuildParameterDialog()
709 * Constructor note: If no wxDb object is passed in, a new connection to the database
710 * is created for this instance of Ccontact. This can be a slow process depending
711 * on the database engine being used, and some database engines have a limit on the
712 * number of connections (either hard limits, or license restricted) so care should
713 * be used to use as few connections as is necessary.
715 * IMPORTANT: Objects which share a wxDb pointer are ALL acted upon whenever a member
716 * function of pDb is called (i.e. CommitTrans() or RollbackTrans(), so if modifying
717 * or creating a table objects which use the same pDb, know that all the objects
718 * will be committed or rolled back when any of the objects has this function call made.
720 Ccontact::Ccontact (wxDb
*pwxDb
) : wxDbTable(pwxDb
? pwxDb
: wxDbGetConnection(wxGetApp().DbConnectInf
),
721 CONTACT_TABLE_NAME
, CONTACT_NO_COLS
, wxT(""),
722 !wxDB_QUERY_ONLY
, wxGetApp().DbConnectInf
->GetDefaultDir())
724 // This is used to represent whether the database connection should be released
725 // when this instance of the object is deleted. If using the same connection
726 // for multiple instance of database objects, then the connection should only be
727 // released when the last database instance using the connection is deleted
731 GetDb()->SetSqlLogging(sqlLogON
);
735 } // Ccontact Constructor
738 void Ccontact::Initialize()
747 JoinDate
.year
= 1980;
753 JoinDate
.fraction
= 0;
754 NativeLanguage
= langENGLISH
;
758 } // Ccontact::Initialize
761 Ccontact::~Ccontact()
765 if (!wxDbFreeConnection(GetDb()))
768 tStr
= wxT("Unable to Free the Ccontact data table handle\n\n");
770 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
771 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
774 } // Ccontract destructor
778 * Handles setting up all the connections for the interface from the wxDbTable
779 * functions to interface to the data structure used to store records in
780 * memory, and for all the column definitions that define the table structure
782 void Ccontact::SetupColumns()
784 // NOTE: Columns now are 8 character names, as that is all dBase can support. Longer
785 // names can be used for other database engines
786 SetColDefs ( 0,wxT("NAME"), DB_DATA_TYPE_VARCHAR
, Name
, SQL_C_CHAR
, sizeof(Name
), TRUE
, TRUE
); // Primary index
787 SetColDefs ( 1,wxT("ADDRESS1"), DB_DATA_TYPE_VARCHAR
, Addr1
, SQL_C_CHAR
, sizeof(Addr1
), FALSE
,TRUE
);
788 SetColDefs ( 2,wxT("ADDRESS2"), DB_DATA_TYPE_VARCHAR
, Addr2
, SQL_C_CHAR
, sizeof(Addr2
), FALSE
,TRUE
);
789 SetColDefs ( 3,wxT("CITY"), DB_DATA_TYPE_VARCHAR
, City
, SQL_C_CHAR
, sizeof(City
), FALSE
,TRUE
);
790 SetColDefs ( 4,wxT("STATE"), DB_DATA_TYPE_VARCHAR
, State
, SQL_C_CHAR
, sizeof(State
), FALSE
,TRUE
);
791 SetColDefs ( 5,wxT("POSTCODE"), DB_DATA_TYPE_VARCHAR
, PostalCode
, SQL_C_CHAR
, sizeof(PostalCode
), FALSE
,TRUE
);
792 SetColDefs ( 6,wxT("COUNTRY"), DB_DATA_TYPE_VARCHAR
, Country
, SQL_C_CHAR
, sizeof(Country
), FALSE
,TRUE
);
793 SetColDefs ( 7,wxT("JOINDATE"), DB_DATA_TYPE_DATE
, &JoinDate
, SQL_C_TIMESTAMP
, sizeof(JoinDate
), FALSE
,TRUE
);
794 SetColDefs ( 8,wxT("IS_DEV"), DB_DATA_TYPE_INTEGER
, &IsDeveloper
, SQL_C_BOOLEAN(IsDeveloper
), sizeof(IsDeveloper
), FALSE
,TRUE
);
795 SetColDefs ( 9,wxT("CONTRIBS"), DB_DATA_TYPE_INTEGER
, &Contributions
, SQL_C_UTINYINT
, sizeof(Contributions
), FALSE
,TRUE
);
796 SetColDefs (10,wxT("LINE_CNT"), DB_DATA_TYPE_INTEGER
, &LinesOfCode
, SQL_C_ULONG
, sizeof(LinesOfCode
), FALSE
,TRUE
);
797 SetColDefs (11,wxT("LANGUAGE"), DB_DATA_TYPE_INTEGER
, &NativeLanguage
, SQL_C_ENUM
, sizeof(NativeLanguage
), FALSE
,TRUE
);
798 #if wxODBC_BLOB_EXPERIMENT > 0
799 SetColDefs (12,wxT("PICTURE"), DB_DATA_TYPE_BLOB
, Picture
, SQL_LONGVARBINARY
, sizeof(Picture
), FALSE
,TRUE
);
801 } // Ccontact::SetupColumns
804 bool Ccontact::CreateIndexes(bool recreate
)
806 // This index could easily be accomplished with an "orderBy" clause,
807 // but is done to show how to construct a non-primary index.
809 wxDbIdxDef idxDef
[2];
813 wxStrcpy(idxDef
[0].ColName
, "IS_DEV");
814 idxDef
[0].Ascending
= TRUE
;
816 wxStrcpy(idxDef
[1].ColName
, "NAME");
817 idxDef
[1].Ascending
= TRUE
;
819 indexName
= GetTableName();
820 indexName
+= "_IDX1";
821 Ok
= CreateIndex(indexName
.c_str(), TRUE
, 2, idxDef
, recreate
);
824 } // Ccontact::CreateIndexes()
828 * Having a function to do a query on the primary key (and possibly others) is
829 * very efficient and tighter coding so that it is available where ever the object
830 * is. Great for use with multiple tables when not using views or outer joins
832 bool Ccontact::FetchByName(const wxString
&name
)
834 whereStr
.Printf(wxT("NAME = '%s'"),name
.c_str());
835 SetWhereClause(whereStr
.c_str());
836 SetOrderByClause(wxT(""));
844 } // Ccontact::FetchByName()
849 * ************* DIALOGS ***************
854 /* CeditorDlg constructor
856 * Creates the dialog used for creating/editing/deleting/copying a Ccontact object.
857 * This dialog actually is drawn in the main frame of the program
859 * An instance of Ccontact is created - "Contact" - which is used to hold the Ccontact
860 * object that is currently being worked with.
863 BEGIN_EVENT_TABLE(CeditorDlg
, wxPanel
)
864 EVT_BUTTON(-1, CeditorDlg::OnButton
)
865 EVT_CLOSE(CeditorDlg::OnCloseWindow
)
868 CeditorDlg::CeditorDlg(wxWindow
*parent
) : wxPanel (parent
, 0, 0, 537, 480)
870 // Since the ::OnCommand() function is overridden, this prevents the widget
871 // detection in ::OnCommand() until all widgets have been initialized to prevent
872 // uninitialized pointers from crashing the program
873 widgetPtrsSet
= FALSE
;
880 } // CeditorDlg constructor
883 void CeditorDlg::OnCloseWindow(wxCloseEvent
& event
)
886 if ((mode
!= mCreate
) && (mode
!= mEdit
))
892 wxMessageBox(wxT("Must finish processing the current record being created/modified before exiting"),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
895 } // CeditorDlg::OnCloseWindow()
898 void CeditorDlg::OnButton(wxCommandEvent
&event
)
900 wxWindow
*win
= (wxWindow
*) event
.GetEventObject();
901 OnCommand( *win
, event
);
902 } // CeditorDlg::OnButton()
905 void CeditorDlg::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
909 widgetName
= win
.GetName();
914 if (widgetName
== pCreateBtn
->GetName())
916 wxGetApp().Contact
->Initialize();
919 pNameTxt
->SetValue(wxT(""));
920 pNameTxt
->SetFocus();
924 if (widgetName
== pEditBtn
->GetName())
926 saveName
= wxGetApp().Contact
->Name
;
928 pNameTxt
->SetFocus();
932 if (widgetName
== pCopyBtn
->GetName())
935 pNameTxt
->SetValue(wxT(""));
936 pNameTxt
->SetFocus();
940 if (widgetName
== pDeleteBtn
->GetName())
942 bool Ok
= (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
947 if (Ok
&& wxGetApp().Contact
->Delete())
949 // NOTE: Deletions are not finalized until a CommitTrans() is performed.
950 // If the commit were not performed, the program will continue to
951 // show the table contents as if they were deleted until this instance
952 // of Ccontact is deleted. If the Commit wasn't performed, the
953 // database will automatically Rollback the changes when the database
954 // connection is terminated
955 wxGetApp().Contact
->GetDb()->CommitTrans();
957 // Try to get the row that followed the just deleted row in the orderBy sequence
960 // There was now row (in sequence) after the just deleted row, so get the
961 // row which preceded the just deleted row
964 // There are now no rows remaining, so clear the dialog widgets
965 wxGetApp().Contact
->Initialize();
969 SetMode(mode
); // force reset of button enable/disable
973 wxGetApp().Contact
->GetDb()->RollbackTrans();
979 if (widgetName
== pSaveBtn
->GetName())
985 if (widgetName
== pCancelBtn
->GetName())
987 bool Ok
= (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
992 if (saveName
.IsEmpty())
994 wxGetApp().Contact
->Initialize();
1001 // Requery previous record
1002 if (wxGetApp().Contact
->FetchByName(saveName
))
1010 // Previous record not available, retrieve first record in table
1011 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1012 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1014 wxGetApp().Contact
->whereStr
= wxT("NAME = (SELECT MIN(NAME) FROM ");
1015 wxGetApp().Contact
->whereStr
+= wxGetApp().Contact
->GetTableName();
1016 wxGetApp().Contact
->whereStr
+= wxT(")");
1017 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
.c_str());
1020 wxGetApp().Contact
->SetWhereClause(wxT(""));
1022 if (!wxGetApp().Contact
->Query())
1025 tStr
= wxT("ODBC error during Query()\n\n");
1026 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
1027 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1032 if (wxGetApp().Contact
->GetNext()) // Successfully read first record
1038 // No contacts are available, clear dialog
1039 wxGetApp().Contact
->Initialize();
1045 if (widgetName
== pPrevBtn
->GetName())
1052 if (widgetName
== pNextBtn
->GetName())
1059 if (widgetName
== pQueryBtn
->GetName())
1061 // Display the query dialog box
1062 wxChar qryWhere
[DB_MAX_WHERE_CLAUSE_LEN
+1];
1063 wxStrcpy(qryWhere
, (const wxChar
*) wxGetApp().Contact
->qryWhereStr
);
1064 wxChar
*tblName
[] = {(wxChar
*)CONTACT_TABLE_NAME
, 0};
1065 new CqueryDlg(GetParent(), wxGetApp().Contact
->GetDb(), tblName
, qryWhere
);
1067 // Query the first record in the new record set and
1068 // display it, if the query string has changed.
1069 if (wxStrcmp(qryWhere
, (const wxChar
*) wxGetApp().Contact
->qryWhereStr
))
1071 wxGetApp().Contact
->whereStr
.Empty();
1072 wxGetApp().Contact
->SetOrderByClause("NAME");
1074 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1075 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1077 wxGetApp().Contact
->whereStr
= wxT("NAME = (SELECT MIN(NAME) FROM ");
1078 wxGetApp().Contact
->whereStr
+= CONTACT_TABLE_NAME
;
1081 // Append the query where string (if there is one)
1082 wxGetApp().Contact
->qryWhereStr
= qryWhere
;
1083 if (wxStrlen(qryWhere
))
1085 wxGetApp().Contact
->whereStr
+= wxT(" WHERE ");
1086 wxGetApp().Contact
->whereStr
+= wxGetApp().Contact
->qryWhereStr
;
1088 // Close the expression with a right paren
1089 wxGetApp().Contact
->whereStr
+= wxT(")");
1090 // Requery the table
1091 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
.c_str());
1092 if (!wxGetApp().Contact
->Query())
1095 tStr
= wxT("ODBC error during Query()\n\n");
1096 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
1097 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1101 // Display the first record from the query set
1102 if (!wxGetApp().Contact
->GetNext())
1103 wxGetApp().Contact
->Initialize();
1107 // Enable/Disable the reset button
1108 pResetBtn
->Enable(!wxGetApp().Contact
->qryWhereStr
.IsEmpty());
1114 if (widgetName
== pResetBtn
->GetName())
1116 // Clear the additional where criteria established by the query feature
1117 wxGetApp().Contact
->qryWhereStr
= wxT("");
1118 wxGetApp().Contact
->SetOrderByClause(wxT("NAME"));
1120 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1121 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1123 wxGetApp().Contact
->whereStr
= wxT("NAME = (SELECT MIN(NAME) FROM ");
1124 wxGetApp().Contact
->whereStr
+= CONTACT_TABLE_NAME
;
1125 wxGetApp().Contact
->whereStr
+= wxT(")");
1128 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
.c_str());
1129 if (!wxGetApp().Contact
->Query())
1132 tStr
= wxT("ODBC error during Query()\n\n");
1133 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
1134 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1137 if (!wxGetApp().Contact
->GetNext())
1138 wxGetApp().Contact
->Initialize();
1140 pResetBtn
->Enable(FALSE
);
1146 if (widgetName
== pNameListBtn
->GetName())
1148 new ClookUpDlg(/* wxWindow *parent */ this,
1149 /* wxChar *windowTitle */ wxT("Select contact name"),
1150 /* wxChar *tableName */ (wxChar
*) CONTACT_TABLE_NAME
,
1151 /* wxChar *dispCol1 */ wxT("NAME"),
1152 /* wxChar *dispCol2 */ wxT("JOINDATE"),
1153 /* wxChar *where */ wxT(""),
1154 /* wxChar *orderBy */ wxT("NAME"),
1155 /* wxDb *pDb */ wxGetApp().READONLY_DB
,
1156 /* const wxString &defDir */ wxGetApp().DbConnectInf
->GetDefaultDir(),
1157 /* bool distinctValues */ TRUE
);
1159 if (ListDB_Selection
&& wxStrlen(ListDB_Selection
))
1161 wxString w
= wxT("NAME = '");
1162 w
+= ListDB_Selection
;
1170 if (widgetName
== pDataTypesBtn
->GetName())
1172 CheckSupportForAllDataTypes(wxGetApp().READONLY_DB
);
1173 wxMessageBox("Support datatypes was dumped to stdout.");
1175 } // Data types Button
1177 if (widgetName
== pDbDiagsBtn
->GetName())
1179 DisplayDbDiagnostics(wxGetApp().READONLY_DB
);
1180 wxMessageBox("Diagnostics info was dumped to stdout.");
1184 if (widgetName
== pCatalogBtn
->GetName())
1186 if (wxGetApp().Contact
->GetDb()->Catalog("","catalog.txt"))
1187 wxMessageBox("The file 'catalog.txt' was created.");
1189 wxMessageBox("Creation of the file 'catalog.txt' was failed.");
1193 } // CeditorDlg::OnCommand()
1196 bool CeditorDlg::Initialize()
1198 // Create the data structure and a new database connection.
1199 // (As there is not a pDb being passed in the constructor, a new database
1200 // connection is created)
1201 wxGetApp().Contact
= new Ccontact();
1203 if (!wxGetApp().Contact
)
1205 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
1209 // Check if the table exists or not. If it doesn't, ask the user if they want to
1210 // create the table. Continue trying to create the table until it exists, or user aborts
1211 while (!wxGetApp().Contact
->GetDb()->TableExists((wxChar
*)CONTACT_TABLE_NAME
,
1212 wxGetApp().DbConnectInf
->GetUserID(),
1213 wxGetApp().DbConnectInf
->GetDefaultDir()))
1216 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
);
1217 bool createTable
= (wxMessageBox(tStr
.c_str(),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
1225 wxGetApp().CreateDataTable(FALSE
);
1228 // Tables must be "opened" before anything other than creating/deleting table can be done
1229 if (!wxGetApp().Contact
->Open())
1231 // Table does exist, or there was some problem opening it. Currently this should
1232 // never fail, except in the case of the table not exisiting or the current
1233 // user has insufficent privileges to access the table
1235 // This code is experimenting with a new function that will hopefully be available
1236 // in the 2.4 release. This check will determine whether the open failing was due
1237 // to the table not existing, or the users privileges being insufficient to
1239 if (!wxGetApp().Contact
->GetDb()->TablePrivileges(CONTACT_TABLE_NAME
, wxT("SELECT"),
1240 wxGetApp().Contact
->GetDb()->GetUsername(),
1241 wxGetApp().Contact
->GetDb()->GetUsername(),
1242 wxGetApp().DbConnectInf
->GetDefaultDir()))
1245 tStr
.Printf(wxT("Unable to open the table '%s' (likely due to\ninsufficient privileges of the logged in user).\n\n"),CONTACT_TABLE_NAME
);
1247 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
1248 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1252 if (!wxGetApp().Contact
->GetDb()->TableExists(CONTACT_TABLE_NAME
,
1253 wxGetApp().Contact
->GetDb()->GetUsername(),
1254 wxGetApp().DbConnectInf
->GetDefaultDir()))
1257 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
);
1258 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
1259 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1267 (void)new wxStaticBox(this, EDITOR_DIALOG_FN_GROUP
, wxT(""), wxPoint(15, 1), wxSize(497, 69), 0, wxT("FunctionGrp"));
1268 (void)new wxStaticBox(this, EDITOR_DIALOG_SEARCH_GROUP
, wxT(""), wxPoint(417, 1), wxSize(95, 242), 0, wxT("SearchGrp"));
1270 pCreateBtn
= new wxButton(this, EDITOR_DIALOG_CREATE
, wxT("&Create"), wxPoint( 25, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CreateBtn"));
1271 pEditBtn
= new wxButton(this, EDITOR_DIALOG_EDIT
, wxT("&Edit"), wxPoint(102, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("EditBtn"));
1272 pDeleteBtn
= new wxButton(this, EDITOR_DIALOG_DELETE
, wxT("&Delete"), wxPoint(179, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("DeleteBtn"));
1273 pCopyBtn
= new wxButton(this, EDITOR_DIALOG_COPY
, wxT("Cop&y"), wxPoint(256, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CopyBtn"));
1274 pSaveBtn
= new wxButton(this, EDITOR_DIALOG_SAVE
, wxT("&Save"), wxPoint(333, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("SaveBtn"));
1275 pCancelBtn
= new wxButton(this, EDITOR_DIALOG_CANCEL
, wxT("C&ancel"), wxPoint(430, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CancelBtn"));
1276 pPrevBtn
= new wxButton(this, EDITOR_DIALOG_PREV
, wxT("<< &Prev"), wxPoint(430, 81), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("PrevBtn"));
1277 pNextBtn
= new wxButton(this, EDITOR_DIALOG_NEXT
, wxT("&Next >>"), wxPoint(430, 121), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("NextBtn"));
1278 pQueryBtn
= new wxButton(this, EDITOR_DIALOG_QUERY
, wxT("&Query"), wxPoint(430, 161), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("QueryBtn"));
1279 pResetBtn
= new wxButton(this, EDITOR_DIALOG_RESET
, wxT("&Reset"), wxPoint(430, 200), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("ResetBtn"));
1280 pNameMsg
= new wxStaticText(this, EDITOR_DIALOG_NAME_MSG
, wxT("Name:"), wxPoint( 17, 80), wxSize( -1, -1), 0, wxT("NameMsg"));
1281 pNameTxt
= new wxTextCtrl(this, EDITOR_DIALOG_NAME_TEXT
, wxT(""), wxPoint( 17, 97), wxSize(308, 25), 0, wxDefaultValidator
, wxT("NameTxt"));
1282 pNameListBtn
= new wxButton(this, EDITOR_DIALOG_LOOKUP
, wxT("&Lookup"), wxPoint(333, 97), wxSize( 70, 24), 0, wxDefaultValidator
, wxT("LookupBtn"));
1283 pAddress1Msg
= new wxStaticText(this, EDITOR_DIALOG_ADDRESS1_MSG
, wxT("Address:"), wxPoint( 17, 130), wxSize( -1, -1), 0, wxT("Address1Msg"));
1284 pAddress1Txt
= new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT
, wxT(""), wxPoint( 17, 147), wxSize(308, 25), 0, wxDefaultValidator
, wxT("Address1Txt"));
1285 pAddress2Msg
= new wxStaticText(this, EDITOR_DIALOG_ADDRESS2_MSG
, wxT("Address:"), wxPoint( 17, 180), wxSize( -1, -1), 0, wxT("Address2Msg"));
1286 pAddress2Txt
= new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT
, wxT(""), wxPoint( 17, 197), wxSize(308, 25), 0, wxDefaultValidator
, wxT("Address2Txt"));
1287 pCityMsg
= new wxStaticText(this, EDITOR_DIALOG_CITY_MSG
, wxT("City:"), wxPoint( 17, 230), wxSize( -1, -1), 0, wxT("CityMsg"));
1288 pCityTxt
= new wxTextCtrl(this, EDITOR_DIALOG_CITY_TEXT
, wxT(""), wxPoint( 17, 247), wxSize(225, 25), 0, wxDefaultValidator
, wxT("CityTxt"));
1289 pStateMsg
= new wxStaticText(this, EDITOR_DIALOG_STATE_MSG
, wxT("State:"), wxPoint(250, 230), wxSize( -1, -1), 0, wxT("StateMsg"));
1290 pStateTxt
= new wxTextCtrl(this, EDITOR_DIALOG_STATE_TEXT
, wxT(""), wxPoint(250, 247), wxSize(153, 25), 0, wxDefaultValidator
, wxT("StateTxt"));
1291 pCountryMsg
= new wxStaticText(this, EDITOR_DIALOG_COUNTRY_MSG
, wxT("Country:"), wxPoint( 17, 280), wxSize( -1, -1), 0, wxT("CountryMsg"));
1292 pCountryTxt
= new wxTextCtrl(this, EDITOR_DIALOG_COUNTRY_TEXT
, wxT(""), wxPoint( 17, 297), wxSize(225, 25), 0, wxDefaultValidator
, wxT("CountryTxt"));
1293 pPostalCodeMsg
= new wxStaticText(this, EDITOR_DIALOG_POSTAL_MSG
, wxT("Postal Code:"),wxPoint(250, 280), wxSize( -1, -1), 0, wxT("PostalCodeMsg"));
1294 pPostalCodeTxt
= new wxTextCtrl(this, EDITOR_DIALOG_POSTAL_TEXT
, wxT(""), wxPoint(250, 297), wxSize(153, 25), 0, wxDefaultValidator
, wxT("PostalCodeTxt"));
1296 wxString choice_strings
[5];
1297 choice_strings
[0] = wxT("English");
1298 choice_strings
[1] = wxT("French");
1299 choice_strings
[2] = wxT("German");
1300 choice_strings
[3] = wxT("Spanish");
1301 choice_strings
[4] = wxT("Other");
1303 pNativeLangChoice
= new wxChoice(this, EDITOR_DIALOG_LANG_CHOICE
, wxPoint( 17, 346), wxSize(277, -1), 5, choice_strings
);
1304 pNativeLangMsg
= new wxStaticText(this, EDITOR_DIALOG_LANG_MSG
, wxT("Native language:"), wxPoint( 17, 330), wxSize( -1, -1), 0, wxT("NativeLangMsg"));
1306 wxString radio_strings
[2];
1307 radio_strings
[0] = wxT("No");
1308 radio_strings
[1] = wxT("Yes");
1309 pDeveloperRadio
= new wxRadioBox(this,EDITOR_DIALOG_DEVELOPER
, wxT("Developer:"), wxPoint(303, 330), wxSize( -1, -1), 2, radio_strings
, 2, wxHORIZONTAL
);
1310 pJoinDateMsg
= new wxStaticText(this, EDITOR_DIALOG_JOIN_MSG
, wxT("Date joined:"), wxPoint( 17, 380), wxSize( -1, -1), 0, wxT("JoinDateMsg"));
1311 pJoinDateTxt
= new wxTextCtrl(this, EDITOR_DIALOG_JOIN_TEXT
, wxT(""), wxPoint( 17, 397), wxSize(150, 25), 0, wxDefaultValidator
, wxT("JoinDateTxt"));
1312 pContribMsg
= new wxStaticText(this, EDITOR_DIALOG_CONTRIB_MSG
,wxT("Contributions:"), wxPoint(175, 380), wxSize( -1, -1), 0, wxT("ContribMsg"));
1313 pContribTxt
= new wxTextCtrl(this, EDITOR_DIALOG_CONTRIB_TEXT
, wxT(""), wxPoint(175, 397), wxSize(120, 25), 0, wxDefaultValidator
, wxT("ContribTxt"));
1314 pLinesMsg
= new wxStaticText(this, EDITOR_DIALOG_LINES_MSG
, wxT("Lines of code:"), wxPoint(303, 380), wxSize( -1, -1), 0, wxT("LinesMsg"));
1315 pLinesTxt
= new wxTextCtrl(this, EDITOR_DIALOG_LINES_TEXT
, wxT(""), wxPoint(303, 397), wxSize(100, 25), 0, wxDefaultValidator
, wxT("LinesTxt"));
1317 pCatalogBtn
= new wxButton(this, EDITOR_DIALOG_CATALOG
, wxT("Catalo&g"), wxPoint(430, 287), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CatalogBtn"));
1318 pDataTypesBtn
= new wxButton(this, EDITOR_DIALOG_DATATYPES
, wxT("Data&types"), wxPoint(430, 337), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("DataTypesBtn"));
1319 pDbDiagsBtn
= new wxButton(this, EDITOR_DIALOG_DB_DIAGS
, wxT("DB Dia&gs"), wxPoint(430, 387), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("DbDiagsBtn"));
1321 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
1322 // handle all widget processing
1323 widgetPtrsSet
= TRUE
;
1325 // Setup the orderBy and where clauses to return back a single record as the result set,
1326 // as there will only be one record being shown on the dialog at a time, this optimizes
1327 // network traffic by only returning a one row result
1329 wxGetApp().Contact
->SetOrderByClause(wxT("NAME")); // field name to sort by
1331 // The wxString "whereStr" is not a member of the wxDbTable object, it is a member variable
1332 // specifically in the Ccontact class. It is used here for simpler construction of a varying
1333 // length string, and then after the string is built, the wxDbTable member variable "where" is
1334 // assigned the pointer to the constructed string.
1336 // The constructed where clause below has a sub-query within it "SELECT MIN(NAME) FROM %s"
1337 // to achieve a single row (in this case the first name in alphabetical order).
1339 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1340 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1342 wxGetApp().Contact
->whereStr
.Printf(wxT("NAME = (SELECT MIN(NAME) FROM %s)"),
1343 wxGetApp().Contact
->GetTableName().c_str());
1344 // NOTE: (const wxChar*) returns a pointer which may not be valid later, so this is short term use only
1345 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
);
1348 wxGetApp().Contact
->SetWhereClause(wxT(""));
1350 // Perform the Query to get the result set.
1351 // NOTE: If there are no rows returned, that is a valid result, so Query() would return TRUE.
1352 // Only if there is a database error will Query() come back as FALSE
1353 if (!wxGetApp().Contact
->Query())
1356 tStr
= wxT("ODBC error during Query()\n\n");
1357 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
1358 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1362 // Since Query succeeded, now get the row that was returned
1363 if (!wxGetApp().Contact
->GetNext())
1364 // If the GetNext() failed at this point, then there are no rows to retrieve,
1365 // so clear the values in the members of "Contact" so that PutData() blanks the
1366 // widgets on the dialog
1367 wxGetApp().Contact
->Initialize();
1369 wxGetApp().Contact->GetDb()->RollbackTrans();
1378 } // CeditorDlg::Initialize()
1381 void CeditorDlg::FieldsEditable()
1386 pNameTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1387 pAddress1Txt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1388 pAddress2Txt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1389 pCityTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1390 pStateTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1391 pPostalCodeTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1392 pCountryTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1394 pJoinDateTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1395 pContribTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1396 pLinesTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1397 pNativeLangChoice
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1398 pDeveloperRadio
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1400 } // CeditorDlg::FieldsEditable()
1403 void CeditorDlg::SetMode(enum DialogModes m
)
1424 pCreateBtn
->Enable( !edit
);
1425 pEditBtn
->Enable( !edit
&& (wxStrcmp(wxGetApp().Contact
->Name
,wxT(""))!=0) );
1426 pDeleteBtn
->Enable( !edit
&& (wxStrcmp(wxGetApp().Contact
->Name
,wxT(""))!=0) );
1427 pCopyBtn
->Enable( !edit
&& (wxStrcmp(wxGetApp().Contact
->Name
,wxT(""))!=0) );
1428 pSaveBtn
->Enable( edit
);
1429 pCancelBtn
->Enable( edit
);
1430 pPrevBtn
->Enable( !edit
);
1431 pNextBtn
->Enable( !edit
);
1432 pQueryBtn
->Enable( !edit
);
1433 pResetBtn
->Enable( !edit
&& !wxGetApp().Contact
->qryWhereStr
.IsEmpty() );
1434 pNameListBtn
->Enable( !edit
);
1438 } // CeditorDlg::SetMode()
1441 bool CeditorDlg::PutData()
1445 pNameTxt
->SetValue(wxGetApp().Contact
->Name
);
1446 pAddress1Txt
->SetValue(wxGetApp().Contact
->Addr1
);
1447 pAddress2Txt
->SetValue(wxGetApp().Contact
->Addr2
);
1448 pCityTxt
->SetValue(wxGetApp().Contact
->City
);
1449 pStateTxt
->SetValue(wxGetApp().Contact
->State
);
1450 pCountryTxt
->SetValue(wxGetApp().Contact
->Country
);
1451 pPostalCodeTxt
->SetValue(wxGetApp().Contact
->PostalCode
);
1453 tStr
.Printf(wxT("%d/%d/%d"),wxGetApp().Contact
->JoinDate
.month
,wxGetApp().Contact
->JoinDate
.day
,wxGetApp().Contact
->JoinDate
.year
);
1454 pJoinDateTxt
->SetValue(tStr
);
1456 tStr
.Printf(wxT("%d"),wxGetApp().Contact
->Contributions
);
1457 pContribTxt
->SetValue(tStr
);
1459 tStr
.Printf(wxT("%lu"),wxGetApp().Contact
->LinesOfCode
);
1460 pLinesTxt
->SetValue(tStr
);
1462 pNativeLangChoice
->SetSelection(wxGetApp().Contact
->NativeLanguage
);
1464 pDeveloperRadio
->SetSelection(wxGetApp().Contact
->IsDeveloper
);
1467 } // Ceditor::PutData()
1471 * Reads the data out of all the widgets on the dialog. Some data evaluation is done
1472 * to ensure that there is a name entered and that the date field is valid.
1474 * A return value of TRUE means that valid data was retrieved from the dialog, otherwise
1475 * invalid data was found (and a message was displayed telling the user what to fix), and
1476 * the data was not placed into the appropraite fields of Ccontact
1478 bool CeditorDlg::GetData()
1480 // Validate that the data currently entered into the widgets is valid data
1483 tStr
= pNameTxt
->GetValue();
1484 if (!wxStrcmp((const wxChar
*) tStr
,wxT("")))
1486 wxMessageBox(wxT("A name is required for entry into the contact table"),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
1490 bool invalid
= FALSE
;
1494 tStr
= pJoinDateTxt
->GetValue();
1495 if (tStr
.Freq(wxT('/')) != 2)
1498 // Find the month, day, and year tokens
1501 first
= tStr
.First(wxT('/'));
1502 second
= tStr
.Last(wxT('/'));
1504 mm
= atoi(tStr
.SubString(0,first
));
1505 dd
= atoi(tStr
.SubString(first
+1,second
));
1506 yyyy
= atoi(tStr
.SubString(second
+1,tStr
.Length()-1));
1508 invalid
= !(mm
&& dd
&& yyyy
);
1511 // Force Year 2000 compliance
1512 if (!invalid
&& (yyyy
< 1000))
1515 // Check the token ranges for validity
1520 else if ((mm
< 1) || (mm
> 12))
1528 int days
[12] = {31,28,31,30,31,30,
1530 if (dd
> days
[mm
-1])
1533 if ((dd
== 29) && (mm
== 2))
1535 if (((yyyy
% 4) == 0) && (((yyyy
% 100) != 0) || ((yyyy
% 400) == 0)))
1545 wxGetApp().Contact
->JoinDate
.month
= mm
;
1546 wxGetApp().Contact
->JoinDate
.day
= dd
;
1547 wxGetApp().Contact
->JoinDate
.year
= yyyy
;
1551 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
);
1555 tStr
= pNameTxt
->GetValue();
1556 wxStrcpy(wxGetApp().Contact
->Name
,(const wxChar
*) tStr
);
1557 wxStrcpy(wxGetApp().Contact
->Addr1
,pAddress1Txt
->GetValue());
1558 wxStrcpy(wxGetApp().Contact
->Addr2
,pAddress2Txt
->GetValue());
1559 wxStrcpy(wxGetApp().Contact
->City
,pCityTxt
->GetValue());
1560 wxStrcpy(wxGetApp().Contact
->State
,pStateTxt
->GetValue());
1561 wxStrcpy(wxGetApp().Contact
->Country
,pCountryTxt
->GetValue());
1562 wxStrcpy(wxGetApp().Contact
->PostalCode
,pPostalCodeTxt
->GetValue());
1564 wxGetApp().Contact
->Contributions
= atoi(pContribTxt
->GetValue());
1565 wxGetApp().Contact
->LinesOfCode
= atol(pLinesTxt
->GetValue());
1567 wxGetApp().Contact
->NativeLanguage
= (enum Language
) pNativeLangChoice
->GetSelection();
1568 wxGetApp().Contact
->IsDeveloper
= pDeveloperRadio
->GetSelection() > 0;
1571 } // CeditorDlg::GetData()
1575 * Retrieve data from the dialog, verify the validity of the data, and if it is valid,
1576 * try to insert/update the data to the table based on the current 'mode' the dialog
1579 * A return value of TRUE means the insert/update was completed successfully, a return
1580 * value of FALSE means that Save() failed. If returning FALSE, then this function
1581 * has displayed a detailed error message for the user.
1583 bool CeditorDlg::Save()
1585 bool failed
= FALSE
;
1587 // Read the data in the widgets of the dialog to get the user's data
1591 // Perform any other required validations necessary before saving
1594 wxBeginBusyCursor();
1596 if (mode
== mCreate
)
1598 RETCODE result
= wxGetApp().Contact
->Insert();
1600 failed
= (result
!= DB_SUCCESS
);
1603 // Some errors may be expected, like a duplicate key, so handle those instances with
1604 // specific error messages.
1605 if (result
== DB_ERR_INTEGRITY_CONSTRAINT_VIOL
)
1608 tStr
= wxT("A duplicate key value already exists in the table.\nUnable to save record\n\n");
1609 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
1610 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1614 // Some other unexpected error occurred
1616 tStr
= wxT("Database insert failed\n\n");
1617 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
1618 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1622 else // mode == mEdit
1624 wxGetApp().Contact
->GetDb()->RollbackTrans();
1625 wxGetApp().Contact
->whereStr
.Printf("NAME = '%s'",saveName
.c_str());
1626 if (!wxGetApp().Contact
->UpdateWhere(wxGetApp().Contact
->whereStr
))
1629 tStr
= wxT("Database update failed\n\n");
1630 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
1631 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1638 wxGetApp().Contact
->GetDb()->CommitTrans();
1639 SetMode(mView
); // Sets the dialog mode back to viewing after save is successful
1642 wxGetApp().Contact
->GetDb()->RollbackTrans();
1648 } // CeditorDlg::Save()
1652 * Where this program is only showing a single row at a time in the dialog,
1653 * a special where clause must be built to find just the single row which,
1654 * in sequence, would follow the currently displayed row.
1656 bool CeditorDlg::GetNextRec()
1660 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1661 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1663 w
= wxT("NAME = (SELECT MIN(NAME) FROM ");
1664 w
+= wxGetApp().Contact
->GetTableName();
1665 w
+= wxT(" WHERE NAME > '");
1668 w
= wxT("(NAME > '");
1670 w
+= wxGetApp().Contact
->Name
;
1673 // If a query where string is currently set, append that criteria
1674 if (!wxGetApp().Contact
->qryWhereStr
.IsEmpty())
1677 w
+= wxGetApp().Contact
->qryWhereStr
;
1684 } // CeditorDlg::GetNextRec()
1688 * Where this program is only showing a single row at a time in the dialog,
1689 * a special where clause must be built to find just the single row which,
1690 * in sequence, would precede the currently displayed row.
1692 bool CeditorDlg::GetPrevRec()
1696 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1697 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1699 w
= wxT("NAME = (SELECT MAX(NAME) FROM ");
1700 w
+= wxGetApp().Contact
->GetTableName();
1701 w
+= wxT(" WHERE NAME < '");
1704 w
= wxT("(NAME < '");
1706 w
+= wxGetApp().Contact
->Name
;
1709 // If a query where string is currently set, append that criteria
1710 if (!wxGetApp().Contact
->qryWhereStr
.IsEmpty())
1713 w
+= wxGetApp().Contact
->qryWhereStr
;
1721 } // CeditorDlg::GetPrevRec()
1725 * This function is here to avoid duplicating this same code in both the
1726 * GetPrevRec() and GetNextRec() functions
1728 bool CeditorDlg::GetRec(const wxString
&whereStr
)
1730 wxGetApp().Contact
->SetWhereClause(whereStr
);
1731 wxGetApp().Contact
->SetOrderByClause(wxT("NAME"));
1733 if (!wxGetApp().Contact
->Query())
1736 tStr
= wxT("ODBC error during Query()\n\n");
1737 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
1738 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1743 if (wxGetApp().Contact
->GetNext())
1750 } // CeditorDlg::GetRec()
1755 * CparameterDlg constructor
1758 BEGIN_EVENT_TABLE(CparameterDlg
, wxDialog
)
1759 EVT_BUTTON(PARAMETER_DIALOG_SAVE
, CparameterDlg::OnButton
)
1760 EVT_BUTTON(PARAMETER_DIALOG_CANCEL
, CparameterDlg::OnButton
)
1761 EVT_CLOSE(CparameterDlg::OnCloseWindow
)
1764 CparameterDlg::CparameterDlg(wxWindow
*parent
) : wxDialog (parent
, PARAMETER_DIALOG
, wxT("ODBC parameter settings"), wxPoint(-1, -1), wxSize(400, 325))
1766 // Since the ::OnCommand() function is overridden, this prevents the widget
1767 // detection in ::OnCommand() until all widgets have been initialized to prevent
1768 // uninitialized pointers from crashing the program
1769 widgetPtrsSet
= FALSE
;
1771 pParamODBCSourceMsg
= new wxStaticText(this, PARAMETER_DIALOG_SOURCE_MSG
, wxT("ODBC data sources:"), wxPoint( 10, 10), wxSize( -1, -1), 0, wxT("ParamODBCSourceMsg"));
1772 pParamODBCSourceList
= new wxListBox(this, PARAMETER_DIALOG_SOURCE_LISTBOX
, wxPoint( 10, 29), wxSize(285, 150), 0, 0, wxLB_SINGLE
|wxLB_ALWAYS_SB
, wxDefaultValidator
, wxT("ParamODBCSourceList"));
1773 pParamUserNameMsg
= new wxStaticText(this, PARAMETER_DIALOG_NAME_MSG
, wxT("Database user name:"), wxPoint( 10, 193), wxSize( -1, -1), 0, wxT("ParamUserNameMsg"));
1774 pParamUserNameTxt
= new wxTextCtrl(this, PARAMETER_DIALOG_NAME_TEXT
, wxT(""), wxPoint(10, 209), wxSize( 140, 25), 0, wxDefaultValidator
, wxT("ParamUserNameTxt"));
1775 pParamPasswordMsg
= new wxStaticText(this, PARAMETER_DIALOG_PASSWORD_MSG
, wxT("Password:"), wxPoint(156, 193), wxSize( -1, -1), 0, wxT("ParamPasswordMsg"));
1776 pParamPasswordTxt
= new wxTextCtrl(this, PARAMETER_DIALOG_PASSWORD_TEXT
, wxT(""), wxPoint(156, 209), wxSize( 140, 25), 0, wxDefaultValidator
, wxT("ParamPasswordTxt"));
1777 pParamDirPathMsg
= new wxStaticText(this, PARAMETER_DIALOG_DIRPATH_MSG
, wxT("Directory:"), wxPoint( 10, 243), wxSize( -1, -1), 0, wxT("ParamDirPathMsg"));
1778 pParamDirPathTxt
= new wxTextCtrl(this, PARAMETER_DIALOG_DIRPATH_TEXT
, wxT(""), wxPoint( 10, 259), wxSize(140, 25), 0, wxDefaultValidator
, wxT("ParamDirPathTxt"));
1779 pParamSaveBtn
= new wxButton(this, PARAMETER_DIALOG_SAVE
, wxT("&Save"), wxPoint(310, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("ParamSaveBtn"));
1780 pParamCancelBtn
= new wxButton(this, PARAMETER_DIALOG_CANCEL
, wxT("C&ancel"), wxPoint(310, 66), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("ParamCancelBtn"));
1782 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
1783 // handle all widget processing
1784 widgetPtrsSet
= TRUE
;
1787 savedParamSettings
= wxGetApp().params
;
1792 } // CparameterDlg constructor
1795 void CparameterDlg::OnCloseWindow(wxCloseEvent
& event
)
1797 // Put any additional checking necessary to make certain it is alright
1798 // to close the program here that is not done elsewhere
1801 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
);
1809 wxGetApp().params
= savedParamSettings
;
1812 if (GetParent() != NULL
)
1813 GetParent()->SetFocus();
1819 SetReturnCode(0); // added so BoundsChecker would not report use of uninitialized variable
1822 } // CparameterDlg::OnCloseWindow()
1825 void CparameterDlg::OnButton( wxCommandEvent
&event
)
1827 wxWindow
*win
= (wxWindow
*) event
.GetEventObject();
1828 OnCommand( *win
, event
);
1832 void CparameterDlg::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
1834 wxString widgetName
;
1836 widgetName
= win
.GetName();
1841 if (widgetName
== pParamSaveBtn
->GetName())
1846 tStr
= wxT("Database parameters have been saved.");
1847 if (GetParent() != NULL
) // The parameter dialog was not called during startup due to a missing cfg file
1848 tStr
+= wxT("\nNew parameters will take effect the next time the program is started.");
1849 wxMessageBox(tStr
,wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
1856 if (widgetName
== pParamCancelBtn
->GetName())
1861 } // CparameterDlg::OnCommand()
1864 bool CparameterDlg::PutData()
1866 // Fill the data source list box
1867 FillDataSourceList();
1869 // Fill in the fields from the params object
1870 if (wxGetApp().params
.ODBCSource
&& wxStrlen(wxGetApp().params
.ODBCSource
))
1871 pParamODBCSourceList
->SetStringSelection(wxGetApp().params
.ODBCSource
);
1872 pParamUserNameTxt
->SetValue(wxGetApp().params
.UserName
);
1873 pParamPasswordTxt
->SetValue(wxGetApp().params
.Password
);
1874 pParamDirPathTxt
->SetValue(wxGetApp().params
.DirPath
);
1876 } // CparameterDlg::PutData()
1879 bool CparameterDlg::GetData()
1882 if (pParamODBCSourceList
->GetStringSelection() != wxT(""))
1884 tStr
= pParamODBCSourceList
->GetStringSelection();
1885 if (tStr
.Length() > (sizeof(wxGetApp().params
.ODBCSource
)-1))
1888 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());
1889 wxMessageBox(errmsg
,wxT("Internal program error..."),wxOK
| wxICON_EXCLAMATION
);
1892 wxStrcpy(wxGetApp().params
.ODBCSource
, tStr
);
1897 tStr
= pParamUserNameTxt
->GetValue();
1898 if (tStr
.Length() > (sizeof(wxGetApp().params
.UserName
)-1))
1901 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());
1902 wxMessageBox(errmsg
,wxT("Internal program error..."),wxOK
| wxICON_EXCLAMATION
);
1905 wxStrcpy(wxGetApp().params
.UserName
, tStr
);
1907 tStr
= pParamPasswordTxt
->GetValue();
1908 if (tStr
.Length() > (sizeof(wxGetApp().params
.Password
)-1))
1911 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());
1912 wxMessageBox(errmsg
,wxT("Internal program error..."),wxOK
| wxICON_EXCLAMATION
);
1915 wxStrcpy(wxGetApp().params
.Password
,tStr
);
1917 tStr
= pParamDirPathTxt
->GetValue();
1918 tStr
.Replace(wxT("\\"),wxT("/"));
1919 if (tStr
.Length() > (sizeof(wxGetApp().params
.DirPath
)-1))
1922 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());
1923 wxMessageBox(errmsg
,wxT("Internal program error..."),wxOK
| wxICON_EXCLAMATION
);
1926 wxStrcpy(wxGetApp().params
.DirPath
,tStr
);
1928 } // CparameterDlg::GetData()
1931 bool CparameterDlg::Save()
1933 // Copy the current params in case user cancels changing
1934 // the params, so that we can reset them.
1937 wxGetApp().params
= savedParamSettings
;
1941 wxGetApp().WriteParamFile(wxGetApp().params
);
1944 } // CparameterDlg::Save()
1947 void CparameterDlg::FillDataSourceList()
1949 wxChar Dsn
[SQL_MAX_DSN_LENGTH
+ 1];
1951 wxStringList strList
;
1953 while (wxDbGetDataSource(wxGetApp().DbConnectInf
->GetHenv(), Dsn
,
1954 SQL_MAX_DSN_LENGTH
+1, DsDesc
, 255))
1958 strList
.Add(wxT(""));
1959 wxChar
**p
= strList
.ListToArray();
1962 for (i
= 0; wxStrlen(p
[i
]); i
++)
1963 pParamODBCSourceList
->Append(p
[i
]);
1966 } // CparameterDlg::FillDataSourceList()
1969 BEGIN_EVENT_TABLE(CqueryDlg
, wxDialog
)
1970 EVT_BUTTON(-1, CqueryDlg::OnButton
)
1971 EVT_CLOSE(CqueryDlg::OnCloseWindow
)
1975 // CqueryDlg() constructor
1976 CqueryDlg::CqueryDlg(wxWindow
*parent
, wxDb
*pDb
, wxChar
*tblName
[],
1977 const wxString
&pWhereArg
) :
1978 wxDialog (parent
, QUERY_DIALOG
, wxT("Query"), wxPoint(-1, -1), wxSize(480, 360))
1980 wxBeginBusyCursor();
1984 masterTableName
= tblName
[0];
1985 widgetPtrsSet
= FALSE
;
1988 // Initialize the WHERE clause from the string passed in
1989 pWhere
= pWhereArg
; // Save a pointer to the output buffer
1990 if (pWhere
.Length() > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN
) // Check the length of the buffer passed in
1993 s
.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN
+1);
1994 wxMessageBox(s
,wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
1999 pQueryCol1Msg
= new wxStaticText(this, QUERY_DIALOG_COL_MSG
, wxT("Column 1:"), wxPoint( 10, 10), wxSize( 69, 16), 0, wxT("QueryCol1Msg"));
2000 pQueryCol1Choice
= new wxChoice(this, QUERY_DIALOG_COL_CHOICE
, wxPoint( 10, 27), wxSize(250, 27), 0, 0, 0, wxDefaultValidator
, wxT("QueryCol1Choice"));
2001 pQueryNotMsg
= new wxStaticText(this, QUERY_DIALOG_NOT_MSG
, wxT("NOT"), wxPoint(268, 10), wxSize( -1, -1), 0, wxT("QueryNotMsg"));
2002 pQueryNotCheck
= new wxCheckBox(this, QUERY_DIALOG_NOT_CHECKBOX
, wxT(""), wxPoint(275, 37), wxSize( 20, 20), 0, wxDefaultValidator
, wxT("QueryNotCheck"));
2004 wxString choice_strings
[9];
2005 choice_strings
[0] = wxT("=");
2006 choice_strings
[1] = wxT("<");
2007 choice_strings
[2] = wxT(">");
2008 choice_strings
[3] = wxT("<=");
2009 choice_strings
[4] = wxT(">=");
2010 choice_strings
[5] = wxT("Begins");
2011 choice_strings
[6] = wxT("Contains");
2012 choice_strings
[7] = wxT("Like");
2013 choice_strings
[8] = wxT("Between");
2015 pQueryOperatorMsg
= new wxStaticText(this, QUERY_DIALOG_OP_MSG
, wxT("Operator:"), wxPoint(305, 10), wxSize( -1, -1), 0, wxT("QueryOperatorMsg"));
2016 pQueryOperatorChoice
= new wxChoice(this, QUERY_DIALOG_OP_CHOICE
, wxPoint(305, 27), wxSize( 80, 27), 9, choice_strings
, 0, wxDefaultValidator
, wxT("QueryOperatorChoice"));
2017 pQueryCol2Msg
= new wxStaticText(this, QUERY_DIALOG_COL2_MSG
, wxT("Column 2:"), wxPoint( 10, 65), wxSize( 69, 16), 0, wxT("QueryCol2Msg"));
2018 pQueryCol2Choice
= new wxChoice(this, QUERY_DIALOG_COL2_CHOICE
, wxPoint( 10, 82), wxSize(250, 27), 0, 0, 0, wxDefaultValidator
, wxT("QueryCol2Choice"));
2019 pQuerySqlWhereMsg
= new wxStaticText(this, QUERY_DIALOG_WHERE_MSG
, wxT("SQL where clause:"), wxPoint( 10, 141), wxSize( -1, -1), 0, wxT("QuerySqlWhereMsg"));
2020 pQuerySqlWhereMtxt
= new wxTextCtrl(this, QUERY_DIALOG_WHERE_TEXT
, wxT(""), wxPoint( 10, 159), wxSize(377, 134), wxTE_MULTILINE
, wxDefaultValidator
, wxT("QuerySqlWhereMtxt"));
2021 pQueryAddBtn
= new wxButton(this, QUERY_DIALOG_ADD
, wxT("&Add"), wxPoint(406, 24), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryAddBtn"));
2022 pQueryAndBtn
= new wxButton(this, QUERY_DIALOG_AND
, wxT("A&nd"), wxPoint(406, 58), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryAndBtn"));
2023 pQueryOrBtn
= new wxButton(this, QUERY_DIALOG_OR
, wxT("&Or"), wxPoint(406, 92), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryOrBtn"));
2024 pQueryLParenBtn
= new wxButton(this, QUERY_DIALOG_LPAREN
, wxT("("), wxPoint(406, 126), wxSize( 26, 26), 0, wxDefaultValidator
, wxT("QueryLParenBtn"));
2025 pQueryRParenBtn
= new wxButton(this, QUERY_DIALOG_RPAREN
, wxT(")"), wxPoint(436, 126), wxSize( 26, 26), 0, wxDefaultValidator
, wxT("QueryRParenBtn"));
2026 pQueryDoneBtn
= new wxButton(this, QUERY_DIALOG_DONE
, wxT("&Done"), wxPoint(406, 185), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryDoneBtn"));
2027 pQueryClearBtn
= new wxButton(this, QUERY_DIALOG_CLEAR
, wxT("C&lear"), wxPoint(406, 218), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryClearBtn"));
2028 pQueryCountBtn
= new wxButton(this, QUERY_DIALOG_COUNT
, wxT("&Count"), wxPoint(406, 252), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryCountBtn"));
2029 pQueryValue1Msg
= new wxStaticText(this, QUERY_DIALOG_VALUE1_MSG
, wxT("Value:"), wxPoint(277, 66), wxSize( -1, -1), 0, wxT("QueryValue1Msg"));
2030 pQueryValue1Txt
= new wxTextCtrl(this, QUERY_DIALOG_VALUE1_TEXT
, wxT(""), wxPoint(277, 83), wxSize(108, 25), 0, wxDefaultValidator
, wxT("QueryValue1Txt"));
2031 pQueryValue2Msg
= new wxStaticText(this, QUERY_DIALOG_VALUE2_MSG
, wxT("AND"), wxPoint(238, 126), wxSize( -1, -1), 0, wxT("QueryValue2Msg"));
2032 pQueryValue2Txt
= new wxTextCtrl(this, QUERY_DIALOG_VALUE2_TEXT
, wxT(""), wxPoint(277, 120), wxSize(108, 25), 0, wxDefaultValidator
, wxT("QueryValue2Txt"));
2033 pQueryHintGrp
= new wxStaticBox(this, QUERY_DIALOG_HINT_GROUP
, wxT(""), wxPoint( 10, 291), wxSize(377, 40), 0, wxT("QueryHintGrp"));
2034 pQueryHintMsg
= new wxStaticText(this, QUERY_DIALOG_HINT_MSG
, wxT(""), wxPoint( 16, 306), wxSize( -1, -1), 0, wxT("QueryHintMsg"));
2036 widgetPtrsSet
= TRUE
;
2037 // Initialize the dialog
2039 pQueryCol2Choice
->Append(wxT("VALUE -->"));
2040 colInf
= pDB
->GetColumns(tblName
);
2046 tStr
= wxT("ODBC error during GetColumns()\n\n");
2047 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
2048 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2053 for (i
= 0; colInf
[i
].colName
&& wxStrlen(colInf
[i
].colName
); i
++)
2055 // If there is more than one table being queried, qualify
2056 // the column names with the table name prefix.
2057 if (tblName
[1] && wxStrlen(tblName
[1]))
2059 qualName
.Printf(wxT("%s.%s"), colInf
[i
].tableName
, colInf
[i
].colName
);
2060 pQueryCol1Choice
->Append(qualName
);
2061 pQueryCol2Choice
->Append(qualName
);
2063 else // Single table query, append just the column names
2065 pQueryCol1Choice
->Append(colInf
[i
].colName
);
2066 pQueryCol2Choice
->Append(colInf
[i
].colName
);
2070 pQueryCol1Choice
->SetSelection(0);
2071 pQueryCol2Choice
->SetSelection(0);
2072 pQueryOperatorChoice
->SetSelection(0);
2074 pQueryValue2Msg
->Show(FALSE
);
2075 pQueryValue2Txt
->Show(FALSE
);
2077 pQueryHintMsg
->SetLabel(langQRY_EQ
);
2079 pQuerySqlWhereMtxt
->SetValue(pWhere
.c_str());
2083 // Display the dialog window
2086 } // CqueryDlg() constructor
2089 CqueryDlg::~CqueryDlg()
2091 } // CqueryDlg::~CqueryDlg() destructor
2094 void CqueryDlg::OnButton(wxCommandEvent
&event
)
2096 wxWindow
*win
= (wxWindow
*) event
.GetEventObject();
2097 OnCommand( *win
, event
);
2098 } // CqueryDlg::OnButton()
2101 void CqueryDlg::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
2103 // Widget pointers won't be set when the dialog is constructed.
2104 // Control is passed through this function once for each widget on
2105 // a dialog as the dialog is constructed.
2109 wxString widgetName
= win
.GetName();
2111 // Operator choice box
2112 if (widgetName
== pQueryOperatorChoice
->GetName())
2114 // Set the help text
2115 switch((qryOp
) pQueryOperatorChoice
->GetSelection())
2118 pQueryHintMsg
->SetLabel(langQRY_EQ
);
2121 pQueryHintMsg
->SetLabel(langQRY_LT
);
2124 pQueryHintMsg
->SetLabel(langQRY_GT
);
2127 pQueryHintMsg
->SetLabel(langQRY_LE
);
2130 pQueryHintMsg
->SetLabel(langQRY_GE
);
2133 pQueryHintMsg
->SetLabel(langQRY_BEGINS
);
2136 pQueryHintMsg
->SetLabel(langQRY_CONTAINS
);
2139 pQueryHintMsg
->SetLabel(langQRY_LIKE
);
2142 pQueryHintMsg
->SetLabel(langQRY_BETWEEN
);
2146 // Hide the value2 widget
2147 pQueryValue2Msg
->Show(FALSE
); // BETWEEN will show this widget
2148 pQueryValue2Txt
->Show(FALSE
); // BETWEEN will show this widget
2150 // Disable the NOT operator for <, <=, >, >=
2151 switch((qryOp
) pQueryOperatorChoice
->GetSelection())
2157 pQueryNotCheck
->SetValue(0);
2158 pQueryNotCheck
->Enable(FALSE
);
2161 pQueryNotCheck
->Enable(TRUE
);
2165 // Manipulate the dialog to handle the selected operator
2166 switch((qryOp
) pQueryOperatorChoice
->GetSelection())
2173 pQueryCol2Choice
->Enable(TRUE
);
2174 if (pQueryCol2Choice
->GetSelection()) // Column name is highlighted
2176 pQueryValue1Msg
->Show(FALSE
);
2177 pQueryValue1Txt
->Show(FALSE
);
2179 else // "Value" is highlighted
2181 pQueryValue1Msg
->Show(TRUE
);
2182 pQueryValue1Txt
->Show(TRUE
);
2183 pQueryValue1Txt
->SetFocus();
2189 pQueryCol2Choice
->SetSelection(0);
2190 pQueryCol2Choice
->Enable(FALSE
);
2191 pQueryValue1Msg
->Show(TRUE
);
2192 pQueryValue1Txt
->Show(TRUE
);
2193 pQueryValue1Txt
->SetFocus();
2196 pQueryCol2Choice
->SetSelection(0);
2197 pQueryCol2Choice
->Enable(FALSE
);
2198 pQueryValue2Msg
->Show(TRUE
);
2199 pQueryValue2Txt
->Show(TRUE
);
2200 pQueryValue1Msg
->Show(TRUE
);
2201 pQueryValue1Txt
->Show(TRUE
);
2202 pQueryValue1Txt
->SetFocus();
2208 } // Operator choice box
2211 if (widgetName
== pQueryCol2Choice
->GetName())
2213 if (pQueryCol2Choice
->GetSelection()) // Column name is highlighted
2215 pQueryValue1Msg
->Show(FALSE
);
2216 pQueryValue1Txt
->Show(FALSE
);
2218 else // "Value" is highlighted
2220 pQueryValue1Msg
->Show(TRUE
);
2221 pQueryValue1Txt
->Show(TRUE
);
2222 pQueryValue1Txt
->SetFocus();
2225 } // Column 2 choice
2228 if (widgetName
== pQueryAddBtn
->GetName())
2235 if (widgetName
== pQueryAndBtn
->GetName())
2237 AppendToWhere(wxT(" AND\n"));
2242 if (widgetName
== pQueryOrBtn
->GetName())
2244 AppendToWhere(wxT(" OR\n"));
2248 // Left Paren button
2249 if (widgetName
== pQueryLParenBtn
->GetName())
2251 AppendToWhere(wxT("("));
2253 } // Left Paren button
2255 // Right paren button
2256 if (widgetName
== pQueryRParenBtn
->GetName())
2258 AppendToWhere(wxT(")"));
2260 } // Right Paren button
2263 if (widgetName
== pQueryDoneBtn
->GetName())
2265 // Be sure the where clause will not overflow the output buffer
2266 if (wxStrlen(pQuerySqlWhereMtxt
->GetValue()) > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN
)
2269 s
.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN
+1);
2270 wxMessageBox(s
,wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2273 // Validate the where clause for things such as matching parens
2274 if (!ValidateWhereClause())
2276 // Copy the where clause to the output buffer and exit
2277 pWhere
= pQuerySqlWhereMtxt
->GetValue();
2283 if (widgetName
== pQueryClearBtn
->GetName())
2285 bool Ok
= (wxMessageBox(wxT("Are you sure you wish to clear the Query?"),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
2288 pQuerySqlWhereMtxt
->SetValue(wxT(""));
2293 if (widgetName
== pQueryCountBtn
->GetName())
2295 wxBeginBusyCursor();
2301 } // CqueryDlg::OnCommand
2304 void CqueryDlg::OnCloseWindow(wxCloseEvent
& event
)
2311 GetParent()->SetFocus();
2316 SetReturnCode(1); // added so BoundsChecker would not report use of uninitialized variable
2319 } // CqueryDlg::OnCloseWindow()
2322 void CqueryDlg::AppendToWhere(wxChar
*s
)
2324 wxString whereStr
= pQuerySqlWhereMtxt
->GetValue();
2326 pQuerySqlWhereMtxt
->SetValue(whereStr
);
2327 } // CqueryDlg::AppendToWhere()
2330 void CqueryDlg::ProcessAddBtn()
2332 qryOp oper
= (qryOp
) pQueryOperatorChoice
->GetSelection();
2334 // Verify that eveything is filled in correctly
2335 if (pQueryCol2Choice
->GetSelection() == 0) // "Value" is selected
2337 // Verify that value 1 is filled in
2338 if (wxStrlen(pQueryValue1Txt
->GetValue()) == 0)
2341 pQueryValue1Txt
->SetFocus();
2344 // For the BETWEEN operator, value 2 must be filled in as well
2345 if (oper
== qryOpBETWEEN
&&
2346 wxStrlen(pQueryValue2Txt
->GetValue()) == 0)
2349 pQueryValue2Txt
->SetFocus();
2354 // Build the expression and append it to the where clause window
2355 wxString s
= pQueryCol1Choice
->GetStringSelection();
2357 if (pQueryNotCheck
->GetValue() && (oper
!= qryOpEQ
))
2363 if (pQueryNotCheck
->GetValue()) // NOT box is checked
2386 s
+= wxT(" BETWEEN");
2392 int col1Idx
= pQueryCol1Choice
->GetSelection();
2395 if (colInf
[col1Idx
].sqlDataType
== SQL_VARCHAR
||
2396 oper
== qryOpBEGINS
||
2397 oper
== qryOpCONTAINS
||
2401 if (pQueryCol2Choice
->GetSelection()) // Column name
2402 s
+= pQueryCol2Choice
->GetStringSelection();
2403 else // Column 2 is a "value"
2407 if (oper
== qryOpCONTAINS
)
2409 s
+= pQueryValue1Txt
->GetValue();
2410 if (oper
== qryOpCONTAINS
|| oper
== qryOpBEGINS
)
2416 if (oper
== qryOpBETWEEN
)
2421 s
+= pQueryValue2Txt
->GetValue();
2426 AppendToWhere((wxChar
*) (const wxChar
*) s
);
2428 } // CqueryDlg::ProcessAddBtn()
2431 void CqueryDlg::ProcessCountBtn()
2433 if (!ValidateWhereClause())
2436 if (!dbTable
) // wxDbTable object needs to be created and opened
2438 dbTable
= new wxDbTable(pDB
, masterTableName
, 0, wxT(""),
2440 wxGetApp().DbConnectInf
->GetDefaultDir());
2443 wxMessageBox(wxT("Memory allocation failed creating a wxDbTable object."),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2446 if (!dbTable
->Open())
2449 tStr
= wxT("ODBC error during Open()\n\n");
2450 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
2451 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2456 // Count() with WHERE clause
2459 whereStr
= pQuerySqlWhereMtxt
->GetValue();
2460 dbTable
->SetWhereClause(whereStr
.c_str());
2462 ULONG whereCnt
= dbTable
->Count();
2464 // Count() of all records in the table
2465 dbTable
->SetWhereClause(wxT(""));
2466 ULONG totalCnt
= dbTable
->Count();
2468 if (whereCnt
> 0 || totalCnt
== 0)
2471 tStr
.Printf(wxT("%lu of %lu records match the query criteria."),whereCnt
,totalCnt
);
2472 wxMessageBox(tStr
,wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
2477 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
);
2478 wxMessageBox(tStr
,wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
2481 // After a wxMessageBox, the focus does not necessarily return to the
2482 // window which was the focus when the message box popped up, so return
2483 // focus to the Query dialog for certain
2486 } // CqueryDlg::ProcessCountBtn()
2489 bool CqueryDlg::ValidateWhereClause()
2491 wxString where
= pQuerySqlWhereMtxt
->GetValue();
2493 if (where
.Freq(wxT('(')) != where
.Freq(wxT(')')))
2495 wxMessageBox(wxT("There are mismatched parenthesis in the constructed where clause"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2498 // After a wxMessageBox, the focus does not necessarily return to the
2499 // window which was the focus when the message box popped up, so return
2500 // focus to the Query dialog for certain
2505 } // CqueryDlg::ValidateWhereClause()
2509 void DisplayDbDiagnostics(wxDb
*pDb
)
2514 s
= langDBINF_DB_NAME
;
2515 s
+= pDb
->dbInf
.dbmsName
;
2518 s
+= langDBINF_DB_VER
;
2519 s
+= pDb
->dbInf
.dbmsVer
;
2522 s
+= langDBINF_DRIVER_NAME
;
2523 s
+= pDb
->dbInf
.driverName
;
2526 s
+= langDBINF_DRIVER_ODBC_VER
;
2527 s
+= pDb
->dbInf
.odbcVer
;
2530 s
+= langDBINF_DRIVER_MGR_ODBC_VER
;
2531 s
+= pDb
->dbInf
.drvMgrOdbcVer
;
2534 s
+= langDBINF_DRIVER_VER
;
2535 s
+= pDb
->dbInf
.driverVer
;
2538 s
+= langDBINF_SERVER_NAME
;
2539 s
+= pDb
->dbInf
.serverName
;
2542 s
+= langDBINF_FILENAME
;
2543 s
+= pDb
->dbInf
.databaseName
;
2546 s
+= langDBINF_OUTER_JOINS
;
2547 s
+= pDb
->dbInf
.outerJoins
;
2550 s
+= langDBINF_STORED_PROC
;
2551 s
+= pDb
->dbInf
.procedureSupport
;
2554 if (pDb
->dbInf
.maxConnections
)
2555 t
.sprintf("%s%d\n", langDBINF_MAX_HDBC
, pDb
->dbInf
.maxConnections
);
2557 t
.sprintf("%s%s\n", langDBINF_MAX_HDBC
, langDBINF_UNLIMITED
);
2560 if (pDb
->dbInf
.maxStmts
)
2561 t
.sprintf("%s%d\n", langDBINF_MAX_HSTMT
, pDb
->dbInf
.maxStmts
);
2563 t
.sprintf("%s%s\n", langDBINF_MAX_HSTMT
, langDBINF_UNLIMITED
);
2566 s
+= langDBINF_API_LVL
;
2567 switch(pDb
->dbInf
.apiConfLvl
)
2569 case SQL_OAC_NONE
: s
+= langDBINF_NONE
; break;
2570 case SQL_OAC_LEVEL1
: s
+= langDBINF_LEVEL1
; break;
2571 case SQL_OAC_LEVEL2
: s
+= langDBINF_LEVEL2
; break;
2575 s
+= langDBINF_CLI_LVL
;
2576 switch(pDb
->dbInf
.cliConfLvl
)
2578 case SQL_OSCC_NOT_COMPLIANT
: s
+= langDBINF_NOT_COMPLIANT
; break;
2579 case SQL_OSCC_COMPLIANT
: s
+= langDBINF_COMPLIANT
; break;
2583 s
+= langDBINF_SQL_LVL
;
2584 switch(pDb
->dbInf
.sqlConfLvl
)
2586 case SQL_OSC_MINIMUM
: s
+= langDBINF_MIN_GRAMMAR
; break;
2587 case SQL_OSC_CORE
: s
+= langDBINF_CORE_GRAMMAR
; break;
2588 case SQL_OSC_EXTENDED
: s
+= langDBINF_EXT_GRAMMAR
; break;
2592 s
+= langDBINF_COMMIT_BEHAVIOR
;
2593 switch(pDb
->dbInf
.cursorCommitBehavior
)
2595 case SQL_CB_DELETE
: s
+= langDBINF_DELETE_CURSORS
; break;
2596 case SQL_CB_CLOSE
: s
+= langDBINF_CLOSE_CURSORS
; break;
2597 case SQL_CB_PRESERVE
: s
+= langDBINF_PRESERVE_CURSORS
; break;
2601 s
+= langDBINF_ROLLBACK_BEHAVIOR
;
2602 switch(pDb
->dbInf
.cursorRollbackBehavior
)
2604 case SQL_CB_DELETE
: s
+= langDBINF_DELETE_CURSORS
; break;
2605 case SQL_CB_CLOSE
: s
+= langDBINF_CLOSE_CURSORS
; break;
2606 case SQL_CB_PRESERVE
: s
+= langDBINF_PRESERVE_CURSORS
; break;
2610 s
+= langDBINF_SUPP_NOT_NULL
;
2611 switch(pDb
->dbInf
.supportNotNullClause
)
2613 case SQL_NNC_NULL
: s
+= langNO
; break;
2614 case SQL_NNC_NON_NULL
: s
+= langYES
; break;
2618 s
+= langDBINF_SUPP_IEF
;
2619 s
+= pDb
->dbInf
.supportIEF
;
2622 // DEFAULT setting for "Transaction Isolation Level"
2623 s
+= langDBINF_TXN_ISOLATION
;
2624 switch(pDb
->dbInf
.txnIsolation
)
2626 case SQL_TXN_READ_UNCOMMITTED
: s
+= langDBINF_READ_UNCOMMITTED
; break;
2627 case SQL_TXN_READ_COMMITTED
: s
+= langDBINF_READ_COMMITTED
; break;
2628 case SQL_TXN_REPEATABLE_READ
: s
+= langDBINF_REPEATABLE_READ
; break;
2629 case SQL_TXN_SERIALIZABLE
: s
+= langDBINF_SERIALIZABLE
; break;
2631 case SQL_TXN_VERSIONING
: s
+= langDBINF_VERSIONING
; break;
2636 // CURRENT setting for "Transaction Isolation Level"
2638 s
+= langDBINF_TXN_ISOLATION_CURR
;
2639 if (SQLGetConnectOption(pDb
->GetHDBC(),SQL_TXN_ISOLATION
,&txnIsoLvl
) == SQL_SUCCESS
)
2643 case SQL_TXN_READ_UNCOMMITTED
: s
+= langDBINF_READ_UNCOMMITTED
; break;
2644 case SQL_TXN_READ_COMMITTED
: s
+= langDBINF_READ_COMMITTED
; break;
2645 case SQL_TXN_REPEATABLE_READ
: s
+= langDBINF_REPEATABLE_READ
; break;
2646 case SQL_TXN_SERIALIZABLE
: s
+= langDBINF_SERIALIZABLE
; break;
2648 case SQL_TXN_VERSIONING
: s
+= langDBINF_VERSIONING
; break;
2655 s
+= langDBINF_TXN_ISOLATION_OPTS
;
2656 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_READ_UNCOMMITTED
)
2657 {s
+= langDBINF_READ_UNCOMMITTED
; comma
++;}
2658 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_READ_COMMITTED
)
2659 {if (comma
++) s
+= ", "; s
+= langDBINF_READ_COMMITTED
;}
2660 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_REPEATABLE_READ
)
2661 {if (comma
++) s
+= ", "; s
+= langDBINF_REPEATABLE_READ
;}
2662 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_SERIALIZABLE
)
2663 {if (comma
++) s
+= ", "; s
+= langDBINF_SERIALIZABLE
;}
2665 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_VERSIONING
)
2666 {if (comma
++) s
+= ", "; s
+= langDBINF_VERSIONING
;}
2671 s
+= langDBINF_FETCH_DIRS
;
2672 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_NEXT
)
2673 {s
+= langDBINF_NEXT
; comma
++;}
2674 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_PRIOR
)
2675 {if (comma
++) s
+= ", "; s
+= langDBINF_PREV
;}
2676 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_FIRST
)
2677 {if (comma
++) s
+= ", "; s
+= langDBINF_FIRST
;}
2678 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_LAST
)
2679 {if (comma
++) s
+= ", "; s
+= langDBINF_LAST
;}
2680 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_ABSOLUTE
)
2681 {if (comma
++) s
+= ", "; s
+= langDBINF_ABSOLUTE
;}
2682 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_RELATIVE
)
2683 {if (comma
++) s
+= ", "; s
+= langDBINF_RELATIVE
;}
2685 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_RESUME
)
2686 {if (comma
++) s
+= ", "; s
+= langDBINF_RESUME
;}
2688 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_BOOKMARK
)
2689 {if (comma
++) s
+= ", "; s
+= langDBINF_BOOKMARK
;}
2693 s
+= langDBINF_LOCK_TYPES
;
2694 if (pDb
->dbInf
.lockTypes
& SQL_LCK_NO_CHANGE
)
2695 {s
+= langDBINF_NO_CHANGE
; comma
++;}
2696 if (pDb
->dbInf
.lockTypes
& SQL_LCK_EXCLUSIVE
)
2697 {if (comma
++) s
+= ", "; s
+= langDBINF_EXCLUSIVE
;}
2698 if (pDb
->dbInf
.lockTypes
& SQL_LCK_UNLOCK
)
2699 {if (comma
++) s
+= ", "; s
+= langDBINF_UNLOCK
;}
2703 s
+= langDBINF_POS_OPERS
;
2704 if (pDb
->dbInf
.posOperations
& SQL_POS_POSITION
)
2705 {s
+= langDBINF_POSITION
; comma
++;}
2706 if (pDb
->dbInf
.posOperations
& SQL_POS_REFRESH
)
2707 {if (comma
++) s
+= ", "; s
+= langDBINF_REFRESH
;}
2708 if (pDb
->dbInf
.posOperations
& SQL_POS_UPDATE
)
2709 {if (comma
++) s
+= ", "; s
+= langDBINF_UPD
;}
2710 if (pDb
->dbInf
.posOperations
& SQL_POS_DELETE
)
2711 {if (comma
++) s
+= ", "; s
+= langDBINF_DEL
;}
2712 if (pDb
->dbInf
.posOperations
& SQL_POS_ADD
)
2713 {if (comma
++) s
+= ", "; s
+= langDBINF_ADD
;}
2717 s
+= langDBINF_POS_STMTS
;
2718 if (pDb
->dbInf
.posStmts
& SQL_PS_POSITIONED_DELETE
)
2719 {s
+= langDBINF_POS_DEL
; comma
++;}
2720 if (pDb
->dbInf
.posStmts
& SQL_PS_POSITIONED_UPDATE
)
2721 {if (comma
++) s
+= ", "; s
+= langDBINF_POS_UPD
;}
2722 if (pDb
->dbInf
.posStmts
& SQL_PS_SELECT_FOR_UPDATE
)
2723 {if (comma
++) s
+= ", "; s
+= langDBINF_SELECT_FOR_UPD
;}
2727 s
+= langDBINF_SCROLL_CONCURR
;
2728 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_READ_ONLY
)
2729 {s
+= langDBINF_READ_ONLY
; comma
++;}
2730 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_LOCK
)
2731 {if (comma
++) s
+= ", "; s
+= langDBINF_LOCK
;}
2732 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_OPT_ROWVER
)
2733 {if (comma
++) s
+= ", "; s
+= langDBINF_OPT_ROWVER
;}
2734 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_OPT_VALUES
)
2735 {if (comma
++) s
+= ", "; s
+= langDBINF_OPT_VALUES
;}
2739 s
+= langDBINF_SCROLL_OPTS
;
2740 if (pDb
->dbInf
.scrollOptions
& SQL_SO_FORWARD_ONLY
)
2741 {s
+= langDBINF_FWD_ONLY
; comma
++;}
2742 if (pDb
->dbInf
.scrollOptions
& SQL_SO_STATIC
)
2743 {if (comma
++) s
+= ", "; s
+= langDBINF_STATIC
;}
2744 if (pDb
->dbInf
.scrollOptions
& SQL_SO_KEYSET_DRIVEN
)
2745 {if (comma
++) s
+= ", "; s
+= langDBINF_KEYSET_DRIVEN
;}
2746 if (pDb
->dbInf
.scrollOptions
& SQL_SO_DYNAMIC
)
2747 {if (comma
++) s
+= ", "; s
+= langDBINF_DYNAMIC
;}
2748 if (pDb
->dbInf
.scrollOptions
& SQL_SO_MIXED
)
2749 {if (comma
++) s
+= ", "; s
+= langDBINF_MIXED
;}
2753 s
+= langDBINF_STATIC_SENS
;
2754 if (pDb
->dbInf
.staticSensitivity
& SQL_SS_ADDITIONS
)
2755 {s
+= langDBINF_ADDITIONS
; comma
++;}
2756 if (pDb
->dbInf
.staticSensitivity
& SQL_SS_DELETIONS
)
2757 {if (comma
++) s
+= ", "; s
+= langDBINF_DELETIONS
;}
2758 if (pDb
->dbInf
.staticSensitivity
& SQL_SS_UPDATES
)
2759 {if (comma
++) s
+= ", "; s
+= langDBINF_UPDATES
;}
2763 s
+= langDBINF_TXN_CAPABLE
;
2764 switch(pDb
->dbInf
.txnCapable
)
2766 case SQL_TC_NONE
: s
+= langNO
; break;
2767 case SQL_TC_DML
: s
+= langDBINF_DML_ONLY
; break;
2768 case SQL_TC_DDL_COMMIT
: s
+= langDBINF_DDL_COMMIT
; break;
2769 case SQL_TC_DDL_IGNORE
: s
+= langDBINF_DDL_IGNORE
; break;
2770 case SQL_TC_ALL
: s
+= langDBINF_DDL_AND_DML
; break;
2774 t
.sprintf("%s%d\n", langDBINF_LOGIN_TIMEOUT
, pDb
->dbInf
.loginTimeout
);
2777 // Oracle specific information
2778 if (pDb
->Dbms() == dbmsORACLE
)
2781 s
+= langDBINF_ORACLE_BANNER
;
2784 // Oracle cache hit ratio
2787 pDb
->ExecSql("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'db block gets'");
2789 if (pDb
->GetData(1, SQL_C_ULONG
, &dbBlockGets
, 0, &cb
))
2791 t
.sprintf("%s: %lu\n", langDBINF_DB_BLOCK_GETS
, dbBlockGets
);
2795 ULONG consistentGets
;
2796 pDb
->ExecSql("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'consistent gets'");
2798 if (pDb
->GetData(1, SQL_C_ULONG
, &consistentGets
, 0, &cb
))
2800 t
.sprintf("%s: %lu\n", langDBINF_CONSISTENT_GETS
, consistentGets
);
2805 pDb
->ExecSql("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'physical reads'");
2807 if (pDb
->GetData(1, SQL_C_ULONG
, &physReads
, 0, &cb
))
2809 t
.sprintf("%s: %lu\n", langDBINF_PHYSICAL_READS
, physReads
);
2813 ULONG hitRatio
= (ULONG
)((1.00 - ((float)physReads
/ (float)(dbBlockGets
+ consistentGets
))) * 100.00);
2814 t
.sprintf("*** %s: %lu%%\n", langDBINF_CACHE_HIT_RATIO
, hitRatio
);
2817 // Tablespace information
2819 s
+= langDBINF_TABLESPACE_IO
;
2822 char tablespaceName
[257];
2823 pDb
->ExecSql("SELECT NAME,PHYRDS,PHYWRTS FROM V$DATAFILE, V$FILESTAT WHERE V$DATAFILE.FILE# = V$FILESTAT.FILE#");
2824 while (pDb
->GetNext())
2826 pDb
->GetData(1, SQL_C_CHAR
, tablespaceName
, 257, &cb
);
2827 pDb
->GetData(2, SQL_C_ULONG
, &physReads
, 0, &cb
);
2828 pDb
->GetData(3, SQL_C_ULONG
, &physWrites
, 0, &cb
);
2829 t
.sprintf("%s\n\t%s: %lu\t%s: %lu\n", tablespaceName
,
2830 langDBINF_PHYSICAL_READS
, physReads
, langDBINF_PHYSICAL_WRITES
, physWrites
);
2839 } // DisplayDbDiagnostics()
2843 BEGIN_EVENT_TABLE(DbGridFrame
, wxFrame
)
2844 // EVT_CLOSE(DbGridFrame::OnCloseWindow)
2848 DbGridFrame::DbGridFrame(wxWindow
*parent
)
2849 : wxFrame (parent
, -1, wxT("Database Table"),
2850 wxDefaultPosition
, wxSize(400, 325))
2852 initialized
= FALSE
;
2856 void DbGridFrame::OnCloseWindow(wxCloseEvent
& event
)
2862 bool DbGridFrame::Initialize()
2864 wxGrid
*grid
= new wxGrid(this, -1, wxDefaultPosition
);
2866 grid
->RegisterDataType(wxGRID_VALUE_DATETIME
,
2867 new wxGridCellDateTimeRenderer(_T("%d %b %Y")),
2868 new wxGridCellTextEditor
);
2870 grid
->RegisterDataType(wxGRID_VALUE_CHOICEINT
,
2871 new wxGridCellEnumRenderer
,
2872 new wxGridCellEnumEditor
);
2874 wxString
NativeLangChoice( wxString::Format("%s:%s,%s,%s,%s,%s",wxGRID_VALUE_CHOICEINT
,
2882 // Columns must match the sequence specified in SetColDef() calls
2883 wxDbGridColInfo
* cols
=
2884 new wxDbGridColInfo( 0,wxGRID_VALUE_STRING
,wxT("Name"),
2885 new wxDbGridColInfo( 1,wxGRID_VALUE_STRING
,wxT("Address 1"),
2886 new wxDbGridColInfo( 2,wxGRID_VALUE_STRING
,wxT("Address 2"),
2887 new wxDbGridColInfo( 3,wxGRID_VALUE_STRING
,wxT("City"),
2888 new wxDbGridColInfo( 4,wxGRID_VALUE_STRING
,wxT("State"),
2889 new wxDbGridColInfo( 5,wxGRID_VALUE_STRING
,wxT("PostCode"),
2890 new wxDbGridColInfo( 6,wxGRID_VALUE_STRING
,wxT("Country"),
2891 new wxDbGridColInfo( 7,wxGRID_VALUE_DBAUTO
,wxT("Join Date"),
2892 new wxDbGridColInfo( 8,wxGRID_VALUE_BOOL
, wxT("Developer"),
2893 new wxDbGridColInfo( 9,wxGRID_VALUE_NUMBER
,wxT("Contributions"),
2894 new wxDbGridColInfo(10,wxGRID_VALUE_NUMBER
,wxT("Lines Of Code"),
2896 new wxDbGridColInfo(11,NativeLangChoice
, wxT("Native Language"),NULL
))))))))))));
2898 new wxDbGridColInfo(11,wxGRID_VALUE_NUMBER
,wxT("Native Language"),NULL
))))))))))));
2901 Ccontact
*Contact
= new Ccontact();
2902 //wxGetApp().Contact
2906 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"), wxT("Error..."), wxOK
| wxICON_EXCLAMATION
);
2910 if (!Contact
->Open())
2912 if (Contact
->GetDb()->TableExists(CONTACT_TABLE_NAME
, Contact
->GetDb()->GetUsername(),
2913 wxGetApp().DbConnectInf
->GetDefaultDir()))
2916 tStr
.Printf(wxT("Unable to open the table '%s'.\n\n"),CONTACT_TABLE_NAME
);
2917 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
2918 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2924 // Execute the following query using the cursor designated
2925 // for full table query
2926 Contact
->SetRowMode(wxDbTable::WX_ROW_MODE_QUERY
);
2928 if (!Contact
->Query())
2931 tStr
= wxT("ODBC error during Query()\n\n");
2932 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__FILE__
,__LINE__
),
2933 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2937 // No data has been read in from the database yet, so
2938 // we need to initialize the data members to valid values
2939 // so Fit() can correctly size the grid
2940 Contact
->Initialize();
2942 wxDbGridTableBase
* db
= new wxDbGridTableBase(Contact
, cols
, wxUSE_QUERY
, TRUE
);
2946 grid
->SetTable(db
,TRUE
);
2947 grid
->SetMargins(0, 0);
2950 wxSize size
= grid
->GetSize();
2953 SetClientSize(size
);
2956 } // DbGridFrame::Initialize()
2958 #endif // #if wxUSE_NEW_GRID
2961 TEST CODE FOR TESTING THE wxDbCreateDataSource() FUNCTION
2964 result = wxDbCreateDataSource(wxT("Microsoft Access Driver (*.mdb)"),wxT("GLT-TEST2"),wxT("GLT-Descrip"),FALSE,wxT(""),this);
2967 // check for errors caused by ConfigDSN based functions
2970 wxChar errMsg[500+1];
2971 errMsg[0] = wxT('\0');
2973 SQLInstallerError(1,&retcode,errMsg,500,&cb);
2975 wxMessageBox(wxT("FAILED creating data source"),wxT("FAILED"));
2978 wxMessageBox(wxT("SUCCEEDED creating data source"),wxT("SUCCESS"));