1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxWidgets 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"
38 #if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMAC__)
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 */
65 #ifdef wxODBC_BLOB_SUPPORT
67 #include "wx/mstream.h"
69 #include "wx/bitmap.h"
70 #include "wx/statbmp.h"
74 #error Sample cannot be compiled unless setup.h has wxUSE_ODBC set to 1
78 bool DataTypeSupported(wxDb
*pDb
, SWORD datatype
, wxString
*nativeDataTypeName
)
80 wxDbSqlTypeInfo sqlTypeInfo
;
82 bool breakpoint
= false;
84 *nativeDataTypeName
= wxEmptyString
;
85 if (pDb
->GetDataTypeInfo(datatype
, sqlTypeInfo
))
87 *nativeDataTypeName
= sqlTypeInfo
.TypeName
;
93 } // GetDataTypesSupported();
97 void CheckSupportForAllDataTypes(wxDb
*pDb
)
99 wxString nativeDataTypeName
;
101 wxLogMessage(wxT("\nThe following datatypes are supported by the\ndatabase you are currently connected to:"));
103 if (DataTypeSupported(pDb
,SQL_C_BINARY
, &nativeDataTypeName
))
105 nativeDataTypeName
= wxT("SQL_C_BINARY (") + nativeDataTypeName
;
106 nativeDataTypeName
+= wxT(")\n");
107 wxLogMessage(nativeDataTypeName
);
111 if (DataTypeSupported(pDb
,SQL_C_BIT
, &nativeDataTypeName
))
113 nativeDataTypeName
= wxT("SQL_C_BIT (") + nativeDataTypeName
;
114 nativeDataTypeName
+= wxT(")\n");
115 wxLogMessage(nativeDataTypeName
);
118 #ifdef SQL_C_BOOKMARK
119 if (DataTypeSupported(pDb
,SQL_C_BOOKMARK
, &nativeDataTypeName
))
121 nativeDataTypeName
= wxT("SQL_C_BOOKMARK (") + nativeDataTypeName
;
122 nativeDataTypeName
+= wxT(")\n");
123 wxLogMessage(nativeDataTypeName
);
127 if (DataTypeSupported(pDb
,SQL_C_CHAR
, &nativeDataTypeName
))
129 nativeDataTypeName
= wxT("SQL_C_CHAR (") + nativeDataTypeName
;
130 nativeDataTypeName
+= wxT(")\n");
131 wxLogMessage(nativeDataTypeName
);
135 if (DataTypeSupported(pDb
,SQL_C_DATE
, &nativeDataTypeName
))
137 nativeDataTypeName
= wxT("SQL_C_DATE (") + nativeDataTypeName
;
138 nativeDataTypeName
+= wxT(")\n");
139 wxLogMessage(nativeDataTypeName
);
143 if (DataTypeSupported(pDb
,SQL_C_DEFAULT
, &nativeDataTypeName
))
145 nativeDataTypeName
= wxT("SQL_C_DEFAULT (") + nativeDataTypeName
;
146 nativeDataTypeName
+= wxT(")\n");
147 wxLogMessage(nativeDataTypeName
);
151 if (DataTypeSupported(pDb
,SQL_C_DOUBLE
, &nativeDataTypeName
))
153 nativeDataTypeName
= wxT("SQL_C_DOUBLE (") + nativeDataTypeName
;
154 nativeDataTypeName
+= wxT(")\n");
155 wxLogMessage(nativeDataTypeName
);
159 if (DataTypeSupported(pDb
,SQL_C_FLOAT
, &nativeDataTypeName
))
161 nativeDataTypeName
= wxT("SQL_C_FLOAT (") + nativeDataTypeName
;
162 nativeDataTypeName
+= wxT(")\n");
163 wxLogMessage(nativeDataTypeName
);
167 if (DataTypeSupported(pDb
,SQL_C_GUID
, &nativeDataTypeName
))
169 nativeDataTypeName
= wxT("SQL_C_GUID (") + nativeDataTypeName
;
170 nativeDataTypeName
+= wxT(")\n");
171 wxLogMessage(nativeDataTypeName
);
174 #ifdef SQL_C_INTERVAL_DAY
175 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_DAY
, &nativeDataTypeName
))
177 nativeDataTypeName
= wxT("SQL_C_INTERVAL_DAY (") + nativeDataTypeName
;
178 nativeDataTypeName
+= wxT(")\n");
179 wxLogMessage(nativeDataTypeName
);
182 #ifdef SQL_C_INTERVAL_DAY_TO_HOUR
183 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_DAY_TO_HOUR
, &nativeDataTypeName
))
185 nativeDataTypeName
= wxT("SQL_C_INTERVAL_DAY_TO_HOUR (") + nativeDataTypeName
;
186 nativeDataTypeName
+= wxT(")\n");
187 wxLogMessage(nativeDataTypeName
);
190 #ifdef SQL_C_INTERVAL_DAY_TO_MINUTE
191 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_DAY_TO_MINUTE
, &nativeDataTypeName
))
193 nativeDataTypeName
= wxT("SQL_C_INTERVAL_DAY_TO_MINUTE (") + nativeDataTypeName
;
194 nativeDataTypeName
+= wxT(")\n");
195 wxLogMessage(nativeDataTypeName
);
198 #ifdef SQL_C_INTERVAL_DAY_TO_SECOND
199 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_DAY_TO_SECOND
, &nativeDataTypeName
))
201 nativeDataTypeName
= wxT("SQL_C_INTERVAL_DAY_TO_SECOND (") + nativeDataTypeName
;
202 nativeDataTypeName
+= wxT(")\n");
203 wxLogMessage(nativeDataTypeName
);
206 #ifdef SQL_C_INTERVAL_HOUR
207 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_HOUR
, &nativeDataTypeName
))
209 nativeDataTypeName
= wxT("SQL_C_INTERVAL_HOUR (") + nativeDataTypeName
;
210 nativeDataTypeName
+= wxT(")\n");
211 wxLogMessage(nativeDataTypeName
);
214 #ifdef SQL_C_INTERVAL_HOUR_TO_MINUTE
215 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_HOUR_TO_MINUTE
, &nativeDataTypeName
))
217 nativeDataTypeName
= wxT("SQL_C_INTERVAL_HOUR_TO_MINUTE (") + nativeDataTypeName
;
218 nativeDataTypeName
+= wxT(")\n");
219 wxLogMessage(nativeDataTypeName
);
222 #ifdef SQL_C_INTERVAL_HOUR_TO_SECOND
223 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_HOUR_TO_SECOND
, &nativeDataTypeName
))
225 nativeDataTypeName
= wxT("SQL_C_INTERVAL_HOUR_TO_SECOND (") + nativeDataTypeName
;
226 nativeDataTypeName
+= wxT(")\n");
227 wxLogMessage(nativeDataTypeName
);
230 #ifdef SQL_C_INTERVAL_MINUTE
231 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_MINUTE
, &nativeDataTypeName
))
233 nativeDataTypeName
= wxT("SQL_C_INTERVAL_MINUTE (") + nativeDataTypeName
;
234 nativeDataTypeName
+= wxT(")\n");
235 wxLogMessage(nativeDataTypeName
);
238 #ifdef SQL_C_INTERVAL_MINUTE_TO_SECOND
239 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_MINUTE_TO_SECOND
, &nativeDataTypeName
))
241 nativeDataTypeName
= wxT("SQL_C_INTERVAL_MINUTE_TO_SECOND (") + nativeDataTypeName
;
242 nativeDataTypeName
+= wxT(")\n");
243 wxLogMessage(nativeDataTypeName
);
246 #ifdef SQL_C_INTERVAL_MONTH
247 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_MONTH
, &nativeDataTypeName
))
249 nativeDataTypeName
= wxT("SQL_C_INTERVAL_MONTH (") + nativeDataTypeName
;
250 nativeDataTypeName
+= wxT(")\n");
251 wxLogMessage(nativeDataTypeName
);
254 #ifdef SQL_C_INTERVAL_SECOND
255 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_SECOND
, &nativeDataTypeName
))
257 nativeDataTypeName
= wxT("SQL_C_INTERVAL_SECOND (") + nativeDataTypeName
;
258 nativeDataTypeName
+= wxT(")\n");
259 wxLogMessage(nativeDataTypeName
);
262 #ifdef SQL_C_INTERVAL_YEAR
263 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_YEAR
, &nativeDataTypeName
))
265 nativeDataTypeName
= wxT("SQL_C_INTERVAL_YEAR (") + nativeDataTypeName
;
266 nativeDataTypeName
+= wxT(")\n");
267 wxLogMessage(nativeDataTypeName
);
270 #ifdef SQL_C_INTERVAL_YEAR_TO_MONTH
271 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_YEAR_TO_MONTH
, &nativeDataTypeName
))
273 nativeDataTypeName
= wxT("SQL_C_INTERVAL_YEAR_TO_MONTH (") + nativeDataTypeName
;
274 nativeDataTypeName
+= wxT(")\n");
275 wxLogMessage(nativeDataTypeName
);
279 if (DataTypeSupported(pDb
,SQL_C_LONG
, &nativeDataTypeName
))
281 nativeDataTypeName
= wxT("SQL_C_LONG (") + nativeDataTypeName
;
282 nativeDataTypeName
+= wxT(")\n");
283 wxLogMessage(nativeDataTypeName
);
287 if (DataTypeSupported(pDb
,SQL_C_NUMERIC
, &nativeDataTypeName
))
289 nativeDataTypeName
= wxT("SQL_C_NUMERIC (") + nativeDataTypeName
;
290 nativeDataTypeName
+= wxT(")\n");
291 wxLogMessage(nativeDataTypeName
);
295 if (DataTypeSupported(pDb
,SQL_C_SBIGINT
, &nativeDataTypeName
))
297 nativeDataTypeName
= wxT("SQL_C_SBIGINT (") + nativeDataTypeName
;
298 nativeDataTypeName
+= wxT(")\n");
299 wxLogMessage(nativeDataTypeName
);
303 if (DataTypeSupported(pDb
,SQL_C_SHORT
, &nativeDataTypeName
))
305 nativeDataTypeName
= wxT("SQL_C_SHORT (") + nativeDataTypeName
;
306 nativeDataTypeName
+= wxT(")\n");
307 wxLogMessage(nativeDataTypeName
);
311 if (DataTypeSupported(pDb
,SQL_C_SLONG
, &nativeDataTypeName
))
313 nativeDataTypeName
= wxT("SQL_C_SLONG (") + nativeDataTypeName
;
314 nativeDataTypeName
+= wxT(")\n");
315 wxLogMessage(nativeDataTypeName
);
319 if (DataTypeSupported(pDb
,SQL_C_SSHORT
, &nativeDataTypeName
))
321 nativeDataTypeName
= wxT("SQL_C_SSHORT (") + nativeDataTypeName
;
322 nativeDataTypeName
+= wxT(")\n");
323 wxLogMessage(nativeDataTypeName
);
326 #ifdef SQL_C_STINYINT
327 if (DataTypeSupported(pDb
,SQL_C_STINYINT
, &nativeDataTypeName
))
329 nativeDataTypeName
= wxT("SQL_C_STINYINT (") + nativeDataTypeName
;
330 nativeDataTypeName
+= wxT(")\n");
331 wxLogMessage(nativeDataTypeName
);
335 if (DataTypeSupported(pDb
,SQL_C_TIME
, &nativeDataTypeName
))
337 nativeDataTypeName
= wxT("SQL_C_TIME (") + nativeDataTypeName
;
338 nativeDataTypeName
+= wxT(")\n");
339 wxLogMessage(nativeDataTypeName
);
342 #ifdef SQL_C_TIMESTAMP
343 if (DataTypeSupported(pDb
,SQL_C_TIMESTAMP
, &nativeDataTypeName
))
345 nativeDataTypeName
= wxT("SQL_C_TIMESTAMP (") + nativeDataTypeName
;
346 nativeDataTypeName
+= wxT(")\n");
347 wxLogMessage(nativeDataTypeName
);
351 if (DataTypeSupported(pDb
,SQL_C_TINYINT
, &nativeDataTypeName
))
353 nativeDataTypeName
= wxT("SQL_C_TINYINT (") + nativeDataTypeName
;
354 nativeDataTypeName
+= wxT(")\n");
355 wxLogMessage(nativeDataTypeName
);
358 #ifdef SQL_C_TYPE_DATE
359 if (DataTypeSupported(pDb
,SQL_C_TYPE_DATE
, &nativeDataTypeName
))
361 nativeDataTypeName
= wxT("SQL_C_TYPE_DATE (") + nativeDataTypeName
;
362 nativeDataTypeName
+= wxT(")\n");
363 wxLogMessage(nativeDataTypeName
);
366 #ifdef SQL_C_TYPE_TIME
367 if (DataTypeSupported(pDb
,SQL_C_TYPE_TIME
, &nativeDataTypeName
))
369 nativeDataTypeName
= wxT("SQL_C_TYPE_TIME (") + nativeDataTypeName
;
370 nativeDataTypeName
+= wxT(")\n");
371 wxLogMessage(nativeDataTypeName
);
374 #ifdef SQL_C_TYPE_TIMESTAMP
375 if (DataTypeSupported(pDb
,SQL_C_TYPE_TIMESTAMP
, &nativeDataTypeName
))
377 nativeDataTypeName
= wxT("SQL_C_TYPE_TIMESTAMP (") + nativeDataTypeName
;
378 nativeDataTypeName
+= wxT(")\n");
379 wxLogMessage(nativeDataTypeName
);
383 if (DataTypeSupported(pDb
,SQL_C_UBIGINT
, &nativeDataTypeName
))
385 nativeDataTypeName
= wxT("SQL_C_UBIGINT (") + nativeDataTypeName
;
386 nativeDataTypeName
+= wxT(")\n");
387 wxLogMessage(nativeDataTypeName
);
391 if (DataTypeSupported(pDb
,SQL_C_ULONG
, &nativeDataTypeName
))
393 nativeDataTypeName
= wxT("SQL_C_ULONG (") + nativeDataTypeName
;
394 nativeDataTypeName
+= wxT(")\n");
395 wxLogMessage(nativeDataTypeName
);
399 if (DataTypeSupported(pDb
,SQL_C_USHORT
, &nativeDataTypeName
))
401 nativeDataTypeName
= wxT("SQL_C_USHORT (") + nativeDataTypeName
;
402 nativeDataTypeName
+= wxT(")\n");
403 wxLogMessage(nativeDataTypeName
);
406 #ifdef SQL_C_UTINYINT
407 if (DataTypeSupported(pDb
,SQL_C_UTINYINT
, &nativeDataTypeName
))
409 nativeDataTypeName
= wxT("SQL_C_UTINYINT (") + nativeDataTypeName
;
410 nativeDataTypeName
+= wxT(")\n");
411 wxLogMessage(nativeDataTypeName
);
414 #ifdef SQL_C_VARBOOKMARK
415 if (DataTypeSupported(pDb
,SQL_C_VARBOOKMARK
, &nativeDataTypeName
))
417 nativeDataTypeName
= wxT("SQL_C_VARBOOKMARK (") + nativeDataTypeName
;
418 nativeDataTypeName
+= wxT(")\n");
419 wxLogMessage(nativeDataTypeName
);
423 if (DataTypeSupported(pDb
,SQL_C_WXCHAR
, &nativeDataTypeName
))
425 nativeDataTypeName
= wxT("SQL_C_WXCHAR (") + nativeDataTypeName
;
426 nativeDataTypeName
+= wxT(")\n");
427 wxLogMessage(nativeDataTypeName
);
431 // Extended SQL types
433 if (DataTypeSupported(pDb
,SQL_DATE
, &nativeDataTypeName
))
435 nativeDataTypeName
= wxT("SQL_DATE (") + nativeDataTypeName
;
436 nativeDataTypeName
+= wxT(")\n");
437 wxLogMessage(nativeDataTypeName
);
441 if (DataTypeSupported(pDb
,SQL_INTERVAL
, &nativeDataTypeName
))
443 nativeDataTypeName
= wxT("SQL_INTERVAL (") + nativeDataTypeName
;
444 nativeDataTypeName
+= wxT(")\n");
445 wxLogMessage(nativeDataTypeName
);
449 if (DataTypeSupported(pDb
,SQL_TIME
, &nativeDataTypeName
))
451 nativeDataTypeName
= wxT("SQL_TIME (") + nativeDataTypeName
;
452 nativeDataTypeName
+= wxT(")\n");
453 wxLogMessage(nativeDataTypeName
);
457 if (DataTypeSupported(pDb
,SQL_TIMESTAMP
, &nativeDataTypeName
))
459 nativeDataTypeName
= wxT("SQL_TIMESTAMP (") + nativeDataTypeName
;
460 nativeDataTypeName
+= wxT(")\n");
461 wxLogMessage(nativeDataTypeName
);
464 #ifdef SQL_LONGVARCHAR
465 if (DataTypeSupported(pDb
,SQL_LONGVARCHAR
, &nativeDataTypeName
))
467 nativeDataTypeName
= wxT("SQL_LONGVARCHAR (") + nativeDataTypeName
;
468 nativeDataTypeName
+= wxT(")\n");
469 wxLogMessage(nativeDataTypeName
);
473 if (DataTypeSupported(pDb
,SQL_BINARY
, &nativeDataTypeName
))
475 nativeDataTypeName
= wxT("SQL_BINARY (") + nativeDataTypeName
;
476 nativeDataTypeName
+= wxT(")\n");
477 wxLogMessage(nativeDataTypeName
);
481 if (DataTypeSupported(pDb
,SQL_VARBINARY
, &nativeDataTypeName
))
483 nativeDataTypeName
= wxT("SQL_VARBINARY (") + nativeDataTypeName
;
484 nativeDataTypeName
+= wxT(")\n");
485 wxLogMessage(nativeDataTypeName
);
488 #ifdef SQL_LONGVARBINARY
489 if (DataTypeSupported(pDb
,SQL_LONGVARBINARY
, &nativeDataTypeName
))
491 nativeDataTypeName
= wxT("SQL_LOGVARBINARY (") + nativeDataTypeName
;
492 nativeDataTypeName
+= wxT(")\n");
493 wxLogMessage(nativeDataTypeName
);
497 if (DataTypeSupported(pDb
,SQL_BIGINT
, &nativeDataTypeName
))
499 nativeDataTypeName
= wxT("SQL_BIGINT (") + nativeDataTypeName
;
500 nativeDataTypeName
+= wxT(")\n");
501 wxLogMessage(nativeDataTypeName
);
505 if (DataTypeSupported(pDb
,SQL_TINYINT
, &nativeDataTypeName
))
507 nativeDataTypeName
= wxT("SQL_TINYINT (") + nativeDataTypeName
;
508 nativeDataTypeName
+= wxT(")\n");
509 wxLogMessage(nativeDataTypeName
);
513 if (DataTypeSupported(pDb
,SQL_BIT
, &nativeDataTypeName
))
515 nativeDataTypeName
= wxT("SQL_BIT (") + nativeDataTypeName
;
516 nativeDataTypeName
+= wxT(")\n");
517 wxLogMessage(nativeDataTypeName
);
521 if (DataTypeSupported(pDb
,SQL_GUID
, &nativeDataTypeName
))
523 nativeDataTypeName
= wxT("SQL_GUID (") + nativeDataTypeName
;
524 nativeDataTypeName
+= wxT(")\n");
525 wxLogMessage(nativeDataTypeName
);
530 if (DataTypeSupported(pDb
,SQL_CHAR
, &nativeDataTypeName
))
532 nativeDataTypeName
= wxT("SQL_CHAR (") + nativeDataTypeName
;
533 nativeDataTypeName
+= wxT(")\n");
534 wxLogMessage(nativeDataTypeName
);
538 if (DataTypeSupported(pDb
,SQL_INTEGER
, &nativeDataTypeName
))
540 nativeDataTypeName
= wxT("SQL_INTEGER (") + nativeDataTypeName
;
541 nativeDataTypeName
+= wxT(")\n");
542 wxLogMessage(nativeDataTypeName
);
546 if (DataTypeSupported(pDb
,SQL_SMALLINT
, &nativeDataTypeName
))
548 nativeDataTypeName
= wxT("SQL_SAMLLINT (") + nativeDataTypeName
;
549 nativeDataTypeName
+= wxT(")\n");
550 wxLogMessage(nativeDataTypeName
);
554 if (DataTypeSupported(pDb
,SQL_REAL
, &nativeDataTypeName
))
556 nativeDataTypeName
= wxT("SQL_REAL (") + nativeDataTypeName
;
557 nativeDataTypeName
+= wxT(")\n");
558 wxLogMessage(nativeDataTypeName
);
562 if (DataTypeSupported(pDb
,SQL_DOUBLE
, &nativeDataTypeName
))
564 nativeDataTypeName
= wxT("SQL_DOUBLE (") + nativeDataTypeName
;
565 nativeDataTypeName
+= wxT(")\n");
566 wxLogMessage(nativeDataTypeName
);
570 if (DataTypeSupported(pDb
,SQL_NUMERIC
, &nativeDataTypeName
))
572 nativeDataTypeName
= wxT("SQL_NUMERIC (") + nativeDataTypeName
;
573 nativeDataTypeName
+= wxT(")\n");
574 wxLogMessage(nativeDataTypeName
);
578 if (DataTypeSupported(pDb
,SQL_DATE
, &nativeDataTypeName
))
580 nativeDataTypeName
= wxT("SQL_DATE (") + nativeDataTypeName
;
581 nativeDataTypeName
+= wxT(")\n");
582 wxLogMessage(nativeDataTypeName
);
586 if (DataTypeSupported(pDb
,SQL_TIME
, &nativeDataTypeName
))
588 nativeDataTypeName
= wxT("SQL_TIME (") + nativeDataTypeName
;
589 nativeDataTypeName
+= wxT(")\n");
590 wxLogMessage(nativeDataTypeName
);
594 if (DataTypeSupported(pDb
,SQL_TIMESTAMP
, &nativeDataTypeName
))
596 nativeDataTypeName
= wxT("SQL_TIMESTAMP (") + nativeDataTypeName
;
597 nativeDataTypeName
+= wxT(")\n");
598 wxLogMessage(nativeDataTypeName
);
602 if (DataTypeSupported(pDb
,SQL_VARCHAR
, &nativeDataTypeName
))
604 nativeDataTypeName
= wxT("SQL_VARCHAR (") + nativeDataTypeName
;
605 nativeDataTypeName
+= wxT(")\n");
606 wxLogMessage(nativeDataTypeName
);
612 if (DataTypeSupported(pDb
,SQL_C_TCHAR
, &nativeDataTypeName
))
614 nativeDataTypeName
= wxT("SQL_C_TCHAR (") + nativeDataTypeName
;
615 nativeDataTypeName
+= wxT(")\n");
616 wxLogMessage(nativeDataTypeName
);
620 wxLogMessage(wxT("Done\n"));
621 } // CheckSupportForAllDataTypes()
624 bool DatabaseDemoApp::OnInit()
629 // Create the main frame window
630 DemoFrame
= new DatabaseDemoFrame(NULL
, wxT("wxWidgets Database Demo"), wxPoint(50, 50), wxSize(537, 530));
633 DemoFrame
->SetIcon(wxICON(db
));
636 wxMenu
*file_menu
= new wxMenu
;
637 file_menu
->Append(FILE_CREATE_ID
, wxT("&Create CONTACT table"));
638 file_menu
->Append(FILE_RECREATE_TABLE
, wxT("&Recreate CONTACT table"));
639 file_menu
->Append(FILE_RECREATE_INDEXES
, wxT("&Recreate CONTACT indexes"));
641 file_menu
->Append(FILE_DBGRID_TABLE
, wxT("&Open DB Grid example"));
643 file_menu
->Append(FILE_EXIT
, wxT("E&xit"));
645 wxMenu
*edit_menu
= new wxMenu
;
646 edit_menu
->Append(EDIT_PARAMETERS
, wxT("&Parameters..."));
648 wxMenu
*help_menu
= new wxMenu
;
649 help_menu
->Append(HELP_ABOUT
, wxT("&About"));
651 wxMenuBar
*menu_bar
= new wxMenuBar
;
652 menu_bar
->Append(file_menu
, wxT("&File"));
653 menu_bar
->Append(edit_menu
, wxT("&Edit"));
654 menu_bar
->Append(help_menu
, wxT("&Help"));
655 DemoFrame
->SetMenuBar(menu_bar
);
657 params
.ODBCSource
[0] = 0;
658 params
.UserName
[0] = 0;
659 params
.Password
[0] = 0;
660 params
.DirPath
[0] = 0;
662 #ifdef wxODBC_BLOB_SUPPORT
663 wxInitAllImageHandlers();
664 wxImage::InitStandardHandlers();
665 wxBitmap::InitStandardHandlers();
669 DemoFrame
->Show(true);
671 // Passing NULL for the SQL environment handle causes
672 // the wxDbConnectInf constructor to obtain a handle
675 // WARNING: Be certain that you do not free this handle
676 // directly with SQLFreeEnv(). Use either the
677 // method ::FreeHenv() or delete the DbConnectInf.
678 DbConnectInf
= new wxDbConnectInf(NULL
, params
.ODBCSource
, params
.UserName
,
679 params
.Password
, params
.DirPath
);
681 if (!DbConnectInf
|| !DbConnectInf
->GetHenv())
683 wxMessageBox(wxT("Unable to define data source connection info."), wxT("DB CONNECTION ERROR..."),wxOK
| wxICON_EXCLAMATION
);
684 wxDELETE(DbConnectInf
);
687 if (!ReadParamFile(params
))
688 DemoFrame
->BuildParameterDialog(NULL
);
690 if (!wxStrlen(params
.ODBCSource
))
692 wxDELETE(DbConnectInf
);
696 DbConnectInf
->SetDsn(params
.ODBCSource
);
697 DbConnectInf
->SetUserID(params
.UserName
);
698 DbConnectInf
->SetPassword(params
.Password
);
699 DbConnectInf
->SetDefaultDir(params
.DirPath
);
701 READONLY_DB
= wxDbGetConnection(DbConnectInf
);
702 if (READONLY_DB
== 0)
704 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
);
705 DemoFrame
->BuildParameterDialog(NULL
);
706 wxDELETE(DbConnectInf
);
707 wxMessageBox(wxT("Now exiting program.\n\nRestart program to try any new settings."),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
711 DemoFrame
->BuildEditorDialog();
714 DemoFrame
->Refresh();
717 } // DatabaseDemoApp::OnInit()
721 * Remove CR or CR/LF from a character string.
723 wxChar
* wxRemoveLineTerminator(wxChar
* aString
)
725 int len
= wxStrlen(aString
);
726 while (len
> 0 && (aString
[len
-1] == wxT('\r') || aString
[len
-1] == wxT('\n'))) {
727 aString
[len
-1] = wxT('\0');
734 bool DatabaseDemoApp::ReadParamFile(Cparameters
¶ms
)
737 if ((paramFile
= wxFopen(PARAM_FILENAME
, wxT("r"))) == NULL
)
740 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
);
741 wxMessageBox(tStr
,wxT("File I/O Error..."),wxOK
| wxICON_EXCLAMATION
);
746 wxChar buffer
[1000+1];
747 wxFgets(buffer
, sizeof(params
.ODBCSource
), paramFile
);
748 wxRemoveLineTerminator(buffer
);
749 wxStrcpy(params
.ODBCSource
,buffer
);
751 wxFgets(buffer
, sizeof(params
.UserName
), paramFile
);
752 wxRemoveLineTerminator(buffer
);
753 wxStrcpy(params
.UserName
,buffer
);
755 wxFgets(buffer
, sizeof(params
.Password
), paramFile
);
756 wxRemoveLineTerminator(buffer
);
757 wxStrcpy(params
.Password
,buffer
);
759 wxFgets(buffer
, sizeof(params
.DirPath
), paramFile
);
760 wxRemoveLineTerminator(buffer
);
761 wxStrcpy(params
.DirPath
,buffer
);
766 } // DatabaseDemoApp::ReadParamFile()
769 bool DatabaseDemoApp::WriteParamFile(Cparameters
&WXUNUSED(params
))
772 if ((paramFile
= wxFopen(PARAM_FILENAME
, wxT("wt"))) == NULL
)
775 tStr
.Printf(wxT("Unable to write/overwrite '%s'."),PARAM_FILENAME
);
776 wxMessageBox(tStr
,wxT("File I/O Error..."),wxOK
| wxICON_EXCLAMATION
);
780 wxFputs(wxGetApp().params
.ODBCSource
, paramFile
);
781 wxFputc(wxT('\n'), paramFile
);
782 wxFputs(wxGetApp().params
.UserName
, paramFile
);
783 wxFputc(wxT('\n'), paramFile
);
784 wxFputs(wxGetApp().params
.Password
, paramFile
);
785 wxFputc(wxT('\n'), paramFile
);
786 wxFputs(wxGetApp().params
.DirPath
, paramFile
);
787 wxFputc(wxT('\n'), paramFile
);
791 } // DatabaseDemoApp::WriteParamFile()
794 void DatabaseDemoApp::CreateDataTable(bool recreate
)
798 Ok
= (wxMessageBox(wxT("Any data currently residing in the table will be erased.\n\nAre you sure?"),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
807 Contact
->GetDb()->RollbackTrans(); // Make sure the current cursor is in a known/stable state
809 if (!Contact
->CreateTable(recreate
))
813 tStr
= wxT("Error creating CONTACTS table.\nTable was not created.\n\n");
814 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),Contact
->GetDb(),__TFILE__
,__LINE__
),
815 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
821 if (!Contact
->CreateIndexes(recreate
))
825 tStr
= wxT("Error creating CONTACTS indexes.\nIndexes will be unavailable.\n\n");
826 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),Contact
->GetDb(),__TFILE__
,__LINE__
),
827 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
836 wxMessageBox(wxT("Table and index(es) were successfully created."),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
837 } // DatabaseDemoApp::CreateDataTable()
840 BEGIN_EVENT_TABLE(DatabaseDemoFrame
, wxFrame
)
841 EVT_MENU(FILE_CREATE_ID
, DatabaseDemoFrame::OnCreate
)
842 EVT_MENU(FILE_RECREATE_TABLE
, DatabaseDemoFrame::OnRecreateTable
)
843 EVT_MENU(FILE_RECREATE_INDEXES
, DatabaseDemoFrame::OnRecreateIndexes
)
845 EVT_MENU(FILE_DBGRID_TABLE
, DatabaseDemoFrame::OnDbGridTable
)
847 EVT_MENU(FILE_EXIT
, DatabaseDemoFrame::OnExit
)
848 EVT_MENU(EDIT_PARAMETERS
, DatabaseDemoFrame::OnEditParameters
)
849 EVT_MENU(HELP_ABOUT
, DatabaseDemoFrame::OnAbout
)
850 EVT_CLOSE(DatabaseDemoFrame::OnCloseWindow
)
854 // DatabaseDemoFrame constructor
855 DatabaseDemoFrame::DatabaseDemoFrame(wxFrame
*frame
, const wxString
& title
,
856 const wxPoint
& pos
, const wxSize
& size
):
857 wxFrame(frame
, wxID_ANY
, title
, pos
, size
)
859 // Put any code in necessary for initializing the main frame here
864 delete wxLog::SetActiveTarget(new wxLogStderr
);
867 } // DatabaseDemoFrame constructor
869 DatabaseDemoFrame::~DatabaseDemoFrame()
872 delete wxLog::SetActiveTarget(NULL
);
874 } // DatabaseDemoFrame destructor
877 void DatabaseDemoFrame::OnCreate(wxCommandEvent
& WXUNUSED(event
))
879 wxGetApp().CreateDataTable(false);
880 } // DatabaseDemoFrame::OnCreate()
883 void DatabaseDemoFrame::OnRecreateTable(wxCommandEvent
& WXUNUSED(event
))
885 wxGetApp().CreateDataTable(true);
886 } // DatabaseDemoFrame::OnRecreate()
889 void DatabaseDemoFrame::OnRecreateIndexes(wxCommandEvent
& WXUNUSED(event
))
891 wxGetApp().Contact
->GetDb()->RollbackTrans(); // Make sure the current cursor is in a known/stable state
893 if (!wxGetApp().Contact
->CreateIndexes(true))
898 tStr
= wxT("Error creating CONTACTS indexes.\nNew indexes will be unavailable.\n\n");
899 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
900 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
904 wxMessageBox(wxT("Index(es) were successfully recreated."),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
906 } // DatabaseDemoFrame::OnRecreateIndexes()
910 void DatabaseDemoFrame::OnDbGridTable(wxCommandEvent
& WXUNUSED(event
))
912 DbGridFrame
*frame
= new DbGridFrame(this);
913 if (frame
->Initialize())
920 void DatabaseDemoFrame::OnExit(wxCommandEvent
& WXUNUSED(event
))
923 } // DatabaseDemoFrame::OnExit()
926 void DatabaseDemoFrame::OnEditParameters(wxCommandEvent
& WXUNUSED(event
))
928 if ((pEditorDlg
->mode
!= mCreate
) && (pEditorDlg
->mode
!= mEdit
))
929 BuildParameterDialog(this);
931 wxMessageBox(wxT("Cannot change database parameters while creating or editing a record"),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
932 } // DatabaseDemoFrame::OnEditParameters()
935 void DatabaseDemoFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
937 wxMessageBox(wxT("wxWidgets sample program for database classes\n\nContributed on 27 July 1998"),wxT("About..."),wxOK
| wxICON_INFORMATION
);
938 } // DatabaseDemoFrame::OnAbout()
941 // Put any additional checking necessary to make certain it is alright
942 // to close the program here that is not done elsewhere
943 void DatabaseDemoFrame::OnCloseWindow(wxCloseEvent
& event
)
946 if (pEditorDlg
&& pEditorDlg
->Close())
957 wxDELETE(wxGetApp().Contact
);
959 // This function will close all the connections to the database that have been
960 // previously cached.
961 wxDbCloseConnections();
963 // Deletion of the wxDbConnectInf instance must be the LAST thing done that
964 // has anything to do with the database. Deleting this before disconnecting,
965 // freeing/closing connections, etc will result in a crash!
966 wxDELETE(wxGetApp().DbConnectInf
);
970 } // DatabaseDemoFrame::OnCloseWindow()
973 void DatabaseDemoFrame::BuildEditorDialog()
976 pEditorDlg
= new CeditorDlg(this);
979 pEditorDlg
->Initialize();
980 if (!pEditorDlg
->initialized
)
984 wxMessageBox(wxT("Unable to initialize the editor dialog for some reason"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
990 wxMessageBox(wxT("Unable to create the editor dialog for some reason"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
993 } // DatabaseDemoFrame::BuildEditorDialog()
996 void DatabaseDemoFrame::BuildParameterDialog(wxWindow
*parent
)
998 pParamDlg
= new CparameterDlg(parent
);
1001 wxMessageBox(wxT("Unable to create the parameter dialog for some reason"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
1002 } // DatabaseDemoFrame::BuildParameterDialog()
1006 * Constructor note: If no wxDb object is passed in, a new connection to the database
1007 * is created for this instance of Ccontact. This can be a slow process depending
1008 * on the database engine being used, and some database engines have a limit on the
1009 * number of connections (either hard limits, or license restricted) so care should
1010 * be used to use as few connections as is necessary.
1012 * IMPORTANT: Objects which share a wxDb pointer are ALL acted upon whenever a member
1013 * function of pDb is called (i.e. CommitTrans() or RollbackTrans(), so if modifying
1014 * or creating a table objects which use the same pDb, know that all the objects
1015 * will be committed or rolled back when any of the objects has this function call made.
1017 Ccontact::Ccontact (wxDb
*pwxDb
) : wxDbTable(pwxDb
? pwxDb
: wxDbGetConnection(wxGetApp().DbConnectInf
),
1018 CONTACT_TABLE_NAME
, CONTACT_NO_COLS
, (const wxString
&)wxEmptyString
,
1019 !wxDB_QUERY_ONLY
, wxGetApp().DbConnectInf
->GetDefaultDir())
1021 // This is used to represent whether the database connection should be released
1022 // when this instance of the object is deleted. If using the same connection
1023 // for multiple instance of database objects, then the connection should only be
1024 // released when the last database instance using the connection is deleted
1025 freeDbConn
= !pwxDb
;
1028 GetDb()->SetSqlLogging(sqlLogON
);
1032 } // Ccontact Constructor
1035 void Ccontact::Initialize()
1044 JoinDate
.year
= 1980;
1048 JoinDate
.minute
= 0;
1049 JoinDate
.second
= 0;
1050 JoinDate
.fraction
= 0;
1051 NativeLanguage
= langENGLISH
;
1052 IsDeveloper
= false;
1056 memset(Picture
, 0, MAX_PICTURE_SIZE
);
1057 } // Ccontact::Initialize
1060 Ccontact::~Ccontact()
1064 if (!wxDbFreeConnection(GetDb()))
1067 tStr
= wxT("Unable to Free the Ccontact data table handle\n\n");
1069 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1070 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1073 } // Ccontract destructor
1077 * Handles setting up all the connections for the interface from the wxDbTable
1078 * functions to interface to the data structure used to store records in
1079 * memory, and for all the column definitions that define the table structure
1081 void Ccontact::SetupColumns()
1083 // NOTE: Columns now are 8 character names, as that is all dBase can support. Longer
1084 // names can be used for other database engines
1085 SetColDefs ( 0,wxT("NAME"), DB_DATA_TYPE_VARCHAR
, Name
, SQL_C_WXCHAR
, sizeof(Name
), true, true); // Primary index
1086 SetColDefs ( 1,wxT("ADDRESS1"), DB_DATA_TYPE_VARCHAR
, Addr1
, SQL_C_WXCHAR
, sizeof(Addr1
), false,true);
1087 SetColDefs ( 2,wxT("ADDRESS2"), DB_DATA_TYPE_VARCHAR
, Addr2
, SQL_C_WXCHAR
, sizeof(Addr2
), false,true);
1088 SetColDefs ( 3,wxT("CITY"), DB_DATA_TYPE_VARCHAR
, City
, SQL_C_WXCHAR
, sizeof(City
), false,true);
1089 SetColDefs ( 4,wxT("STATE"), DB_DATA_TYPE_VARCHAR
, State
, SQL_C_WXCHAR
, sizeof(State
), false,true);
1090 SetColDefs ( 5,wxT("POSTCODE"), DB_DATA_TYPE_VARCHAR
, PostalCode
, SQL_C_WXCHAR
, sizeof(PostalCode
), false,true);
1091 SetColDefs ( 6,wxT("COUNTRY"), DB_DATA_TYPE_VARCHAR
, Country
, SQL_C_WXCHAR
, sizeof(Country
), false,true);
1092 SetColDefs ( 7,wxT("JOINDATE"), DB_DATA_TYPE_DATE
, &JoinDate
, SQL_C_TIMESTAMP
, sizeof(JoinDate
), false,true);
1093 SetColDefs ( 8,wxT("IS_DEV"), DB_DATA_TYPE_INTEGER
, &IsDeveloper
, SQL_C_BOOLEAN(IsDeveloper
), sizeof(IsDeveloper
), false,true);
1094 SetColDefs ( 9,wxT("CONTRIBS"), DB_DATA_TYPE_INTEGER
, &Contributions
, SQL_C_UTINYINT
, sizeof(Contributions
), false,true);
1095 SetColDefs (10,wxT("LINE_CNT"), DB_DATA_TYPE_INTEGER
, &LinesOfCode
, SQL_C_ULONG
, sizeof(LinesOfCode
), false,true);
1096 SetColDefs (11,wxT("LANGUAGE"), DB_DATA_TYPE_INTEGER
, &NativeLanguage
, SQL_C_ENUM
, sizeof(NativeLanguage
), false,true);
1097 #ifdef wxODBC_BLOB_SUPPORT
1098 SetColDefs (12,wxT("PICSIZE"), DB_DATA_TYPE_INTEGER
, &BlobSize
, SQL_C_ULONG
, sizeof(BlobSize
), false,true);
1099 SetColDefs (13,wxT("PICTURE"), DB_DATA_TYPE_BLOB
, Picture
, SQL_C_BINARY
, sizeof(Picture
), false,true);
1101 } // Ccontact::SetupColumns
1104 bool Ccontact::CreateIndexes(bool recreate
)
1106 // This index could easily be accomplished with an "orderBy" clause,
1107 // but is done to show how to construct a non-primary index.
1109 wxDbIdxDef idxDef
[2];
1111 wxStrcpy(idxDef
[0].ColName
, wxT("IS_DEV"));
1112 idxDef
[0].Ascending
= true;
1114 wxStrcpy(idxDef
[1].ColName
, wxT("NAME"));
1115 idxDef
[1].Ascending
= true;
1117 indexName
= GetTableName();
1118 indexName
+= wxT("_IDX1");
1120 return CreateIndex(indexName
.c_str(), true, 2, idxDef
, recreate
);
1122 } // Ccontact::CreateIndexes()
1126 * Having a function to do a query on the primary key (and possibly others) is
1127 * very efficient and tighter coding so that it is available where ever the object
1128 * is. Great for use with multiple tables when not using views or outer joins
1130 bool Ccontact::FetchByName(const wxString
&name
)
1132 whereStr
.Printf(wxT("NAME = '%s'"),name
.c_str());
1133 SetWhereClause(whereStr
.c_str());
1134 SetOrderByClause(wxEmptyString
);
1142 } // Ccontact::FetchByName()
1147 * ************* DIALOGS ***************
1152 /* CeditorDlg constructor
1154 * Creates the dialog used for creating/editing/deleting/copying a Ccontact object.
1155 * This dialog actually is drawn in the main frame of the program
1157 * An instance of Ccontact is created - "Contact" - which is used to hold the Ccontact
1158 * object that is currently being worked with.
1161 BEGIN_EVENT_TABLE(CeditorDlg
, wxPanel
)
1162 EVT_BUTTON(wxID_ANY
, CeditorDlg::OnButton
)
1163 EVT_CLOSE(CeditorDlg::OnCloseWindow
)
1166 CeditorDlg::CeditorDlg(wxWindow
*parent
) : wxPanel (parent
, 0, 0, 537, 530)
1168 // Since the ::OnCommand() function is overridden, this prevents the widget
1169 // detection in ::OnCommand() until all widgets have been initialized to prevent
1170 // uninitialized pointers from crashing the program
1171 widgetPtrsSet
= false;
1173 initialized
= false;
1178 } // CeditorDlg constructor
1181 void CeditorDlg::OnCloseWindow(wxCloseEvent
& event
)
1184 if ((mode
!= mCreate
) && (mode
!= mEdit
))
1190 wxMessageBox(wxT("Must finish processing the current record being created/modified before exiting"),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
1193 } // CeditorDlg::OnCloseWindow()
1196 void CeditorDlg::OnButton(wxCommandEvent
&event
)
1198 wxWindow
*win
= (wxWindow
*) event
.GetEventObject();
1199 OnCommand( *win
, event
);
1200 } // CeditorDlg::OnButton()
1203 void CeditorDlg::OnCommand(wxWindow
& win
, wxCommandEvent
& WXUNUSED(event
))
1205 wxString widgetName
;
1207 widgetName
= win
.GetName();
1212 if (widgetName
== pCreateBtn
->GetName())
1214 wxGetApp().Contact
->Initialize();
1217 pNameTxt
->SetValue(wxEmptyString
);
1218 pNameTxt
->SetFocus();
1222 if (widgetName
== pEditBtn
->GetName())
1224 saveName
= wxGetApp().Contact
->Name
;
1226 pNameTxt
->SetFocus();
1230 if (widgetName
== pCopyBtn
->GetName())
1233 pNameTxt
->SetValue(wxEmptyString
);
1234 pNameTxt
->SetFocus();
1238 if (widgetName
== pDeleteBtn
->GetName())
1240 bool Ok
= (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
1245 if (Ok
&& wxGetApp().Contact
->Delete())
1247 // NOTE: Deletions are not finalized until a CommitTrans() is performed.
1248 // If the commit were not performed, the program will continue to
1249 // show the table contents as if they were deleted until this instance
1250 // of Ccontact is deleted. If the Commit wasn't performed, the
1251 // database will automatically Rollback the changes when the database
1252 // connection is terminated
1253 wxGetApp().Contact
->GetDb()->CommitTrans();
1255 // Try to get the row that followed the just deleted row in the orderBy sequence
1258 // There was now row (in sequence) after the just deleted row, so get the
1259 // row which preceded the just deleted row
1262 // There are now no rows remaining, so clear the dialog widgets
1263 wxGetApp().Contact
->Initialize();
1267 SetMode(mode
); // force reset of button enable/disable
1271 wxGetApp().Contact
->GetDb()->RollbackTrans();
1277 if (widgetName
== pSaveBtn
->GetName())
1283 if (widgetName
== pCancelBtn
->GetName())
1285 bool Ok
= (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
1290 if (saveName
.IsEmpty())
1292 wxGetApp().Contact
->Initialize();
1299 // Requery previous record
1300 if (wxGetApp().Contact
->FetchByName(saveName
))
1308 // Previous record not available, retrieve first record in table
1309 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1310 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1312 wxGetApp().Contact
->whereStr
= wxT("NAME = (SELECT MIN(NAME) FROM ");
1313 wxGetApp().Contact
->whereStr
+= wxGetApp().Contact
->GetTableName();
1314 wxGetApp().Contact
->whereStr
+= wxT(")");
1315 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
.c_str());
1318 wxGetApp().Contact
->SetWhereClause(wxEmptyString
);
1320 if (!wxGetApp().Contact
->Query())
1323 tStr
= wxT("ODBC error during Query()\n\n");
1324 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1325 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1330 if (wxGetApp().Contact
->GetNext()) // Successfully read first record
1336 // No contacts are available, clear dialog
1337 wxGetApp().Contact
->Initialize();
1343 if (widgetName
== pPrevBtn
->GetName())
1350 if (widgetName
== pNextBtn
->GetName())
1357 if (widgetName
== pQueryBtn
->GetName())
1359 // Display the query dialog box
1360 wxChar qryWhere
[DB_MAX_WHERE_CLAUSE_LEN
+1];
1361 wxStrcpy(qryWhere
, (const wxChar
*) wxGetApp().Contact
->qryWhereStr
);
1362 wxChar
*tblName
[] = {(wxChar
*)CONTACT_TABLE_NAME
.c_str(), 0};
1363 new CqueryDlg(GetParent(), wxGetApp().Contact
->GetDb(), tblName
, qryWhere
);
1365 // Query the first record in the new record set and
1366 // display it, if the query string has changed.
1367 if (wxStrcmp(qryWhere
, (const wxChar
*) wxGetApp().Contact
->qryWhereStr
))
1369 wxGetApp().Contact
->whereStr
.Empty();
1370 wxGetApp().Contact
->SetOrderByClause(wxT("NAME"));
1372 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1373 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1375 wxGetApp().Contact
->whereStr
= wxT("NAME = (SELECT MIN(NAME) FROM ");
1376 wxGetApp().Contact
->whereStr
+= CONTACT_TABLE_NAME
;
1379 // Append the query where string (if there is one)
1380 wxGetApp().Contact
->qryWhereStr
= qryWhere
;
1381 if (wxStrlen(qryWhere
))
1383 wxGetApp().Contact
->whereStr
+= wxT(" WHERE ");
1384 wxGetApp().Contact
->whereStr
+= wxGetApp().Contact
->qryWhereStr
;
1386 // Close the expression with a right paren
1387 wxGetApp().Contact
->whereStr
+= wxT(")");
1388 // Requery the table
1389 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
.c_str());
1390 if (!wxGetApp().Contact
->Query())
1393 tStr
= wxT("ODBC error during Query()\n\n");
1394 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1395 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1399 // Display the first record from the query set
1400 if (!wxGetApp().Contact
->GetNext())
1401 wxGetApp().Contact
->Initialize();
1405 // Enable/Disable the reset button
1406 pResetBtn
->Enable(!wxGetApp().Contact
->qryWhereStr
.IsEmpty());
1412 if (widgetName
== pResetBtn
->GetName())
1414 // Clear the additional where criteria established by the query feature
1415 wxGetApp().Contact
->qryWhereStr
= wxEmptyString
;
1416 wxGetApp().Contact
->SetOrderByClause(wxT("NAME"));
1418 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1419 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1421 wxGetApp().Contact
->whereStr
= wxT("NAME = (SELECT MIN(NAME) FROM ");
1422 wxGetApp().Contact
->whereStr
+= CONTACT_TABLE_NAME
;
1423 wxGetApp().Contact
->whereStr
+= wxT(")");
1426 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
.c_str());
1427 if (!wxGetApp().Contact
->Query())
1430 tStr
= wxT("ODBC error during Query()\n\n");
1431 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1432 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1435 if (!wxGetApp().Contact
->GetNext())
1436 wxGetApp().Contact
->Initialize();
1438 pResetBtn
->Enable(false);
1444 if (widgetName
== pNameListBtn
->GetName())
1446 new ClookUpDlg(/* wxWindow *parent */ this,
1447 /* const wxString &windowTitle */ wxT("Select contact name"),
1448 /* const wxString &tableName */ CONTACT_TABLE_NAME
,
1449 /* const wxString &dispCol1 */ wxT("NAME"),
1450 /* const wxString &dispCol2 */ wxT("JOINDATE"),
1451 /* const wxString &where */ wxT(""),
1452 /* const wxString &orderBy */ wxT("NAME"),
1453 /* wxDb *pDb */ wxGetApp().READONLY_DB
,
1454 /* const wxString &defDir */ wxGetApp().DbConnectInf
->GetDefaultDir(),
1455 /* bool distinctValues*/ true);
1457 if (ListDB_Selection
&& wxStrlen(ListDB_Selection
))
1459 wxString w
= wxT("NAME = '");
1460 w
+= ListDB_Selection
;
1468 if (widgetName
== pDataTypesBtn
->GetName())
1470 CheckSupportForAllDataTypes(wxGetApp().READONLY_DB
);
1471 wxMessageBox(wxT("Support datatypes was dumped to stdout."));
1473 } // Data types Button
1475 if (widgetName
== pDbDiagsBtn
->GetName())
1477 DisplayDbDiagnostics(wxGetApp().READONLY_DB
);
1478 wxMessageBox(wxT("Diagnostics info was dumped to stdout."));
1482 if (widgetName
== pCatalogBtn
->GetName())
1484 if (wxGetApp().Contact
->GetDb()->Catalog(wxEmptyString
, wxT("catalog.txt")))
1485 wxMessageBox(wxT("The file 'catalog.txt' was created."));
1487 wxMessageBox(wxT("Creation of the file 'catalog.txt' was failed."));
1491 #ifdef wxODBC_BLOB_SUPPORT
1492 if (widgetName
== pChooseImageBtn
->GetName())
1497 if (widgetName
== pShowImageBtn
->GetName())
1503 } // CeditorDlg::OnCommand()
1506 bool CeditorDlg::Initialize()
1508 // Create the data structure and a new database connection.
1509 // (As there is not a pDb being passed in the constructor, a new database
1510 // connection is created)
1511 wxGetApp().Contact
= new Ccontact();
1513 if (!wxGetApp().Contact
)
1515 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
1519 // Check if the table exists or not. If it doesn't, ask the user if they want to
1520 // create the table. Continue trying to create the table until it exists, or user aborts
1521 while (!wxGetApp().Contact
->GetDb()->TableExists(CONTACT_TABLE_NAME
,
1522 wxGetApp().DbConnectInf
->GetUserID(),
1523 wxGetApp().DbConnectInf
->GetDefaultDir()))
1526 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
);
1527 bool createTable
= (wxMessageBox(tStr
.c_str(),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
1535 wxGetApp().CreateDataTable(false);
1538 // Tables must be "opened" before anything other than creating/deleting table can be done
1539 if (!wxGetApp().Contact
->Open())
1541 // Table does exist, or there was some problem opening it. Currently this should
1542 // never fail, except in the case of the table not exisiting or the current
1543 // user has insufficent privileges to access the table
1545 // This code is experimenting with a new function that will hopefully be available
1546 // in the 2.4 release. This check will determine whether the open failing was due
1547 // to the table not existing, or the users privileges being insufficient to
1549 if (!wxGetApp().Contact
->GetDb()->TablePrivileges(CONTACT_TABLE_NAME
, wxT("SELECT"),
1550 wxGetApp().Contact
->GetDb()->GetUsername(),
1551 wxGetApp().Contact
->GetDb()->GetUsername(),
1552 wxGetApp().DbConnectInf
->GetDefaultDir()))
1555 tStr
.Printf(wxT("Unable to open the table '%s' (likely due to\ninsufficient privileges of the logged in user).\n\n"),CONTACT_TABLE_NAME
);
1557 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1558 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1562 if (!wxGetApp().Contact
->GetDb()->TableExists(CONTACT_TABLE_NAME
,
1563 wxGetApp().Contact
->GetDb()->GetUsername(),
1564 wxGetApp().DbConnectInf
->GetDefaultDir()))
1567 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
);
1568 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1569 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1577 (void)new wxStaticBox(this, EDITOR_DIALOG_FN_GROUP
, wxEmptyString
, wxPoint(15, 1), wxSize(497, 69), 0, wxT("FunctionGrp"));
1578 (void)new wxStaticBox(this, EDITOR_DIALOG_SEARCH_GROUP
, wxEmptyString
, wxPoint(417, 1), wxSize(95, 242), 0, wxT("SearchGrp"));
1580 pCreateBtn
= new wxButton(this, EDITOR_DIALOG_CREATE
, wxT("&Create"), wxPoint( 25, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CreateBtn"));
1581 pEditBtn
= new wxButton(this, EDITOR_DIALOG_EDIT
, wxT("&Edit"), wxPoint(102, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("EditBtn"));
1582 pDeleteBtn
= new wxButton(this, EDITOR_DIALOG_DELETE
, wxT("&Delete"), wxPoint(179, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("DeleteBtn"));
1583 pCopyBtn
= new wxButton(this, EDITOR_DIALOG_COPY
, wxT("Cop&y"), wxPoint(256, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CopyBtn"));
1584 pSaveBtn
= new wxButton(this, EDITOR_DIALOG_SAVE
, wxT("&Save"), wxPoint(333, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("SaveBtn"));
1585 pCancelBtn
= new wxButton(this, EDITOR_DIALOG_CANCEL
, wxT("C&ancel"), wxPoint(430, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CancelBtn"));
1586 pPrevBtn
= new wxButton(this, EDITOR_DIALOG_PREV
, wxT("<< &Prev"), wxPoint(430, 81), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("PrevBtn"));
1587 pNextBtn
= new wxButton(this, EDITOR_DIALOG_NEXT
, wxT("&Next >>"), wxPoint(430, 121), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("NextBtn"));
1588 pQueryBtn
= new wxButton(this, EDITOR_DIALOG_QUERY
, wxT("&Query"), wxPoint(430, 161), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("QueryBtn"));
1589 pResetBtn
= new wxButton(this, EDITOR_DIALOG_RESET
, wxT("&Reset"), wxPoint(430, 200), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("ResetBtn"));
1590 pNameMsg
= new wxStaticText(this, EDITOR_DIALOG_NAME_MSG
, wxT("Name:"), wxPoint( 17, 80), wxDefaultSize
, 0, wxT("NameMsg"));
1591 pNameTxt
= new wxTextCtrl(this, EDITOR_DIALOG_NAME_TEXT
, wxEmptyString
, wxPoint( 17, 97), wxSize(308, 25), 0, wxDefaultValidator
, wxT("NameTxt"));
1592 pNameListBtn
= new wxButton(this, EDITOR_DIALOG_LOOKUP
, wxT("&Lookup"), wxPoint(333, 97), wxSize( 70, 24), 0, wxDefaultValidator
, wxT("LookupBtn"));
1593 pAddress1Msg
= new wxStaticText(this, EDITOR_DIALOG_ADDRESS1_MSG
, wxT("Address:"), wxPoint( 17, 130), wxDefaultSize
, 0, wxT("Address1Msg"));
1594 pAddress1Txt
= new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT
, wxEmptyString
, wxPoint( 17, 147), wxSize(308, 25), 0, wxDefaultValidator
, wxT("Address1Txt"));
1595 pAddress2Msg
= new wxStaticText(this, EDITOR_DIALOG_ADDRESS2_MSG
, wxT("Address:"), wxPoint( 17, 180), wxDefaultSize
, 0, wxT("Address2Msg"));
1596 pAddress2Txt
= new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT
, wxEmptyString
, wxPoint( 17, 197), wxSize(308, 25), 0, wxDefaultValidator
, wxT("Address2Txt"));
1597 pCityMsg
= new wxStaticText(this, EDITOR_DIALOG_CITY_MSG
, wxT("City:"), wxPoint( 17, 230), wxDefaultSize
, 0, wxT("CityMsg"));
1598 pCityTxt
= new wxTextCtrl(this, EDITOR_DIALOG_CITY_TEXT
, wxEmptyString
, wxPoint( 17, 247), wxSize(225, 25), 0, wxDefaultValidator
, wxT("CityTxt"));
1599 pStateMsg
= new wxStaticText(this, EDITOR_DIALOG_STATE_MSG
, wxT("State:"), wxPoint(250, 230), wxDefaultSize
, 0, wxT("StateMsg"));
1600 pStateTxt
= new wxTextCtrl(this, EDITOR_DIALOG_STATE_TEXT
, wxEmptyString
, wxPoint(250, 247), wxSize(153, 25), 0, wxDefaultValidator
, wxT("StateTxt"));
1601 pCountryMsg
= new wxStaticText(this, EDITOR_DIALOG_COUNTRY_MSG
, wxT("Country:"), wxPoint( 17, 280), wxDefaultSize
, 0, wxT("CountryMsg"));
1602 pCountryTxt
= new wxTextCtrl(this, EDITOR_DIALOG_COUNTRY_TEXT
, wxEmptyString
, wxPoint( 17, 297), wxSize(225, 25), 0, wxDefaultValidator
, wxT("CountryTxt"));
1603 pPostalCodeMsg
= new wxStaticText(this, EDITOR_DIALOG_POSTAL_MSG
, wxT("Postal Code:"),wxPoint(250, 280), wxDefaultSize
, 0, wxT("PostalCodeMsg"));
1604 pPostalCodeTxt
= new wxTextCtrl(this, EDITOR_DIALOG_POSTAL_TEXT
, wxEmptyString
, wxPoint(250, 297), wxSize(153, 25), 0, wxDefaultValidator
, wxT("PostalCodeTxt"));
1606 wxString choice_strings
[5];
1607 choice_strings
[0] = wxT("English");
1608 choice_strings
[1] = wxT("French");
1609 choice_strings
[2] = wxT("German");
1610 choice_strings
[3] = wxT("Spanish");
1611 choice_strings
[4] = wxT("Other");
1613 pNativeLangChoice
= new wxChoice(this, EDITOR_DIALOG_LANG_CHOICE
, wxPoint( 17, 346), wxSize(277, wxDefaultCoord
), 5, choice_strings
);
1614 pNativeLangMsg
= new wxStaticText(this, EDITOR_DIALOG_LANG_MSG
, wxT("Native language:"), wxPoint( 17, 330), wxDefaultSize
, 0, wxT("NativeLangMsg"));
1616 wxString radio_strings
[2];
1617 radio_strings
[0] = wxT("No");
1618 radio_strings
[1] = wxT("Yes");
1619 pDeveloperRadio
= new wxRadioBox(this,EDITOR_DIALOG_DEVELOPER
, wxT("Developer:"), wxPoint(303, 330), wxDefaultSize
, 2, radio_strings
, 2, wxHORIZONTAL
);
1620 pJoinDateMsg
= new wxStaticText(this, EDITOR_DIALOG_JOIN_MSG
, wxT("Date joined:"), wxPoint( 17, 380), wxDefaultSize
, 0, wxT("JoinDateMsg"));
1621 pJoinDateTxt
= new wxTextCtrl(this, EDITOR_DIALOG_JOIN_TEXT
, wxEmptyString
, wxPoint( 17, 397), wxSize(150, 25), 0, wxDefaultValidator
, wxT("JoinDateTxt"));
1622 pContribMsg
= new wxStaticText(this, EDITOR_DIALOG_CONTRIB_MSG
,wxT("Contributions:"), wxPoint(175, 380), wxDefaultSize
, 0, wxT("ContribMsg"));
1623 pContribTxt
= new wxTextCtrl(this, EDITOR_DIALOG_CONTRIB_TEXT
, wxEmptyString
, wxPoint(175, 397), wxSize(120, 25), 0, wxDefaultValidator
, wxT("ContribTxt"));
1624 pLinesMsg
= new wxStaticText(this, EDITOR_DIALOG_LINES_MSG
, wxT("Lines of code:"), wxPoint(303, 380), wxDefaultSize
, 0, wxT("LinesMsg"));
1625 pLinesTxt
= new wxTextCtrl(this, EDITOR_DIALOG_LINES_TEXT
, wxEmptyString
, wxPoint(303, 397), wxSize(100, 25), 0, wxDefaultValidator
, wxT("LinesTxt"));
1627 pCatalogBtn
= new wxButton(this, EDITOR_DIALOG_CATALOG
, wxT("Catalo&g"), wxPoint(430, 287), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CatalogBtn"));
1628 pDataTypesBtn
= new wxButton(this, EDITOR_DIALOG_DATATYPES
, wxT("Data&types"), wxPoint(430, 337), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("DataTypesBtn"));
1629 pDbDiagsBtn
= new wxButton(this, EDITOR_DIALOG_DB_DIAGS
, wxT("DB Dia&gs"), wxPoint(430, 387), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("DbDiagsBtn"));
1631 #ifdef wxODBC_BLOB_SUPPORT
1632 pPictureMsg
= new wxStaticText(this, EDITOR_DIALOG_PIC_MSG
, wxT("Picture:"), wxPoint( 17,430), wxDefaultSize
, 0, wxT("PicMsg"));
1633 pPictSizeMsg
= new wxStaticText(this, EDITOR_DIALOG_PICSIZE_MSG
, wxT("Picture Bytes:"), wxPoint(175,430), wxDefaultSize
, 0, wxT("PicSizeMsg"));
1634 pChooseImageBtn
= new wxButton(this, EDITOR_DIALOG_PIC_BROWSE
, wxT("Select..."), wxPoint( 17,447), wxSize( 70, 24), 0, wxDefaultValidator
, wxT("PicBrowseBtn"));
1635 pShowImageBtn
= new wxButton(this, EDITOR_DIALOG_PIC_SHOW
, wxT("Show..."), wxPoint( 97,447), wxSize( 70, 24), 0, wxDefaultValidator
, wxT("PictShowBtn"));
1636 pPictSizeTxt
= new wxTextCtrl(this, EDITOR_DIALOG_PIC_SIZE_TEXT
, wxEmptyString
, wxPoint(175,447), wxSize(120, 25), 0, wxDefaultValidator
, wxT("PictSizeTxt"));
1639 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
1640 // handle all widget processing
1641 widgetPtrsSet
= true;
1643 // Setup the orderBy and where clauses to return back a single record as the result set,
1644 // as there will only be one record being shown on the dialog at a time, this optimizes
1645 // network traffic by only returning a one row result
1647 wxGetApp().Contact
->SetOrderByClause(wxT("NAME")); // field name to sort by
1649 // The wxString "whereStr" is not a member of the wxDbTable object, it is a member variable
1650 // specifically in the Ccontact class. It is used here for simpler construction of a varying
1651 // length string, and then after the string is built, the wxDbTable member variable "where" is
1652 // assigned the pointer to the constructed string.
1654 // The constructed where clause below has a sub-query within it "SELECT MIN(NAME) FROM %s"
1655 // to achieve a single row (in this case the first name in alphabetical order).
1657 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1658 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1660 wxGetApp().Contact
->whereStr
.Printf(wxT("NAME = (SELECT MIN(NAME) FROM %s)"),
1661 wxGetApp().Contact
->GetTableName().c_str());
1662 // NOTE: (const wxChar*) returns a pointer which may not be valid later, so this is short term use only
1663 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
);
1666 wxGetApp().Contact
->SetWhereClause(wxEmptyString
);
1668 // Perform the Query to get the result set.
1669 // NOTE: If there are no rows returned, that is a valid result, so Query() would return true.
1670 // Only if there is a database error will Query() come back as false
1671 if (!wxGetApp().Contact
->Query())
1674 tStr
= wxT("ODBC error during Query()\n\n");
1675 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1676 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1680 // Since Query succeeded, now get the row that was returned
1681 if (!wxGetApp().Contact
->GetNext())
1682 // If the GetNext() failed at this point, then there are no rows to retrieve,
1683 // so clear the values in the members of "Contact" so that PutData() blanks the
1684 // widgets on the dialog
1685 wxGetApp().Contact
->Initialize();
1687 wxGetApp().Contact->GetDb()->RollbackTrans();
1696 } // CeditorDlg::Initialize()
1698 #ifdef wxODBC_BLOB_SUPPORT
1700 void CeditorDlg::OnSelectPict()
1702 wxFileDialog
dlg(this, wxT("Choose an image file less than 60K"), wxEmptyString
, wxEmptyString
, wxT("JPEG files (*.jpg)|*.jpg|GIF files (*.gif)|*.gif|BMP files (*.bmp)|*.bmp|All Files (*.*)|*.*"), wxOPEN
);
1704 if (dlg
.ShowModal() == wxID_OK
)
1706 wxFile
file(dlg
.GetPath());
1708 if (file
.IsOpened())
1710 wxFileOffset iSize
= file
.Length();
1712 if ((iSize
> 0) && (iSize
< MAX_PICTURE_SIZE
))
1714 wxGetApp().Contact
->BlobSize
= (size_t)iSize
;
1716 memset(wxGetApp().Contact
->Picture
, 0, MAX_PICTURE_SIZE
);
1718 wxFileOffset iReadSize
= file
.Read(wxGetApp().Contact
->Picture
, (size_t)iSize
);
1720 if (iReadSize
< iSize
)
1721 wxMessageBox(wxT("Something bad happened while reading..."), wxT("BLOB Loading Error"), wxOK
| wxICON_EXCLAMATION
);
1724 tStr
.Printf(wxT("%lu"),iSize
);
1725 pPictSizeTxt
->SetValue(tStr
);
1728 wxMessageBox(wxT("Selected File is TOO BIG. 60k is the max image size"), wxT("BLOB Loading Error"), wxOK
| wxICON_EXCLAMATION
);
1731 wxMessageBox(wxT("Unable to open the requested image file"), wxT("File Access Error"), wxOK
| wxICON_EXCLAMATION
);
1735 void CeditorDlg::OnShowImage()
1737 if (wxGetApp().Contact
->BlobSize
> 0)
1739 CimageDlg
dlg(this, wxGetApp().Contact
->Picture
, wxGetApp().Contact
->BlobSize
);
1747 void CeditorDlg::FieldsEditable()
1752 pNameTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1753 pAddress1Txt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1754 pAddress2Txt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1755 pCityTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1756 pStateTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1757 pPostalCodeTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1758 pCountryTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1760 pJoinDateTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1761 pContribTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1762 pLinesTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1763 pNativeLangChoice
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1764 pDeveloperRadio
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1766 #ifdef wxODBC_BLOB_SUPPORT
1767 pPictSizeTxt
->Enable(false);
1768 pChooseImageBtn
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1769 pShowImageBtn
->Enable(wxGetApp().Contact
&& wxGetApp().Contact
->BlobSize
> 0); //((mode == mCreate) || (mode == mEdit));
1772 } // CeditorDlg::FieldsEditable()
1775 void CeditorDlg::SetMode(enum DialogModes m
)
1796 pCreateBtn
->Enable( !edit
);
1797 pEditBtn
->Enable( !edit
&& (wxStrcmp(wxGetApp().Contact
->Name
, wxEmptyString
) != 0) );
1798 pDeleteBtn
->Enable( !edit
&& (wxStrcmp(wxGetApp().Contact
->Name
, wxEmptyString
)!=0) );
1799 pCopyBtn
->Enable( !edit
&& (wxStrcmp(wxGetApp().Contact
->Name
, wxEmptyString
)!=0) );
1800 pSaveBtn
->Enable( edit
);
1801 pCancelBtn
->Enable( edit
);
1802 pPrevBtn
->Enable( !edit
);
1803 pNextBtn
->Enable( !edit
);
1804 pQueryBtn
->Enable( !edit
);
1805 pResetBtn
->Enable( !edit
&& !wxGetApp().Contact
->qryWhereStr
.IsEmpty() );
1806 pNameListBtn
->Enable( !edit
);
1810 } // CeditorDlg::SetMode()
1813 bool CeditorDlg::PutData()
1817 pNameTxt
->SetValue(wxGetApp().Contact
->Name
);
1818 pAddress1Txt
->SetValue(wxGetApp().Contact
->Addr1
);
1819 pAddress2Txt
->SetValue(wxGetApp().Contact
->Addr2
);
1820 pCityTxt
->SetValue(wxGetApp().Contact
->City
);
1821 pStateTxt
->SetValue(wxGetApp().Contact
->State
);
1822 pCountryTxt
->SetValue(wxGetApp().Contact
->Country
);
1823 pPostalCodeTxt
->SetValue(wxGetApp().Contact
->PostalCode
);
1825 tStr
.Printf(wxT("%d/%d/%d"),wxGetApp().Contact
->JoinDate
.month
,wxGetApp().Contact
->JoinDate
.day
,wxGetApp().Contact
->JoinDate
.year
);
1826 pJoinDateTxt
->SetValue(tStr
);
1828 tStr
.Printf(wxT("%d"),wxGetApp().Contact
->Contributions
);
1829 pContribTxt
->SetValue(tStr
);
1831 tStr
.Printf(wxT("%lu"),wxGetApp().Contact
->LinesOfCode
);
1832 pLinesTxt
->SetValue(tStr
);
1834 pNativeLangChoice
->SetSelection(wxGetApp().Contact
->NativeLanguage
);
1836 pDeveloperRadio
->SetSelection(wxGetApp().Contact
->IsDeveloper
);
1838 #ifdef wxODBC_BLOB_SUPPORT
1839 tStr
.Printf(wxT("%lu"),wxGetApp().Contact
->BlobSize
);
1840 pPictSizeTxt
->SetValue(tStr
);
1841 pShowImageBtn
->Enable(wxGetApp().Contact
->BlobSize
> 0);
1845 } // Ceditor::PutData()
1849 * Reads the data out of all the widgets on the dialog. Some data evaluation is done
1850 * to ensure that there is a name entered and that the date field is valid.
1852 * A return value of true means that valid data was retrieved from the dialog, otherwise
1853 * invalid data was found (and a message was displayed telling the user what to fix), and
1854 * the data was not placed into the appropraite fields of Ccontact
1856 bool CeditorDlg::GetData()
1858 // Validate that the data currently entered into the widgets is valid data
1861 tStr
= pNameTxt
->GetValue();
1862 if (!wxStrcmp((const wxChar
*) tStr
, wxEmptyString
))
1864 wxMessageBox(wxT("A name is required for entry into the contact table"), wxT("Notice..."), wxOK
| wxICON_INFORMATION
);
1868 bool invalid
= false;
1869 int mm
= 1,dd
= 1,yyyy
= 2001;
1872 tStr
= pJoinDateTxt
->GetValue();
1873 if (tStr
.Freq(wxT('/')) != 2)
1876 // Find the month, day, and year tokens
1879 first
= tStr
.First(wxT('/'));
1880 second
= tStr
.Last(wxT('/'));
1882 mm
= wxAtoi(tStr
.SubString(0,first
));
1883 dd
= wxAtoi(tStr
.SubString(first
+1,second
));
1884 yyyy
= wxAtoi(tStr
.SubString(second
+1,tStr
.Length()-1));
1886 invalid
= !(mm
&& dd
&& yyyy
);
1889 // Force Year 2000 compliance
1890 if (!invalid
&& (yyyy
< 1000))
1893 // Check the token ranges for validity
1898 else if ((mm
< 1) || (mm
> 12))
1906 int days
[12] = {31,28,31,30,31,30,
1908 if (dd
> days
[mm
-1])
1911 if ((dd
== 29) && (mm
== 2))
1913 if (((yyyy
% 4) == 0) && (((yyyy
% 100) != 0) || ((yyyy
% 400) == 0)))
1923 wxGetApp().Contact
->JoinDate
.month
= (unsigned short) mm
;
1924 wxGetApp().Contact
->JoinDate
.day
= (unsigned short) dd
;
1925 wxGetApp().Contact
->JoinDate
.year
= (short) yyyy
;
1929 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
);
1933 tStr
= pNameTxt
->GetValue();
1934 wxStrcpy(wxGetApp().Contact
->Name
,(const wxChar
*) tStr
);
1935 wxStrcpy(wxGetApp().Contact
->Addr1
,pAddress1Txt
->GetValue());
1936 wxStrcpy(wxGetApp().Contact
->Addr2
,pAddress2Txt
->GetValue());
1937 wxStrcpy(wxGetApp().Contact
->City
,pCityTxt
->GetValue());
1938 wxStrcpy(wxGetApp().Contact
->State
,pStateTxt
->GetValue());
1939 wxStrcpy(wxGetApp().Contact
->Country
,pCountryTxt
->GetValue());
1940 wxStrcpy(wxGetApp().Contact
->PostalCode
,pPostalCodeTxt
->GetValue());
1942 wxGetApp().Contact
->Contributions
= (UCHAR
)wxAtoi(pContribTxt
->GetValue());
1943 wxGetApp().Contact
->LinesOfCode
= wxAtol(pLinesTxt
->GetValue());
1945 wxGetApp().Contact
->NativeLanguage
= (enum Language
) pNativeLangChoice
->GetSelection();
1946 wxGetApp().Contact
->IsDeveloper
= pDeveloperRadio
->GetSelection() > 0;
1949 } // CeditorDlg::GetData()
1953 * Retrieve data from the dialog, verify the validity of the data, and if it is valid,
1954 * try to insert/update the data to the table based on the current 'mode' the dialog
1957 * A return value of true means the insert/update was completed successfully, a return
1958 * value of false means that Save() failed. If returning false, then this function
1959 * has displayed a detailed error message for the user.
1961 bool CeditorDlg::Save()
1963 bool failed
= false;
1965 // Read the data in the widgets of the dialog to get the user's data
1969 // Perform any other required validations necessary before saving
1972 wxBeginBusyCursor();
1974 if (mode
== mCreate
)
1976 RETCODE result
= (RETCODE
)wxGetApp().Contact
->Insert();
1978 failed
= (result
!= DB_SUCCESS
);
1981 // Some errors may be expected, like a duplicate key, so handle those instances with
1982 // specific error messages.
1983 if (result
== DB_ERR_INTEGRITY_CONSTRAINT_VIOL
)
1986 tStr
= wxT("A duplicate key value already exists in the table.\nUnable to save record\n\n");
1987 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1988 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1992 // Some other unexpected error occurred
1994 tStr
= wxT("Database insert failed\n\n");
1995 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1996 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2000 else // mode == mEdit
2002 wxGetApp().Contact
->GetDb()->RollbackTrans();
2003 wxGetApp().Contact
->whereStr
.Printf(wxT("NAME = '%s'"),saveName
.c_str());
2004 if (!wxGetApp().Contact
->UpdateWhere(wxGetApp().Contact
->whereStr
))
2007 tStr
= wxT("Database update failed\n\n");
2008 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2009 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2016 wxGetApp().Contact
->GetDb()->CommitTrans();
2017 SetMode(mView
); // Sets the dialog mode back to viewing after save is successful
2020 wxGetApp().Contact
->GetDb()->RollbackTrans();
2026 } // CeditorDlg::Save()
2030 * Where this program is only showing a single row at a time in the dialog,
2031 * a special where clause must be built to find just the single row which,
2032 * in sequence, would follow the currently displayed row.
2034 bool CeditorDlg::GetNextRec()
2038 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
2039 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
2041 w
= wxT("NAME = (SELECT MIN(NAME) FROM ");
2042 w
+= wxGetApp().Contact
->GetTableName();
2043 w
+= wxT(" WHERE NAME > '");
2046 w
= wxT("(NAME > '");
2048 w
+= wxGetApp().Contact
->Name
;
2051 // If a query where string is currently set, append that criteria
2052 if (!wxGetApp().Contact
->qryWhereStr
.IsEmpty())
2055 w
+= wxGetApp().Contact
->qryWhereStr
;
2062 } // CeditorDlg::GetNextRec()
2066 * Where this program is only showing a single row at a time in the dialog,
2067 * a special where clause must be built to find just the single row which,
2068 * in sequence, would precede the currently displayed row.
2070 bool CeditorDlg::GetPrevRec()
2074 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
2075 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
2077 w
= wxT("NAME = (SELECT MAX(NAME) FROM ");
2078 w
+= wxGetApp().Contact
->GetTableName();
2079 w
+= wxT(" WHERE NAME < '");
2082 w
= wxT("(NAME < '");
2084 w
+= wxGetApp().Contact
->Name
;
2087 // If a query where string is currently set, append that criteria
2088 if (!wxGetApp().Contact
->qryWhereStr
.IsEmpty())
2091 w
+= wxGetApp().Contact
->qryWhereStr
;
2099 } // CeditorDlg::GetPrevRec()
2103 * This function is here to avoid duplicating this same code in both the
2104 * GetPrevRec() and GetNextRec() functions
2106 bool CeditorDlg::GetRec(const wxString
&whereStr
)
2108 wxGetApp().Contact
->SetWhereClause(whereStr
);
2109 wxGetApp().Contact
->SetOrderByClause(wxT("NAME"));
2111 if (!wxGetApp().Contact
->Query())
2114 tStr
= wxT("ODBC error during Query()\n\n");
2115 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2116 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2121 if (wxGetApp().Contact
->GetNext())
2128 } // CeditorDlg::GetRec()
2133 * CparameterDlg constructor
2136 BEGIN_EVENT_TABLE(CparameterDlg
, wxDialog
)
2137 EVT_BUTTON(PARAMETER_DIALOG_SAVE
, CparameterDlg::OnButton
)
2138 EVT_BUTTON(PARAMETER_DIALOG_CANCEL
, CparameterDlg::OnButton
)
2139 EVT_CLOSE(CparameterDlg::OnCloseWindow
)
2142 CparameterDlg::CparameterDlg(wxWindow
*parent
) : wxDialog (parent
, PARAMETER_DIALOG
, wxT("ODBC parameter settings"), wxDefaultPosition
, wxSize(400, 325))
2144 // Since the ::OnCommand() function is overridden, this prevents the widget
2145 // detection in ::OnCommand() until all widgets have been initialized to prevent
2146 // uninitialized pointers from crashing the program
2147 widgetPtrsSet
= false;
2149 pParamODBCSourceMsg
= new wxStaticText(this, PARAMETER_DIALOG_SOURCE_MSG
, wxT("ODBC data sources:"), wxPoint( 10, 10), wxDefaultSize
, 0, wxT("ParamODBCSourceMsg"));
2150 pParamODBCSourceList
= new wxListBox(this, PARAMETER_DIALOG_SOURCE_LISTBOX
, wxPoint( 10, 29), wxSize(285, 150), 0, 0, wxLB_SINGLE
|wxLB_ALWAYS_SB
, wxDefaultValidator
, wxT("ParamODBCSourceList"));
2151 pParamUserNameMsg
= new wxStaticText(this, PARAMETER_DIALOG_NAME_MSG
, wxT("Database user name:"), wxPoint( 10, 193), wxDefaultSize
, 0, wxT("ParamUserNameMsg"));
2152 pParamUserNameTxt
= new wxTextCtrl(this, PARAMETER_DIALOG_NAME_TEXT
, wxEmptyString
, wxPoint(10, 209), wxSize( 140, 25), 0, wxDefaultValidator
, wxT("ParamUserNameTxt"));
2153 pParamPasswordMsg
= new wxStaticText(this, PARAMETER_DIALOG_PASSWORD_MSG
, wxT("Password:"), wxPoint(156, 193), wxDefaultSize
, 0, wxT("ParamPasswordMsg"));
2154 pParamPasswordTxt
= new wxTextCtrl(this, PARAMETER_DIALOG_PASSWORD_TEXT
, wxEmptyString
, wxPoint(156, 209), wxSize( 140, 25), 0, wxDefaultValidator
, wxT("ParamPasswordTxt"));
2155 pParamDirPathMsg
= new wxStaticText(this, PARAMETER_DIALOG_DIRPATH_MSG
, wxT("Directory:"), wxPoint( 10, 243), wxDefaultSize
, 0, wxT("ParamDirPathMsg"));
2156 pParamDirPathTxt
= new wxTextCtrl(this, PARAMETER_DIALOG_DIRPATH_TEXT
, wxEmptyString
, wxPoint( 10, 259), wxSize(140, 25), 0, wxDefaultValidator
, wxT("ParamDirPathTxt"));
2157 pParamSaveBtn
= new wxButton(this, PARAMETER_DIALOG_SAVE
, wxT("&Save"), wxPoint(310, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("ParamSaveBtn"));
2158 pParamCancelBtn
= new wxButton(this, PARAMETER_DIALOG_CANCEL
, wxT("C&ancel"), wxPoint(310, 66), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("ParamCancelBtn"));
2160 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
2161 // handle all widget processing
2162 widgetPtrsSet
= true;
2165 savedParamSettings
= wxGetApp().params
;
2170 } // CparameterDlg constructor
2173 void CparameterDlg::OnCloseWindow(wxCloseEvent
& event
)
2175 // Put any additional checking necessary to make certain it is alright
2176 // to close the program here that is not done elsewhere
2179 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
);
2187 wxGetApp().params
= savedParamSettings
;
2190 if (GetParent() != NULL
)
2191 GetParent()->SetFocus();
2197 SetReturnCode(0); // added so BoundsChecker would not report use of uninitialized variable
2200 } // CparameterDlg::OnCloseWindow()
2203 void CparameterDlg::OnButton( wxCommandEvent
&event
)
2205 wxWindow
*win
= (wxWindow
*) event
.GetEventObject();
2206 OnCommand( *win
, event
);
2210 void CparameterDlg::OnCommand(wxWindow
& win
, wxCommandEvent
& WXUNUSED(event
))
2212 wxString widgetName
;
2214 widgetName
= win
.GetName();
2219 if (widgetName
== pParamSaveBtn
->GetName())
2224 tStr
= wxT("Database parameters have been saved.");
2225 if (GetParent() != NULL
) // The parameter dialog was not called during startup due to a missing cfg file
2226 tStr
+= wxT("\nNew parameters will take effect the next time the program is started.");
2227 wxMessageBox(tStr
,wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
2234 if (widgetName
== pParamCancelBtn
->GetName())
2239 } // CparameterDlg::OnCommand()
2242 bool CparameterDlg::PutData()
2244 // Fill the data source list box
2245 FillDataSourceList();
2247 // Fill in the fields from the params object
2248 if (wxGetApp().params
.ODBCSource
&& wxStrlen(wxGetApp().params
.ODBCSource
))
2250 int index
= pParamODBCSourceList
->FindString(wxGetApp().params
.ODBCSource
);
2251 if (index
!= wxNOT_FOUND
)
2252 pParamODBCSourceList
->SetSelection(index
);
2254 pParamUserNameTxt
->SetValue(wxGetApp().params
.UserName
);
2255 pParamPasswordTxt
->SetValue(wxGetApp().params
.Password
);
2256 pParamDirPathTxt
->SetValue(wxGetApp().params
.DirPath
);
2258 } // CparameterDlg::PutData()
2261 bool CparameterDlg::GetData()
2264 if (pParamODBCSourceList
->GetStringSelection() != wxEmptyString
)
2266 tStr
= pParamODBCSourceList
->GetStringSelection();
2267 if (tStr
.Length() > ((int)(sizeof(wxGetApp().params
.ODBCSource
) / sizeof(wxChar
))-1))
2270 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());
2271 wxMessageBox(errmsg
, wxT("Internal program error..."), wxOK
| wxICON_EXCLAMATION
);
2274 wxStrcpy(wxGetApp().params
.ODBCSource
, tStr
);
2279 tStr
= pParamUserNameTxt
->GetValue();
2280 if (tStr
.Length() > ((int)(sizeof(wxGetApp().params
.UserName
) / sizeof(wxChar
))-1))
2283 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());
2284 wxMessageBox(errmsg
, wxT("Internal program error..."), wxOK
| wxICON_EXCLAMATION
);
2287 wxStrcpy(wxGetApp().params
.UserName
, tStr
);
2289 tStr
= pParamPasswordTxt
->GetValue();
2290 if (tStr
.Length() > ((int)(sizeof(wxGetApp().params
.Password
) / sizeof(wxChar
))-1))
2293 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());
2294 wxMessageBox(errmsg
, wxT("Internal program error..."), wxOK
| wxICON_EXCLAMATION
);
2297 wxStrcpy(wxGetApp().params
.Password
,tStr
);
2299 tStr
= pParamDirPathTxt
->GetValue();
2300 tStr
.Replace(wxT("\\"),wxT("/"));
2301 if (tStr
.Length() > ((int)(sizeof(wxGetApp().params
.DirPath
) / sizeof(wxChar
))-1))
2304 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());
2305 wxMessageBox(errmsg
, wxT("Internal program error..."), wxOK
| wxICON_EXCLAMATION
);
2308 wxStrcpy(wxGetApp().params
.DirPath
,tStr
);
2310 } // CparameterDlg::GetData()
2313 bool CparameterDlg::Save()
2315 // Copy the current params in case user cancels changing
2316 // the params, so that we can reset them.
2319 wxGetApp().params
= savedParamSettings
;
2323 wxGetApp().WriteParamFile(wxGetApp().params
);
2326 } // CparameterDlg::Save()
2329 void CparameterDlg::FillDataSourceList()
2331 wxChar Dsn
[SQL_MAX_DSN_LENGTH
+1];
2332 wxChar DsDesc
[254+1];
2333 wxSortedArrayString strArr
;
2335 while (wxDbGetDataSource(wxGetApp().DbConnectInf
->GetHenv(), Dsn
,
2336 SQL_MAX_DSN_LENGTH
, DsDesc
, 254))
2341 for (size_t i
=0; i
< strArr
.GetCount(); i
++)
2343 pParamODBCSourceList
->Append(strArr
[i
].c_str());
2346 } // CparameterDlg::FillDataSourceList()
2349 BEGIN_EVENT_TABLE(CqueryDlg
, wxDialog
)
2350 EVT_BUTTON(wxID_ANY
, CqueryDlg::OnButton
)
2351 EVT_CLOSE(CqueryDlg::OnCloseWindow
)
2355 // CqueryDlg() constructor
2356 CqueryDlg::CqueryDlg(wxWindow
*parent
, wxDb
*pDb
, wxChar
*tblName
[],
2357 const wxString
&pWhereArg
) :
2358 wxDialog (parent
, QUERY_DIALOG
, wxT("Query"), wxDefaultPosition
, wxSize(480, 360))
2360 wxBeginBusyCursor();
2364 masterTableName
= tblName
[0];
2365 widgetPtrsSet
= false;
2368 // Initialize the WHERE clause from the string passed in
2369 pWhere
= pWhereArg
; // Save a pointer to the output buffer
2370 if (pWhere
.Length() > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN
) // Check the length of the buffer passed in
2373 s
.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN
+1);
2374 wxMessageBox(s
,wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2379 pQueryCol1Msg
= new wxStaticText(this, QUERY_DIALOG_COL_MSG
, wxT("Column 1:"), wxPoint( 10, 10), wxSize( 69, 16), 0, wxT("QueryCol1Msg"));
2380 pQueryCol1Choice
= new wxChoice(this, QUERY_DIALOG_COL_CHOICE
, wxPoint( 10, 27), wxSize(250, 27), 0, 0, 0, wxDefaultValidator
, wxT("QueryCol1Choice"));
2381 pQueryNotMsg
= new wxStaticText(this, QUERY_DIALOG_NOT_MSG
, wxT("NOT"), wxPoint(268, 10), wxDefaultSize
, 0, wxT("QueryNotMsg"));
2382 pQueryNotCheck
= new wxCheckBox(this, QUERY_DIALOG_NOT_CHECKBOX
, wxEmptyString
, wxPoint(275, 37), wxSize( 20, 20), 0, wxDefaultValidator
, wxT("QueryNotCheck"));
2384 wxString choice_strings
[9];
2385 choice_strings
[0] = wxT("=");
2386 choice_strings
[1] = wxT("<");
2387 choice_strings
[2] = wxT(">");
2388 choice_strings
[3] = wxT("<=");
2389 choice_strings
[4] = wxT(">=");
2390 choice_strings
[5] = wxT("Begins");
2391 choice_strings
[6] = wxT("Contains");
2392 choice_strings
[7] = wxT("Like");
2393 choice_strings
[8] = wxT("Between");
2395 pQueryOperatorMsg
= new wxStaticText(this, QUERY_DIALOG_OP_MSG
, wxT("Operator:"), wxPoint(305, 10), wxDefaultSize
, 0, wxT("QueryOperatorMsg"));
2396 pQueryOperatorChoice
= new wxChoice(this, QUERY_DIALOG_OP_CHOICE
, wxPoint(305, 27), wxSize( 80, 27), 9, choice_strings
, 0, wxDefaultValidator
, wxT("QueryOperatorChoice"));
2397 pQueryCol2Msg
= new wxStaticText(this, QUERY_DIALOG_COL2_MSG
, wxT("Column 2:"), wxPoint( 10, 65), wxSize( 69, 16), 0, wxT("QueryCol2Msg"));
2398 pQueryCol2Choice
= new wxChoice(this, QUERY_DIALOG_COL2_CHOICE
, wxPoint( 10, 82), wxSize(250, 27), 0, 0, 0, wxDefaultValidator
, wxT("QueryCol2Choice"));
2399 pQuerySqlWhereMsg
= new wxStaticText(this, QUERY_DIALOG_WHERE_MSG
, wxT("SQL where clause:"), wxPoint( 10, 141), wxDefaultSize
, 0, wxT("QuerySqlWhereMsg"));
2400 pQuerySqlWhereMtxt
= new wxTextCtrl(this, QUERY_DIALOG_WHERE_TEXT
, wxEmptyString
, wxPoint( 10, 159), wxSize(377, 134), wxTE_MULTILINE
, wxDefaultValidator
, wxT("QuerySqlWhereMtxt"));
2401 pQueryAddBtn
= new wxButton(this, QUERY_DIALOG_ADD
, wxT("&Add"), wxPoint(406, 24), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryAddBtn"));
2402 pQueryAndBtn
= new wxButton(this, QUERY_DIALOG_AND
, wxT("A&nd"), wxPoint(406, 58), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryAndBtn"));
2403 pQueryOrBtn
= new wxButton(this, QUERY_DIALOG_OR
, wxT("&Or"), wxPoint(406, 92), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryOrBtn"));
2404 pQueryLParenBtn
= new wxButton(this, QUERY_DIALOG_LPAREN
, wxT("("), wxPoint(406, 126), wxSize( 26, 26), 0, wxDefaultValidator
, wxT("QueryLParenBtn"));
2405 pQueryRParenBtn
= new wxButton(this, QUERY_DIALOG_RPAREN
, wxT(")"), wxPoint(436, 126), wxSize( 26, 26), 0, wxDefaultValidator
, wxT("QueryRParenBtn"));
2406 pQueryDoneBtn
= new wxButton(this, QUERY_DIALOG_DONE
, wxT("&Done"), wxPoint(406, 185), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryDoneBtn"));
2407 pQueryClearBtn
= new wxButton(this, QUERY_DIALOG_CLEAR
, wxT("C&lear"), wxPoint(406, 218), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryClearBtn"));
2408 pQueryCountBtn
= new wxButton(this, QUERY_DIALOG_COUNT
, wxT("&Count"), wxPoint(406, 252), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryCountBtn"));
2409 pQueryValue1Msg
= new wxStaticText(this, QUERY_DIALOG_VALUE1_MSG
, wxT("Value:"), wxPoint(277, 66), wxDefaultSize
, 0, wxT("QueryValue1Msg"));
2410 pQueryValue1Txt
= new wxTextCtrl(this, QUERY_DIALOG_VALUE1_TEXT
, wxEmptyString
, wxPoint(277, 83), wxSize(108, 25), 0, wxDefaultValidator
, wxT("QueryValue1Txt"));
2411 pQueryValue2Msg
= new wxStaticText(this, QUERY_DIALOG_VALUE2_MSG
, wxT("AND"), wxPoint(238, 126), wxDefaultSize
, 0, wxT("QueryValue2Msg"));
2412 pQueryValue2Txt
= new wxTextCtrl(this, QUERY_DIALOG_VALUE2_TEXT
, wxEmptyString
, wxPoint(277, 120), wxSize(108, 25), 0, wxDefaultValidator
, wxT("QueryValue2Txt"));
2413 pQueryHintGrp
= new wxStaticBox(this, QUERY_DIALOG_HINT_GROUP
, wxEmptyString
, wxPoint( 10, 291), wxSize(377, 40), 0, wxT("QueryHintGrp"));
2414 pQueryHintMsg
= new wxStaticText(this, QUERY_DIALOG_HINT_MSG
, wxEmptyString
, wxPoint( 16, 306), wxDefaultSize
, 0, wxT("QueryHintMsg"));
2416 widgetPtrsSet
= true;
2417 // Initialize the dialog
2419 pQueryCol2Choice
->Append(wxT("VALUE -->"));
2420 colInf
= pDB
->GetColumns(tblName
);
2426 tStr
= wxT("ODBC error during GetColumns()\n\n");
2427 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2428 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2433 for (i
= 0; colInf
[i
].colName
&& wxStrlen(colInf
[i
].colName
); i
++)
2435 // If there is more than one table being queried, qualify
2436 // the column names with the table name prefix.
2437 if (tblName
[1] && wxStrlen(tblName
[1]))
2439 qualName
.Printf(wxT("%s.%s"), colInf
[i
].tableName
, colInf
[i
].colName
);
2440 pQueryCol1Choice
->Append(qualName
);
2441 pQueryCol2Choice
->Append(qualName
);
2443 else // Single table query, append just the column names
2445 pQueryCol1Choice
->Append(colInf
[i
].colName
);
2446 pQueryCol2Choice
->Append(colInf
[i
].colName
);
2450 pQueryCol1Choice
->SetSelection(0);
2451 pQueryCol2Choice
->SetSelection(0);
2452 pQueryOperatorChoice
->SetSelection(0);
2454 pQueryValue2Msg
->Show(false);
2455 pQueryValue2Txt
->Show(false);
2457 pQueryHintMsg
->SetLabel(langQRY_EQ
);
2459 pQuerySqlWhereMtxt
->SetValue(pWhere
.c_str());
2463 // Display the dialog window
2466 } // CqueryDlg() constructor
2469 CqueryDlg::~CqueryDlg()
2471 } // CqueryDlg::~CqueryDlg() destructor
2474 void CqueryDlg::OnButton(wxCommandEvent
&event
)
2476 wxWindow
*win
= (wxWindow
*) event
.GetEventObject();
2477 OnCommand( *win
, event
);
2478 } // CqueryDlg::OnButton()
2481 void CqueryDlg::OnCommand(wxWindow
& win
, wxCommandEvent
& WXUNUSED(event
))
2483 // Widget pointers won't be set when the dialog is constructed.
2484 // Control is passed through this function once for each widget on
2485 // a dialog as the dialog is constructed.
2489 wxString widgetName
= win
.GetName();
2491 // Operator choice box
2492 if (widgetName
== pQueryOperatorChoice
->GetName())
2494 // Set the help text
2495 switch((qryOp
) pQueryOperatorChoice
->GetSelection())
2498 pQueryHintMsg
->SetLabel(langQRY_EQ
);
2501 pQueryHintMsg
->SetLabel(langQRY_LT
);
2504 pQueryHintMsg
->SetLabel(langQRY_GT
);
2507 pQueryHintMsg
->SetLabel(langQRY_LE
);
2510 pQueryHintMsg
->SetLabel(langQRY_GE
);
2513 pQueryHintMsg
->SetLabel(langQRY_BEGINS
);
2516 pQueryHintMsg
->SetLabel(langQRY_CONTAINS
);
2519 pQueryHintMsg
->SetLabel(langQRY_LIKE
);
2522 pQueryHintMsg
->SetLabel(langQRY_BETWEEN
);
2526 // Hide the value2 widget
2527 pQueryValue2Msg
->Show(false); // BETWEEN will show this widget
2528 pQueryValue2Txt
->Show(false); // BETWEEN will show this widget
2530 // Disable the NOT operator for <, <=, >, >=
2531 switch((qryOp
) pQueryOperatorChoice
->GetSelection())
2537 pQueryNotCheck
->SetValue(0);
2538 pQueryNotCheck
->Enable(false);
2541 pQueryNotCheck
->Enable(true);
2545 // Manipulate the dialog to handle the selected operator
2546 switch((qryOp
) pQueryOperatorChoice
->GetSelection())
2553 pQueryCol2Choice
->Enable(true);
2554 if (pQueryCol2Choice
->GetSelection()) // Column name is highlighted
2556 pQueryValue1Msg
->Show(false);
2557 pQueryValue1Txt
->Show(false);
2559 else // "Value" is highlighted
2561 pQueryValue1Msg
->Show(true);
2562 pQueryValue1Txt
->Show(true);
2563 pQueryValue1Txt
->SetFocus();
2569 pQueryCol2Choice
->SetSelection(0);
2570 pQueryCol2Choice
->Enable(false);
2571 pQueryValue1Msg
->Show(true);
2572 pQueryValue1Txt
->Show(true);
2573 pQueryValue1Txt
->SetFocus();
2576 pQueryCol2Choice
->SetSelection(0);
2577 pQueryCol2Choice
->Enable(false);
2578 pQueryValue2Msg
->Show(true);
2579 pQueryValue2Txt
->Show(true);
2580 pQueryValue1Msg
->Show(true);
2581 pQueryValue1Txt
->Show(true);
2582 pQueryValue1Txt
->SetFocus();
2588 } // Operator choice box
2591 if (widgetName
== pQueryCol2Choice
->GetName())
2593 if (pQueryCol2Choice
->GetSelection()) // Column name is highlighted
2595 pQueryValue1Msg
->Show(false);
2596 pQueryValue1Txt
->Show(false);
2598 else // "Value" is highlighted
2600 pQueryValue1Msg
->Show(true);
2601 pQueryValue1Txt
->Show(true);
2602 pQueryValue1Txt
->SetFocus();
2605 } // Column 2 choice
2608 if (widgetName
== pQueryAddBtn
->GetName())
2615 if (widgetName
== pQueryAndBtn
->GetName())
2617 AppendToWhere(wxT(" AND\n"));
2622 if (widgetName
== pQueryOrBtn
->GetName())
2624 AppendToWhere(wxT(" OR\n"));
2628 // Left Paren button
2629 if (widgetName
== pQueryLParenBtn
->GetName())
2631 AppendToWhere(wxT("("));
2633 } // Left Paren button
2635 // Right paren button
2636 if (widgetName
== pQueryRParenBtn
->GetName())
2638 AppendToWhere(wxT(")"));
2640 } // Right Paren button
2643 if (widgetName
== pQueryDoneBtn
->GetName())
2645 // Be sure the where clause will not overflow the output buffer
2646 if (wxStrlen(pQuerySqlWhereMtxt
->GetValue()) > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN
)
2649 s
.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN
+1);
2650 wxMessageBox(s
,wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2653 // Validate the where clause for things such as matching parens
2654 if (!ValidateWhereClause())
2656 // Copy the where clause to the output buffer and exit
2657 pWhere
= pQuerySqlWhereMtxt
->GetValue();
2663 if (widgetName
== pQueryClearBtn
->GetName())
2665 bool Ok
= (wxMessageBox(wxT("Are you sure you wish to clear the Query?"), wxT("Confirm"), wxYES_NO
|wxICON_QUESTION
) == wxYES
);
2668 pQuerySqlWhereMtxt
->SetValue(wxEmptyString
);
2674 if (widgetName
== pQueryCountBtn
->GetName())
2676 wxBeginBusyCursor();
2682 } // CqueryDlg::OnCommand
2685 void CqueryDlg::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
2692 GetParent()->SetFocus();
2697 SetReturnCode(1); // added so BoundsChecker would not report use of uninitialized variable
2700 } // CqueryDlg::OnCloseWindow()
2703 void CqueryDlg::AppendToWhere(wxChar
*s
)
2705 wxString whereStr
= pQuerySqlWhereMtxt
->GetValue();
2707 pQuerySqlWhereMtxt
->SetValue(whereStr
);
2708 } // CqueryDlg::AppendToWhere()
2711 void CqueryDlg::ProcessAddBtn()
2713 qryOp oper
= (qryOp
) pQueryOperatorChoice
->GetSelection();
2715 // Verify that eveything is filled in correctly
2716 if (pQueryCol2Choice
->GetSelection() == 0) // "Value" is selected
2718 // Verify that value 1 is filled in
2719 if (wxStrlen(pQueryValue1Txt
->GetValue()) == 0)
2722 pQueryValue1Txt
->SetFocus();
2725 // For the BETWEEN operator, value 2 must be filled in as well
2726 if (oper
== qryOpBETWEEN
&&
2727 wxStrlen(pQueryValue2Txt
->GetValue()) == 0)
2730 pQueryValue2Txt
->SetFocus();
2735 // Build the expression and append it to the where clause window
2736 wxString s
= pQueryCol1Choice
->GetStringSelection();
2738 if (pQueryNotCheck
->GetValue() && (oper
!= qryOpEQ
))
2744 if (pQueryNotCheck
->GetValue()) // NOT box is checked
2767 s
+= wxT(" BETWEEN");
2773 int col1Idx
= pQueryCol1Choice
->GetSelection();
2776 if (colInf
[col1Idx
].sqlDataType
== SQL_VARCHAR
||
2777 oper
== qryOpBEGINS
||
2778 oper
== qryOpCONTAINS
||
2782 if (pQueryCol2Choice
->GetSelection()) // Column name
2783 s
+= pQueryCol2Choice
->GetStringSelection();
2784 else // Column 2 is a "value"
2788 if (oper
== qryOpCONTAINS
)
2790 s
+= pQueryValue1Txt
->GetValue();
2791 if (oper
== qryOpCONTAINS
|| oper
== qryOpBEGINS
)
2797 if (oper
== qryOpBETWEEN
)
2802 s
+= pQueryValue2Txt
->GetValue();
2807 AppendToWhere((wxChar
*) (const wxChar
*) s
);
2809 } // CqueryDlg::ProcessAddBtn()
2812 void CqueryDlg::ProcessCountBtn()
2814 if (!ValidateWhereClause())
2817 if (!dbTable
) // wxDbTable object needs to be created and opened
2819 dbTable
= new wxDbTable(pDB
, masterTableName
, 0, (const wxString
&)wxEmptyString
,
2821 wxGetApp().DbConnectInf
->GetDefaultDir());
2824 wxMessageBox(wxT("Memory allocation failed creating a wxDbTable object."),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2827 if (!dbTable
->Open())
2830 tStr
= wxT("ODBC error during Open()\n\n");
2831 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2832 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2837 // Count() with WHERE clause
2840 whereStr
= pQuerySqlWhereMtxt
->GetValue();
2841 dbTable
->SetWhereClause(whereStr
.c_str());
2843 ULONG whereCnt
= dbTable
->Count();
2845 // Count() of all records in the table
2846 dbTable
->SetWhereClause(wxEmptyString
);
2847 ULONG totalCnt
= dbTable
->Count();
2849 if (whereCnt
> 0 || totalCnt
== 0)
2852 tStr
.Printf(wxT("%lu of %lu records match the query criteria."),whereCnt
,totalCnt
);
2853 wxMessageBox(tStr
,wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
2858 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
);
2859 wxMessageBox(tStr
,wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
2862 // After a wxMessageBox, the focus does not necessarily return to the
2863 // window which was the focus when the message box popped up, so return
2864 // focus to the Query dialog for certain
2867 } // CqueryDlg::ProcessCountBtn()
2870 bool CqueryDlg::ValidateWhereClause()
2872 wxString where
= pQuerySqlWhereMtxt
->GetValue();
2874 if (where
.Freq(wxT('(')) != where
.Freq(wxT(')')))
2876 wxMessageBox(wxT("There are mismatched parenthesis in the constructed where clause"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2879 // After a wxMessageBox, the focus does not necessarily return to the
2880 // window which was the focus when the message box popped up, so return
2881 // focus to the Query dialog for certain
2886 } // CqueryDlg::ValidateWhereClause()
2888 #ifdef wxODBC_BLOB_SUPPORT
2890 BEGIN_EVENT_TABLE(CimageDlg
, wxDialog
)
2891 EVT_CLOSE(CimageDlg::OnCloseWindow
)
2894 CimageDlg::CimageDlg(wxWindow
*parent
, wxChar
*pImageData
, off_t iSize
)
2895 : wxDialog(parent
, IMAGE_DIALOG
, wxT("BLOB Image"), wxDefaultPosition
, wxDefaultSize
),
2900 wxMemoryInputStream
inStream(pImageData
, iSize
);
2904 m_pImage
= new wxImage(inStream
, wxBITMAP_TYPE_ANY
);
2908 m_pBmp
= new wxBitmap(m_pImage
);
2909 m_pDisplayBmp
= new wxStaticBitmap(this, IMAGE_DIALOG_STATIC_BMP
, *m_pBmp
, wxPoint(5,5), wxDefaultSize
);
2911 SetSize(m_pBmp
->GetWidth() + 10, m_pBmp
->GetHeight() + 30);
2916 CimageDlg::~CimageDlg()
2925 delete m_pDisplayBmp
;
2928 void CimageDlg::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
2930 GetParent()->SetFocus();
2939 void DisplayDbDiagnostics(wxDb
*pDb
)
2944 s
= wxT("Diagnostics Output\n");
2945 s
+= langDBINF_DB_NAME
;
2946 s
+= pDb
->dbInf
.dbmsName
;
2949 s
+= langDBINF_DB_VER
;
2950 s
+= pDb
->dbInf
.dbmsVer
;
2953 s
+= langDBINF_DRIVER_NAME
;
2954 s
+= pDb
->dbInf
.driverName
;
2957 s
+= langDBINF_DRIVER_ODBC_VER
;
2958 s
+= pDb
->dbInf
.odbcVer
;
2961 s
+= langDBINF_DRIVER_MGR_ODBC_VER
;
2962 s
+= pDb
->dbInf
.drvMgrOdbcVer
;
2965 s
+= langDBINF_DRIVER_VER
;
2966 s
+= pDb
->dbInf
.driverVer
;
2969 s
+= langDBINF_SERVER_NAME
;
2970 s
+= pDb
->dbInf
.serverName
;
2973 s
+= langDBINF_FILENAME
;
2974 s
+= pDb
->dbInf
.databaseName
;
2977 s
+= langDBINF_OUTER_JOINS
;
2978 s
+= pDb
->dbInf
.outerJoins
;
2981 s
+= langDBINF_STORED_PROC
;
2982 s
+= pDb
->dbInf
.procedureSupport
;
2985 if (pDb
->dbInf
.maxConnections
)
2986 t
.sprintf(wxT("%s%d\n"), langDBINF_MAX_HDBC
, pDb
->dbInf
.maxConnections
);
2988 t
.sprintf(wxT("%s%s\n"), langDBINF_MAX_HDBC
, langDBINF_UNLIMITED
);
2991 if (pDb
->dbInf
.maxStmts
)
2992 t
.sprintf(wxT("%s%d\n"), langDBINF_MAX_HSTMT
, pDb
->dbInf
.maxStmts
);
2994 t
.sprintf(wxT("%s%s\n"), langDBINF_MAX_HSTMT
, langDBINF_UNLIMITED
);
2997 s
+= langDBINF_API_LVL
;
2998 switch(pDb
->dbInf
.apiConfLvl
)
3000 case SQL_OAC_NONE
: s
+= langDBINF_NONE
; break;
3001 case SQL_OAC_LEVEL1
: s
+= langDBINF_LEVEL1
; break;
3002 case SQL_OAC_LEVEL2
: s
+= langDBINF_LEVEL2
; break;
3006 s
+= langDBINF_CLI_LVL
;
3007 switch(pDb
->dbInf
.cliConfLvl
)
3009 case SQL_OSCC_NOT_COMPLIANT
: s
+= langDBINF_NOT_COMPLIANT
; break;
3010 case SQL_OSCC_COMPLIANT
: s
+= langDBINF_COMPLIANT
; break;
3014 s
+= langDBINF_SQL_LVL
;
3015 switch(pDb
->dbInf
.sqlConfLvl
)
3017 case SQL_OSC_MINIMUM
: s
+= langDBINF_MIN_GRAMMAR
; break;
3018 case SQL_OSC_CORE
: s
+= langDBINF_CORE_GRAMMAR
; break;
3019 case SQL_OSC_EXTENDED
: s
+= langDBINF_EXT_GRAMMAR
; break;
3023 s
+= langDBINF_COMMIT_BEHAVIOR
;
3024 switch(pDb
->dbInf
.cursorCommitBehavior
)
3026 case SQL_CB_DELETE
: s
+= langDBINF_DELETE_CURSORS
; break;
3027 case SQL_CB_CLOSE
: s
+= langDBINF_CLOSE_CURSORS
; break;
3028 case SQL_CB_PRESERVE
: s
+= langDBINF_PRESERVE_CURSORS
; break;
3032 s
+= langDBINF_ROLLBACK_BEHAVIOR
;
3033 switch(pDb
->dbInf
.cursorRollbackBehavior
)
3035 case SQL_CB_DELETE
: s
+= langDBINF_DELETE_CURSORS
; break;
3036 case SQL_CB_CLOSE
: s
+= langDBINF_CLOSE_CURSORS
; break;
3037 case SQL_CB_PRESERVE
: s
+= langDBINF_PRESERVE_CURSORS
; break;
3041 s
+= langDBINF_SUPP_NOT_NULL
;
3042 switch(pDb
->dbInf
.supportNotNullClause
)
3044 case SQL_NNC_NULL
: s
+= langNO
; break;
3045 case SQL_NNC_NON_NULL
: s
+= langYES
; break;
3049 s
+= langDBINF_SUPP_IEF
;
3050 s
+= pDb
->dbInf
.supportIEF
;
3053 // DEFAULT setting for "Transaction Isolation Level"
3054 s
+= langDBINF_TXN_ISOLATION
;
3055 switch(pDb
->dbInf
.txnIsolation
)
3057 case SQL_TXN_READ_UNCOMMITTED
: s
+= langDBINF_READ_UNCOMMITTED
; break;
3058 case SQL_TXN_READ_COMMITTED
: s
+= langDBINF_READ_COMMITTED
; break;
3059 case SQL_TXN_REPEATABLE_READ
: s
+= langDBINF_REPEATABLE_READ
; break;
3060 case SQL_TXN_SERIALIZABLE
: s
+= langDBINF_SERIALIZABLE
; break;
3062 case SQL_TXN_VERSIONING
: s
+= langDBINF_VERSIONING
; break;
3067 // CURRENT setting for "Transaction Isolation Level"
3069 s
+= langDBINF_TXN_ISOLATION_CURR
;
3070 if (SQLGetConnectOption(pDb
->GetHDBC(),SQL_TXN_ISOLATION
,&txnIsoLvl
) == SQL_SUCCESS
)
3074 case SQL_TXN_READ_UNCOMMITTED
: s
+= langDBINF_READ_UNCOMMITTED
; break;
3075 case SQL_TXN_READ_COMMITTED
: s
+= langDBINF_READ_COMMITTED
; break;
3076 case SQL_TXN_REPEATABLE_READ
: s
+= langDBINF_REPEATABLE_READ
; break;
3077 case SQL_TXN_SERIALIZABLE
: s
+= langDBINF_SERIALIZABLE
; break;
3079 case SQL_TXN_VERSIONING
: s
+= langDBINF_VERSIONING
; break;
3086 #pragma message disable incboodep
3089 s
+= langDBINF_TXN_ISOLATION_OPTS
;
3090 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_READ_UNCOMMITTED
)
3091 {s
+= langDBINF_READ_UNCOMMITTED
; comma
++;}
3092 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_READ_COMMITTED
)
3093 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_READ_COMMITTED
;}
3094 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_REPEATABLE_READ
)
3095 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_REPEATABLE_READ
;}
3096 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_SERIALIZABLE
)
3097 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_SERIALIZABLE
;}
3099 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_VERSIONING
)
3100 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_VERSIONING
;}
3105 s
+= langDBINF_FETCH_DIRS
;
3106 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_NEXT
)
3107 {s
+= langDBINF_NEXT
; comma
++;}
3108 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_PRIOR
)
3109 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_PREV
;}
3110 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_FIRST
)
3111 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_FIRST
;}
3112 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_LAST
)
3113 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_LAST
;}
3114 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_ABSOLUTE
)
3115 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_ABSOLUTE
;}
3116 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_RELATIVE
)
3117 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_RELATIVE
;}
3119 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_RESUME
)
3120 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_RESUME
;}
3122 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_BOOKMARK
)
3123 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_BOOKMARK
;}
3127 s
+= langDBINF_LOCK_TYPES
;
3128 if (pDb
->dbInf
.lockTypes
& SQL_LCK_NO_CHANGE
)
3129 {s
+= langDBINF_NO_CHANGE
; comma
++;}
3130 if (pDb
->dbInf
.lockTypes
& SQL_LCK_EXCLUSIVE
)
3131 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_EXCLUSIVE
;}
3132 if (pDb
->dbInf
.lockTypes
& SQL_LCK_UNLOCK
)
3133 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_UNLOCK
;}
3137 s
+= langDBINF_POS_OPERS
;
3138 if (pDb
->dbInf
.posOperations
& SQL_POS_POSITION
)
3139 {s
+= langDBINF_POSITION
; comma
++;}
3140 if (pDb
->dbInf
.posOperations
& SQL_POS_REFRESH
)
3141 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_REFRESH
;}
3142 if (pDb
->dbInf
.posOperations
& SQL_POS_UPDATE
)
3143 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_UPD
;}
3144 if (pDb
->dbInf
.posOperations
& SQL_POS_DELETE
)
3145 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_DEL
;}
3146 if (pDb
->dbInf
.posOperations
& SQL_POS_ADD
)
3147 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_ADD
;}
3151 s
+= langDBINF_POS_STMTS
;
3152 if (pDb
->dbInf
.posStmts
& SQL_PS_POSITIONED_DELETE
)
3153 {s
+= langDBINF_POS_DEL
; comma
++;}
3154 if (pDb
->dbInf
.posStmts
& SQL_PS_POSITIONED_UPDATE
)
3155 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_POS_UPD
;}
3156 if (pDb
->dbInf
.posStmts
& SQL_PS_SELECT_FOR_UPDATE
)
3157 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_SELECT_FOR_UPD
;}
3161 s
+= langDBINF_SCROLL_CONCURR
;
3162 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_READ_ONLY
)
3163 {s
+= langDBINF_READ_ONLY
; comma
++;}
3164 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_LOCK
)
3165 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_LOCK
;}
3166 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_OPT_ROWVER
)
3167 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_OPT_ROWVER
;}
3168 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_OPT_VALUES
)
3169 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_OPT_VALUES
;}
3173 s
+= langDBINF_SCROLL_OPTS
;
3174 if (pDb
->dbInf
.scrollOptions
& SQL_SO_FORWARD_ONLY
)
3175 {s
+= langDBINF_FWD_ONLY
; comma
++;}
3176 if (pDb
->dbInf
.scrollOptions
& SQL_SO_STATIC
)
3177 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_STATIC
;}
3178 if (pDb
->dbInf
.scrollOptions
& SQL_SO_KEYSET_DRIVEN
)
3179 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_KEYSET_DRIVEN
;}
3180 if (pDb
->dbInf
.scrollOptions
& SQL_SO_DYNAMIC
)
3181 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_DYNAMIC
;}
3182 if (pDb
->dbInf
.scrollOptions
& SQL_SO_MIXED
)
3183 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_MIXED
;}
3187 s
+= langDBINF_STATIC_SENS
;
3188 if (pDb
->dbInf
.staticSensitivity
& SQL_SS_ADDITIONS
)
3189 {s
+= langDBINF_ADDITIONS
; comma
++;}
3190 if (pDb
->dbInf
.staticSensitivity
& SQL_SS_DELETIONS
)
3191 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_DELETIONS
;}
3192 if (pDb
->dbInf
.staticSensitivity
& SQL_SS_UPDATES
)
3193 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_UPDATES
;}
3196 #pragma message enable incboodep
3200 s
+= langDBINF_TXN_CAPABLE
;
3201 switch(pDb
->dbInf
.txnCapable
)
3203 case SQL_TC_NONE
: s
+= langNO
; break;
3204 case SQL_TC_DML
: s
+= langDBINF_DML_ONLY
; break;
3205 case SQL_TC_DDL_COMMIT
: s
+= langDBINF_DDL_COMMIT
; break;
3206 case SQL_TC_DDL_IGNORE
: s
+= langDBINF_DDL_IGNORE
; break;
3207 case SQL_TC_ALL
: s
+= langDBINF_DDL_AND_DML
; break;
3211 t
.sprintf(wxT("%s%lu\n"), langDBINF_LOGIN_TIMEOUT
, pDb
->dbInf
.loginTimeout
);
3214 // Oracle specific information
3215 if (pDb
->Dbms() == dbmsORACLE
)
3218 s
+= langDBINF_ORACLE_BANNER
;
3221 // Oracle cache hit ratio
3224 pDb
->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'db block gets'"));
3226 if (pDb
->GetData(1, SQL_C_ULONG
, &dbBlockGets
, 0, &cb
))
3228 t
.sprintf(wxT("%s: %lu\n"), langDBINF_DB_BLOCK_GETS
, dbBlockGets
);
3232 ULONG consistentGets
;
3233 pDb
->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'consistent gets'"));
3235 if (pDb
->GetData(1, SQL_C_ULONG
, &consistentGets
, 0, &cb
))
3237 t
.sprintf(wxT("%s: %lu\n"), langDBINF_CONSISTENT_GETS
, consistentGets
);
3242 pDb
->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'physical reads'"));
3244 if (pDb
->GetData(1, SQL_C_ULONG
, &physReads
, 0, &cb
))
3246 t
.sprintf(wxT("%s: %lu\n"), langDBINF_PHYSICAL_READS
, physReads
);
3250 ULONG hitRatio
= (ULONG
)((1.00 - ((float)physReads
/ (float)(dbBlockGets
+ consistentGets
))) * 100.00);
3251 t
.sprintf(wxT("*** %s: %lu%%\n"), langDBINF_CACHE_HIT_RATIO
, hitRatio
);
3254 // Tablespace information
3256 s
+= langDBINF_TABLESPACE_IO
;
3259 char tablespaceName
[256+1];
3260 pDb
->ExecSql(wxT("SELECT NAME,PHYRDS,PHYWRTS FROM V$DATAFILE, V$FILESTAT WHERE V$DATAFILE.FILE# = V$FILESTAT.FILE#"));
3261 while (pDb
->GetNext())
3263 pDb
->GetData(1, SQL_C_WXCHAR
, tablespaceName
, 256, &cb
);
3264 pDb
->GetData(2, SQL_C_ULONG
, &physReads
, 0, &cb
);
3265 pDb
->GetData(3, SQL_C_ULONG
, &physWrites
, 0, &cb
);
3266 t
.sprintf(wxT("%s\n\t%s: %lu\t%s: %lu\n"), tablespaceName
,
3267 langDBINF_PHYSICAL_READS
, physReads
, langDBINF_PHYSICAL_WRITES
, physWrites
);
3274 s
+= wxT("End of Diagnostics\n");
3277 } // DisplayDbDiagnostics()
3281 BEGIN_EVENT_TABLE(DbGridFrame
, wxFrame
)
3282 // EVT_CLOSE(DbGridFrame::OnCloseWindow)
3286 DbGridFrame::DbGridFrame(wxWindow
*parent
)
3287 : wxFrame (parent
, wxID_ANY
, wxT("Database Table"),
3288 wxDefaultPosition
, wxSize(400, 325))
3290 initialized
= false;
3294 void DbGridFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
3300 bool DbGridFrame::Initialize()
3302 wxGrid
*grid
= new wxGrid(this, wxID_ANY
, wxDefaultPosition
);
3304 grid
->RegisterDataType(wxGRID_VALUE_DATETIME
,
3305 new wxGridCellDateTimeRenderer(wxT("%d %b %Y")),
3306 new wxGridCellTextEditor
);
3308 grid
->RegisterDataType(wxGRID_VALUE_CHOICEINT
,
3309 new wxGridCellEnumRenderer
,
3310 new wxGridCellEnumEditor
);
3312 wxString
NativeLangChoice( wxString::Format(wxT("%s:%s,%s,%s,%s,%s"),wxGRID_VALUE_CHOICEINT
,
3320 // Columns must match the sequence specified in SetColDef() calls
3321 wxDbGridColInfo
* cols
=
3322 new wxDbGridColInfo( 0,wxGRID_VALUE_STRING
,wxT("Name"),
3323 new wxDbGridColInfo( 1,wxGRID_VALUE_STRING
,wxT("Address 1"),
3324 new wxDbGridColInfo( 2,wxGRID_VALUE_STRING
,wxT("Address 2"),
3325 new wxDbGridColInfo( 3,wxGRID_VALUE_STRING
,wxT("City"),
3326 new wxDbGridColInfo( 4,wxGRID_VALUE_STRING
,wxT("State"),
3327 new wxDbGridColInfo( 5,wxGRID_VALUE_STRING
,wxT("PostCode"),
3328 new wxDbGridColInfo( 6,wxGRID_VALUE_STRING
,wxT("Country"),
3329 new wxDbGridColInfo( 7,wxGRID_VALUE_DBAUTO
,wxT("Join Date"),
3330 new wxDbGridColInfo( 8,wxGRID_VALUE_BOOL
, wxT("Developer"),
3331 new wxDbGridColInfo( 9,wxGRID_VALUE_NUMBER
,wxT("Contributions"),
3332 new wxDbGridColInfo(10,wxGRID_VALUE_NUMBER
,wxT("Lines Of Code"),
3334 new wxDbGridColInfo(11,NativeLangChoice
, wxT("Native Language"),NULL
))))))))))));
3336 new wxDbGridColInfo(11,wxGRID_VALUE_NUMBER
,wxT("Native Language"),NULL
))))))))))));
3339 Ccontact
*Contact
= new Ccontact();
3340 //wxGetApp().Contact
3344 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"), wxT("Error..."), wxOK
| wxICON_EXCLAMATION
);
3348 if (!Contact
->Open())
3350 if (Contact
->GetDb()->TableExists(CONTACT_TABLE_NAME
, Contact
->GetDb()->GetUsername(),
3351 wxGetApp().DbConnectInf
->GetDefaultDir()))
3354 tStr
.Printf(wxT("Unable to open the table '%s'.\n\n"),CONTACT_TABLE_NAME
);
3355 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
3356 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
3362 // Execute the following query using the cursor designated
3363 // for full table query
3364 Contact
->SetRowMode(wxDbTable::WX_ROW_MODE_QUERY
);
3366 if (!Contact
->Query())
3369 tStr
= wxT("ODBC error during Query()\n\n");
3370 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
3371 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
3375 // No data has been read in from the database yet, so
3376 // we need to initialize the data members to valid values
3377 // so Fit() can correctly size the grid
3378 Contact
->Initialize();
3380 wxDbGridTableBase
* db
= new wxDbGridTableBase(Contact
, cols
, wxUSE_QUERY
, true);
3384 grid
->SetTable(db
,true);
3385 grid
->SetMargins(0, 0);
3388 wxSize size
= grid
->GetSize();
3391 SetClientSize(size
);
3394 } // DbGridFrame::Initialize()
3396 #endif // #if wxUSE_GRID
3399 TEST CODE FOR TESTING THE wxDbCreateDataSource() FUNCTION
3402 result = wxDbCreateDataSource(wxT("Microsoft Access Driver (*.mdb)"), wxT("GLT-TEST2"), wxT("GLT-Descrip"), false, wxEmptyString, this);
3405 // check for errors caused by ConfigDSN based functions
3408 wxChar errMsg[500+1];
3409 errMsg[0] = wxT('\0');
3411 SQLInstallerError(1, &retcode, errMsg, 500, &cb);
3413 wxMessageBox(wxT("FAILED creating data source"), wxT("FAILED"));
3416 wxMessageBox(wxT("SUCCEEDED creating data source"), wxT("SUCCESS"));