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.
24 #include "wx/wxprec.h"
34 #if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMAC__)
38 #include <stdio.h> /* Included strictly for reading the text file with the database parameters */
40 //#include "wx/db.h" /* Required in the file which will get the data source connection */
41 //#include "wx/dbtable.h" /* Has the wxDbTable object from which all data objects will inherit their data table functionality */
43 //extern wxDbList WXDLLEXPORT *PtrBegDbList; /* from db.cpp, used in getting back error results from db connections */
47 #include "wx/generic/gridctrl.h"
48 #include "wx/dbgrid.h"
53 #include "dbtest.h" /* Header file for this demonstration program */
54 #include "listdb.h" /* Code to support the "Lookup" button on the editor dialog */
56 IMPLEMENT_APP(DatabaseDemoApp
)
58 extern wxChar ListDB_Selection
[]; /* Used to return the first column value for the selected line from the listDB routines */
59 extern wxChar ListDB_Selection2
[]; /* Used to return the second column value for the selected line from the listDB routines */
61 #ifdef wxODBC_BLOB_SUPPORT
63 #include "wx/mstream.h"
65 #include "wx/bitmap.h"
66 #include "wx/statbmp.h"
70 #error Sample cannot be compiled unless setup.h has wxUSE_ODBC set to 1
74 bool DataTypeSupported(wxDb
*pDb
, SWORD datatype
, wxString
*nativeDataTypeName
)
76 wxDbSqlTypeInfo sqlTypeInfo
;
78 bool breakpoint
= false;
80 *nativeDataTypeName
= wxEmptyString
;
81 if (pDb
->GetDataTypeInfo(datatype
, sqlTypeInfo
))
83 *nativeDataTypeName
= sqlTypeInfo
.TypeName
;
89 } // GetDataTypesSupported();
93 void CheckSupportForAllDataTypes(wxDb
*pDb
)
95 wxString nativeDataTypeName
;
97 wxLogMessage(wxT("\nThe following datatypes are supported by the\ndatabase you are currently connected to:"));
99 if (DataTypeSupported(pDb
,SQL_C_BINARY
, &nativeDataTypeName
))
101 nativeDataTypeName
= wxT("SQL_C_BINARY (") + nativeDataTypeName
;
102 nativeDataTypeName
+= wxT(")\n");
103 wxLogMessage(nativeDataTypeName
);
107 if (DataTypeSupported(pDb
,SQL_C_BIT
, &nativeDataTypeName
))
109 nativeDataTypeName
= wxT("SQL_C_BIT (") + nativeDataTypeName
;
110 nativeDataTypeName
+= wxT(")\n");
111 wxLogMessage(nativeDataTypeName
);
114 #ifdef SQL_C_BOOKMARK
115 if (DataTypeSupported(pDb
,SQL_C_BOOKMARK
, &nativeDataTypeName
))
117 nativeDataTypeName
= wxT("SQL_C_BOOKMARK (") + nativeDataTypeName
;
118 nativeDataTypeName
+= wxT(")\n");
119 wxLogMessage(nativeDataTypeName
);
123 if (DataTypeSupported(pDb
,SQL_C_CHAR
, &nativeDataTypeName
))
125 nativeDataTypeName
= wxT("SQL_C_CHAR (") + nativeDataTypeName
;
126 nativeDataTypeName
+= wxT(")\n");
127 wxLogMessage(nativeDataTypeName
);
131 if (DataTypeSupported(pDb
,SQL_C_DATE
, &nativeDataTypeName
))
133 nativeDataTypeName
= wxT("SQL_C_DATE (") + nativeDataTypeName
;
134 nativeDataTypeName
+= wxT(")\n");
135 wxLogMessage(nativeDataTypeName
);
139 if (DataTypeSupported(pDb
,SQL_C_DEFAULT
, &nativeDataTypeName
))
141 nativeDataTypeName
= wxT("SQL_C_DEFAULT (") + nativeDataTypeName
;
142 nativeDataTypeName
+= wxT(")\n");
143 wxLogMessage(nativeDataTypeName
);
147 if (DataTypeSupported(pDb
,SQL_C_DOUBLE
, &nativeDataTypeName
))
149 nativeDataTypeName
= wxT("SQL_C_DOUBLE (") + nativeDataTypeName
;
150 nativeDataTypeName
+= wxT(")\n");
151 wxLogMessage(nativeDataTypeName
);
155 if (DataTypeSupported(pDb
,SQL_C_FLOAT
, &nativeDataTypeName
))
157 nativeDataTypeName
= wxT("SQL_C_FLOAT (") + nativeDataTypeName
;
158 nativeDataTypeName
+= wxT(")\n");
159 wxLogMessage(nativeDataTypeName
);
163 if (DataTypeSupported(pDb
,SQL_C_GUID
, &nativeDataTypeName
))
165 nativeDataTypeName
= wxT("SQL_C_GUID (") + nativeDataTypeName
;
166 nativeDataTypeName
+= wxT(")\n");
167 wxLogMessage(nativeDataTypeName
);
170 #ifdef SQL_C_INTERVAL_DAY
171 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_DAY
, &nativeDataTypeName
))
173 nativeDataTypeName
= wxT("SQL_C_INTERVAL_DAY (") + nativeDataTypeName
;
174 nativeDataTypeName
+= wxT(")\n");
175 wxLogMessage(nativeDataTypeName
);
178 #ifdef SQL_C_INTERVAL_DAY_TO_HOUR
179 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_DAY_TO_HOUR
, &nativeDataTypeName
))
181 nativeDataTypeName
= wxT("SQL_C_INTERVAL_DAY_TO_HOUR (") + nativeDataTypeName
;
182 nativeDataTypeName
+= wxT(")\n");
183 wxLogMessage(nativeDataTypeName
);
186 #ifdef SQL_C_INTERVAL_DAY_TO_MINUTE
187 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_DAY_TO_MINUTE
, &nativeDataTypeName
))
189 nativeDataTypeName
= wxT("SQL_C_INTERVAL_DAY_TO_MINUTE (") + nativeDataTypeName
;
190 nativeDataTypeName
+= wxT(")\n");
191 wxLogMessage(nativeDataTypeName
);
194 #ifdef SQL_C_INTERVAL_DAY_TO_SECOND
195 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_DAY_TO_SECOND
, &nativeDataTypeName
))
197 nativeDataTypeName
= wxT("SQL_C_INTERVAL_DAY_TO_SECOND (") + nativeDataTypeName
;
198 nativeDataTypeName
+= wxT(")\n");
199 wxLogMessage(nativeDataTypeName
);
202 #ifdef SQL_C_INTERVAL_HOUR
203 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_HOUR
, &nativeDataTypeName
))
205 nativeDataTypeName
= wxT("SQL_C_INTERVAL_HOUR (") + nativeDataTypeName
;
206 nativeDataTypeName
+= wxT(")\n");
207 wxLogMessage(nativeDataTypeName
);
210 #ifdef SQL_C_INTERVAL_HOUR_TO_MINUTE
211 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_HOUR_TO_MINUTE
, &nativeDataTypeName
))
213 nativeDataTypeName
= wxT("SQL_C_INTERVAL_HOUR_TO_MINUTE (") + nativeDataTypeName
;
214 nativeDataTypeName
+= wxT(")\n");
215 wxLogMessage(nativeDataTypeName
);
218 #ifdef SQL_C_INTERVAL_HOUR_TO_SECOND
219 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_HOUR_TO_SECOND
, &nativeDataTypeName
))
221 nativeDataTypeName
= wxT("SQL_C_INTERVAL_HOUR_TO_SECOND (") + nativeDataTypeName
;
222 nativeDataTypeName
+= wxT(")\n");
223 wxLogMessage(nativeDataTypeName
);
226 #ifdef SQL_C_INTERVAL_MINUTE
227 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_MINUTE
, &nativeDataTypeName
))
229 nativeDataTypeName
= wxT("SQL_C_INTERVAL_MINUTE (") + nativeDataTypeName
;
230 nativeDataTypeName
+= wxT(")\n");
231 wxLogMessage(nativeDataTypeName
);
234 #ifdef SQL_C_INTERVAL_MINUTE_TO_SECOND
235 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_MINUTE_TO_SECOND
, &nativeDataTypeName
))
237 nativeDataTypeName
= wxT("SQL_C_INTERVAL_MINUTE_TO_SECOND (") + nativeDataTypeName
;
238 nativeDataTypeName
+= wxT(")\n");
239 wxLogMessage(nativeDataTypeName
);
242 #ifdef SQL_C_INTERVAL_MONTH
243 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_MONTH
, &nativeDataTypeName
))
245 nativeDataTypeName
= wxT("SQL_C_INTERVAL_MONTH (") + nativeDataTypeName
;
246 nativeDataTypeName
+= wxT(")\n");
247 wxLogMessage(nativeDataTypeName
);
250 #ifdef SQL_C_INTERVAL_SECOND
251 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_SECOND
, &nativeDataTypeName
))
253 nativeDataTypeName
= wxT("SQL_C_INTERVAL_SECOND (") + nativeDataTypeName
;
254 nativeDataTypeName
+= wxT(")\n");
255 wxLogMessage(nativeDataTypeName
);
258 #ifdef SQL_C_INTERVAL_YEAR
259 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_YEAR
, &nativeDataTypeName
))
261 nativeDataTypeName
= wxT("SQL_C_INTERVAL_YEAR (") + nativeDataTypeName
;
262 nativeDataTypeName
+= wxT(")\n");
263 wxLogMessage(nativeDataTypeName
);
266 #ifdef SQL_C_INTERVAL_YEAR_TO_MONTH
267 if (DataTypeSupported(pDb
,SQL_C_INTERVAL_YEAR_TO_MONTH
, &nativeDataTypeName
))
269 nativeDataTypeName
= wxT("SQL_C_INTERVAL_YEAR_TO_MONTH (") + nativeDataTypeName
;
270 nativeDataTypeName
+= wxT(")\n");
271 wxLogMessage(nativeDataTypeName
);
275 if (DataTypeSupported(pDb
,SQL_C_LONG
, &nativeDataTypeName
))
277 nativeDataTypeName
= wxT("SQL_C_LONG (") + nativeDataTypeName
;
278 nativeDataTypeName
+= wxT(")\n");
279 wxLogMessage(nativeDataTypeName
);
283 if (DataTypeSupported(pDb
,SQL_C_NUMERIC
, &nativeDataTypeName
))
285 nativeDataTypeName
= wxT("SQL_C_NUMERIC (") + nativeDataTypeName
;
286 nativeDataTypeName
+= wxT(")\n");
287 wxLogMessage(nativeDataTypeName
);
291 if (DataTypeSupported(pDb
,SQL_C_SBIGINT
, &nativeDataTypeName
))
293 nativeDataTypeName
= wxT("SQL_C_SBIGINT (") + nativeDataTypeName
;
294 nativeDataTypeName
+= wxT(")\n");
295 wxLogMessage(nativeDataTypeName
);
299 if (DataTypeSupported(pDb
,SQL_C_SHORT
, &nativeDataTypeName
))
301 nativeDataTypeName
= wxT("SQL_C_SHORT (") + nativeDataTypeName
;
302 nativeDataTypeName
+= wxT(")\n");
303 wxLogMessage(nativeDataTypeName
);
307 if (DataTypeSupported(pDb
,SQL_C_SLONG
, &nativeDataTypeName
))
309 nativeDataTypeName
= wxT("SQL_C_SLONG (") + nativeDataTypeName
;
310 nativeDataTypeName
+= wxT(")\n");
311 wxLogMessage(nativeDataTypeName
);
315 if (DataTypeSupported(pDb
,SQL_C_SSHORT
, &nativeDataTypeName
))
317 nativeDataTypeName
= wxT("SQL_C_SSHORT (") + nativeDataTypeName
;
318 nativeDataTypeName
+= wxT(")\n");
319 wxLogMessage(nativeDataTypeName
);
322 #ifdef SQL_C_STINYINT
323 if (DataTypeSupported(pDb
,SQL_C_STINYINT
, &nativeDataTypeName
))
325 nativeDataTypeName
= wxT("SQL_C_STINYINT (") + nativeDataTypeName
;
326 nativeDataTypeName
+= wxT(")\n");
327 wxLogMessage(nativeDataTypeName
);
331 if (DataTypeSupported(pDb
,SQL_C_TIME
, &nativeDataTypeName
))
333 nativeDataTypeName
= wxT("SQL_C_TIME (") + nativeDataTypeName
;
334 nativeDataTypeName
+= wxT(")\n");
335 wxLogMessage(nativeDataTypeName
);
338 #ifdef SQL_C_TIMESTAMP
339 if (DataTypeSupported(pDb
,SQL_C_TIMESTAMP
, &nativeDataTypeName
))
341 nativeDataTypeName
= wxT("SQL_C_TIMESTAMP (") + nativeDataTypeName
;
342 nativeDataTypeName
+= wxT(")\n");
343 wxLogMessage(nativeDataTypeName
);
347 if (DataTypeSupported(pDb
,SQL_C_TINYINT
, &nativeDataTypeName
))
349 nativeDataTypeName
= wxT("SQL_C_TINYINT (") + nativeDataTypeName
;
350 nativeDataTypeName
+= wxT(")\n");
351 wxLogMessage(nativeDataTypeName
);
354 #ifdef SQL_C_TYPE_DATE
355 if (DataTypeSupported(pDb
,SQL_C_TYPE_DATE
, &nativeDataTypeName
))
357 nativeDataTypeName
= wxT("SQL_C_TYPE_DATE (") + nativeDataTypeName
;
358 nativeDataTypeName
+= wxT(")\n");
359 wxLogMessage(nativeDataTypeName
);
362 #ifdef SQL_C_TYPE_TIME
363 if (DataTypeSupported(pDb
,SQL_C_TYPE_TIME
, &nativeDataTypeName
))
365 nativeDataTypeName
= wxT("SQL_C_TYPE_TIME (") + nativeDataTypeName
;
366 nativeDataTypeName
+= wxT(")\n");
367 wxLogMessage(nativeDataTypeName
);
370 #ifdef SQL_C_TYPE_TIMESTAMP
371 if (DataTypeSupported(pDb
,SQL_C_TYPE_TIMESTAMP
, &nativeDataTypeName
))
373 nativeDataTypeName
= wxT("SQL_C_TYPE_TIMESTAMP (") + nativeDataTypeName
;
374 nativeDataTypeName
+= wxT(")\n");
375 wxLogMessage(nativeDataTypeName
);
379 if (DataTypeSupported(pDb
,SQL_C_UBIGINT
, &nativeDataTypeName
))
381 nativeDataTypeName
= wxT("SQL_C_UBIGINT (") + nativeDataTypeName
;
382 nativeDataTypeName
+= wxT(")\n");
383 wxLogMessage(nativeDataTypeName
);
387 if (DataTypeSupported(pDb
,SQL_C_ULONG
, &nativeDataTypeName
))
389 nativeDataTypeName
= wxT("SQL_C_ULONG (") + nativeDataTypeName
;
390 nativeDataTypeName
+= wxT(")\n");
391 wxLogMessage(nativeDataTypeName
);
395 if (DataTypeSupported(pDb
,SQL_C_USHORT
, &nativeDataTypeName
))
397 nativeDataTypeName
= wxT("SQL_C_USHORT (") + nativeDataTypeName
;
398 nativeDataTypeName
+= wxT(")\n");
399 wxLogMessage(nativeDataTypeName
);
402 #ifdef SQL_C_UTINYINT
403 if (DataTypeSupported(pDb
,SQL_C_UTINYINT
, &nativeDataTypeName
))
405 nativeDataTypeName
= wxT("SQL_C_UTINYINT (") + nativeDataTypeName
;
406 nativeDataTypeName
+= wxT(")\n");
407 wxLogMessage(nativeDataTypeName
);
410 #ifdef SQL_C_VARBOOKMARK
411 if (DataTypeSupported(pDb
,SQL_C_VARBOOKMARK
, &nativeDataTypeName
))
413 nativeDataTypeName
= wxT("SQL_C_VARBOOKMARK (") + nativeDataTypeName
;
414 nativeDataTypeName
+= wxT(")\n");
415 wxLogMessage(nativeDataTypeName
);
419 if (DataTypeSupported(pDb
,SQL_C_WXCHAR
, &nativeDataTypeName
))
421 nativeDataTypeName
= wxT("SQL_C_WXCHAR (") + nativeDataTypeName
;
422 nativeDataTypeName
+= wxT(")\n");
423 wxLogMessage(nativeDataTypeName
);
427 // Extended SQL types
429 if (DataTypeSupported(pDb
,SQL_DATE
, &nativeDataTypeName
))
431 nativeDataTypeName
= wxT("SQL_DATE (") + nativeDataTypeName
;
432 nativeDataTypeName
+= wxT(")\n");
433 wxLogMessage(nativeDataTypeName
);
437 if (DataTypeSupported(pDb
,SQL_INTERVAL
, &nativeDataTypeName
))
439 nativeDataTypeName
= wxT("SQL_INTERVAL (") + nativeDataTypeName
;
440 nativeDataTypeName
+= wxT(")\n");
441 wxLogMessage(nativeDataTypeName
);
445 if (DataTypeSupported(pDb
,SQL_TIME
, &nativeDataTypeName
))
447 nativeDataTypeName
= wxT("SQL_TIME (") + nativeDataTypeName
;
448 nativeDataTypeName
+= wxT(")\n");
449 wxLogMessage(nativeDataTypeName
);
453 if (DataTypeSupported(pDb
,SQL_TIMESTAMP
, &nativeDataTypeName
))
455 nativeDataTypeName
= wxT("SQL_TIMESTAMP (") + nativeDataTypeName
;
456 nativeDataTypeName
+= wxT(")\n");
457 wxLogMessage(nativeDataTypeName
);
460 #ifdef SQL_LONGVARCHAR
461 if (DataTypeSupported(pDb
,SQL_LONGVARCHAR
, &nativeDataTypeName
))
463 nativeDataTypeName
= wxT("SQL_LONGVARCHAR (") + nativeDataTypeName
;
464 nativeDataTypeName
+= wxT(")\n");
465 wxLogMessage(nativeDataTypeName
);
469 if (DataTypeSupported(pDb
,SQL_BINARY
, &nativeDataTypeName
))
471 nativeDataTypeName
= wxT("SQL_BINARY (") + nativeDataTypeName
;
472 nativeDataTypeName
+= wxT(")\n");
473 wxLogMessage(nativeDataTypeName
);
477 if (DataTypeSupported(pDb
,SQL_VARBINARY
, &nativeDataTypeName
))
479 nativeDataTypeName
= wxT("SQL_VARBINARY (") + nativeDataTypeName
;
480 nativeDataTypeName
+= wxT(")\n");
481 wxLogMessage(nativeDataTypeName
);
484 #ifdef SQL_LONGVARBINARY
485 if (DataTypeSupported(pDb
,SQL_LONGVARBINARY
, &nativeDataTypeName
))
487 nativeDataTypeName
= wxT("SQL_LOGVARBINARY (") + nativeDataTypeName
;
488 nativeDataTypeName
+= wxT(")\n");
489 wxLogMessage(nativeDataTypeName
);
493 if (DataTypeSupported(pDb
,SQL_BIGINT
, &nativeDataTypeName
))
495 nativeDataTypeName
= wxT("SQL_BIGINT (") + nativeDataTypeName
;
496 nativeDataTypeName
+= wxT(")\n");
497 wxLogMessage(nativeDataTypeName
);
501 if (DataTypeSupported(pDb
,SQL_TINYINT
, &nativeDataTypeName
))
503 nativeDataTypeName
= wxT("SQL_TINYINT (") + nativeDataTypeName
;
504 nativeDataTypeName
+= wxT(")\n");
505 wxLogMessage(nativeDataTypeName
);
509 if (DataTypeSupported(pDb
,SQL_BIT
, &nativeDataTypeName
))
511 nativeDataTypeName
= wxT("SQL_BIT (") + nativeDataTypeName
;
512 nativeDataTypeName
+= wxT(")\n");
513 wxLogMessage(nativeDataTypeName
);
517 if (DataTypeSupported(pDb
,SQL_GUID
, &nativeDataTypeName
))
519 nativeDataTypeName
= wxT("SQL_GUID (") + nativeDataTypeName
;
520 nativeDataTypeName
+= wxT(")\n");
521 wxLogMessage(nativeDataTypeName
);
526 if (DataTypeSupported(pDb
,SQL_CHAR
, &nativeDataTypeName
))
528 nativeDataTypeName
= wxT("SQL_CHAR (") + nativeDataTypeName
;
529 nativeDataTypeName
+= wxT(")\n");
530 wxLogMessage(nativeDataTypeName
);
534 if (DataTypeSupported(pDb
,SQL_INTEGER
, &nativeDataTypeName
))
536 nativeDataTypeName
= wxT("SQL_INTEGER (") + nativeDataTypeName
;
537 nativeDataTypeName
+= wxT(")\n");
538 wxLogMessage(nativeDataTypeName
);
542 if (DataTypeSupported(pDb
,SQL_SMALLINT
, &nativeDataTypeName
))
544 nativeDataTypeName
= wxT("SQL_SAMLLINT (") + nativeDataTypeName
;
545 nativeDataTypeName
+= wxT(")\n");
546 wxLogMessage(nativeDataTypeName
);
550 if (DataTypeSupported(pDb
,SQL_REAL
, &nativeDataTypeName
))
552 nativeDataTypeName
= wxT("SQL_REAL (") + nativeDataTypeName
;
553 nativeDataTypeName
+= wxT(")\n");
554 wxLogMessage(nativeDataTypeName
);
558 if (DataTypeSupported(pDb
,SQL_DOUBLE
, &nativeDataTypeName
))
560 nativeDataTypeName
= wxT("SQL_DOUBLE (") + nativeDataTypeName
;
561 nativeDataTypeName
+= wxT(")\n");
562 wxLogMessage(nativeDataTypeName
);
566 if (DataTypeSupported(pDb
,SQL_NUMERIC
, &nativeDataTypeName
))
568 nativeDataTypeName
= wxT("SQL_NUMERIC (") + nativeDataTypeName
;
569 nativeDataTypeName
+= wxT(")\n");
570 wxLogMessage(nativeDataTypeName
);
574 if (DataTypeSupported(pDb
,SQL_DATE
, &nativeDataTypeName
))
576 nativeDataTypeName
= wxT("SQL_DATE (") + nativeDataTypeName
;
577 nativeDataTypeName
+= wxT(")\n");
578 wxLogMessage(nativeDataTypeName
);
582 if (DataTypeSupported(pDb
,SQL_TIME
, &nativeDataTypeName
))
584 nativeDataTypeName
= wxT("SQL_TIME (") + nativeDataTypeName
;
585 nativeDataTypeName
+= wxT(")\n");
586 wxLogMessage(nativeDataTypeName
);
590 if (DataTypeSupported(pDb
,SQL_TIMESTAMP
, &nativeDataTypeName
))
592 nativeDataTypeName
= wxT("SQL_TIMESTAMP (") + nativeDataTypeName
;
593 nativeDataTypeName
+= wxT(")\n");
594 wxLogMessage(nativeDataTypeName
);
598 if (DataTypeSupported(pDb
,SQL_VARCHAR
, &nativeDataTypeName
))
600 nativeDataTypeName
= wxT("SQL_VARCHAR (") + nativeDataTypeName
;
601 nativeDataTypeName
+= wxT(")\n");
602 wxLogMessage(nativeDataTypeName
);
608 if (DataTypeSupported(pDb
,SQL_C_TCHAR
, &nativeDataTypeName
))
610 nativeDataTypeName
= wxT("SQL_C_TCHAR (") + nativeDataTypeName
;
611 nativeDataTypeName
+= wxT(")\n");
612 wxLogMessage(nativeDataTypeName
);
616 if (DataTypeSupported(pDb
,SQL_WVARCHAR
, &nativeDataTypeName
))
618 nativeDataTypeName
= wxT("SQL_WVARCHAR (") + nativeDataTypeName
;
619 nativeDataTypeName
+= wxT(")\n");
620 wxLogMessage(nativeDataTypeName
);
624 if (DataTypeSupported(pDb
,SQL_WCHAR
, &nativeDataTypeName
))
626 nativeDataTypeName
= wxT("SQL_WCHAR (") + nativeDataTypeName
;
627 nativeDataTypeName
+= wxT(")\n");
628 wxLogMessage(nativeDataTypeName
);
632 wxLogMessage(wxT("Done\n"));
633 } // CheckSupportForAllDataTypes()
636 bool DatabaseDemoApp::OnInit()
638 if ( !wxApp::OnInit() )
644 // Create the main frame window
645 DemoFrame
= new DatabaseDemoFrame(NULL
, wxT("wxWidgets Database Demo"), wxPoint(50, 50), wxSize(537, 530));
648 DemoFrame
->SetIcon(wxICON(db
));
651 wxMenu
*file_menu
= new wxMenu
;
652 file_menu
->Append(FILE_CREATE_ID
, wxT("&Create CONTACT table"));
653 file_menu
->Append(FILE_RECREATE_TABLE
, wxT("&Recreate CONTACT table"));
654 file_menu
->Append(FILE_RECREATE_INDEXES
, wxT("&Recreate CONTACT indexes"));
656 file_menu
->Append(FILE_DBGRID_TABLE
, wxT("&Open DB Grid example"));
658 file_menu
->Append(FILE_EXIT
, wxT("E&xit"));
660 wxMenu
*edit_menu
= new wxMenu
;
661 edit_menu
->Append(EDIT_PARAMETERS
, wxT("&Parameters..."));
663 wxMenu
*help_menu
= new wxMenu
;
664 help_menu
->Append(HELP_ABOUT
, wxT("&About"));
666 wxMenuBar
*menu_bar
= new wxMenuBar
;
667 menu_bar
->Append(file_menu
, wxT("&File"));
668 menu_bar
->Append(edit_menu
, wxT("&Edit"));
669 menu_bar
->Append(help_menu
, wxT("&Help"));
670 DemoFrame
->SetMenuBar(menu_bar
);
672 params
.ODBCSource
[0] = 0;
673 params
.UserName
[0] = 0;
674 params
.Password
[0] = 0;
675 params
.DirPath
[0] = 0;
677 #ifdef wxODBC_BLOB_SUPPORT
678 wxInitAllImageHandlers();
679 wxImage::InitStandardHandlers();
680 wxBitmap::InitStandardHandlers();
684 DemoFrame
->Show(true);
686 // Passing NULL for the SQL environment handle causes
687 // the wxDbConnectInf constructor to obtain a handle
690 // WARNING: Be certain that you do not free this handle
691 // directly with SQLFreeEnv(). Use either the
692 // method ::FreeHenv() or delete the DbConnectInf.
693 DbConnectInf
= new wxDbConnectInf(NULL
, params
.ODBCSource
, params
.UserName
,
694 params
.Password
, params
.DirPath
);
696 if (!DbConnectInf
|| !DbConnectInf
->GetHenv())
698 wxMessageBox(wxT("Unable to define data source connection info."), wxT("DB CONNECTION ERROR..."),wxOK
| wxICON_EXCLAMATION
);
699 wxDELETE(DbConnectInf
);
702 if (!ReadParamFile(params
))
703 DemoFrame
->BuildParameterDialog(NULL
);
705 if (!wxStrlen(params
.ODBCSource
))
707 wxDELETE(DbConnectInf
);
711 DbConnectInf
->SetDsn(params
.ODBCSource
);
712 DbConnectInf
->SetUserID(params
.UserName
);
713 DbConnectInf
->SetPassword(params
.Password
);
714 DbConnectInf
->SetDefaultDir(params
.DirPath
);
716 READONLY_DB
= wxDbGetConnection(DbConnectInf
);
717 if (READONLY_DB
== 0)
719 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
);
720 DemoFrame
->BuildParameterDialog(NULL
);
721 wxDELETE(DbConnectInf
);
722 wxMessageBox(wxT("Now exiting program.\n\nRestart program to try any new settings."),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
726 DemoFrame
->BuildEditorDialog();
729 DemoFrame
->Refresh();
732 } // DatabaseDemoApp::OnInit()
736 * Remove CR or CR/LF from a character string.
738 wxChar
* wxRemoveLineTerminator(wxChar
* aString
)
740 int len
= wxStrlen(aString
);
741 while (len
> 0 && (aString
[len
-1] == wxT('\r') || aString
[len
-1] == wxT('\n'))) {
742 aString
[len
-1] = wxT('\0');
749 bool DatabaseDemoApp::ReadParamFile(Cparameters
¶ms
)
752 if ((paramFile
= wxFopen(PARAM_FILENAME
, wxT("r"))) == NULL
)
755 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
.c_str());
756 wxMessageBox(tStr
,wxT("File I/O Error..."),wxOK
| wxICON_EXCLAMATION
);
761 wxChar buffer
[1000+1];
762 wxFgets(buffer
, sizeof(params
.ODBCSource
), paramFile
);
763 wxRemoveLineTerminator(buffer
);
764 wxStrcpy(params
.ODBCSource
,buffer
);
766 wxFgets(buffer
, sizeof(params
.UserName
), paramFile
);
767 wxRemoveLineTerminator(buffer
);
768 wxStrcpy(params
.UserName
,buffer
);
770 wxFgets(buffer
, sizeof(params
.Password
), paramFile
);
771 wxRemoveLineTerminator(buffer
);
772 wxStrcpy(params
.Password
,buffer
);
774 wxFgets(buffer
, sizeof(params
.DirPath
), paramFile
);
775 wxRemoveLineTerminator(buffer
);
776 wxStrcpy(params
.DirPath
,buffer
);
781 } // DatabaseDemoApp::ReadParamFile()
784 bool DatabaseDemoApp::WriteParamFile(Cparameters
&WXUNUSED(params
))
787 if ((paramFile
= wxFopen(PARAM_FILENAME
, wxT("wt"))) == NULL
)
790 tStr
.Printf(wxT("Unable to write/overwrite '%s'."),PARAM_FILENAME
.c_str());
791 wxMessageBox(tStr
,wxT("File I/O Error..."),wxOK
| wxICON_EXCLAMATION
);
795 wxFputs(wxGetApp().params
.ODBCSource
, paramFile
);
796 wxFputc(wxT('\n'), paramFile
);
797 wxFputs(wxGetApp().params
.UserName
, paramFile
);
798 wxFputc(wxT('\n'), paramFile
);
799 wxFputs(wxGetApp().params
.Password
, paramFile
);
800 wxFputc(wxT('\n'), paramFile
);
801 wxFputs(wxGetApp().params
.DirPath
, paramFile
);
802 wxFputc(wxT('\n'), paramFile
);
806 } // DatabaseDemoApp::WriteParamFile()
809 void DatabaseDemoApp::CreateDataTable(bool recreate
)
813 Ok
= (wxMessageBox(wxT("Any data currently residing in the table will be erased.\n\nAre you sure?"),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
822 Contact
->GetDb()->RollbackTrans(); // Make sure the current cursor is in a known/stable state
824 if (!Contact
->CreateTable(recreate
))
828 tStr
= wxT("Error creating CONTACTS table.\nTable was not created.\n\n");
829 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),Contact
->GetDb(),__TFILE__
,__LINE__
),
830 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
836 if (!Contact
->CreateIndexes(recreate
))
840 tStr
= wxT("Error creating CONTACTS indexes.\nIndexes will be unavailable.\n\n");
841 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),Contact
->GetDb(),__TFILE__
,__LINE__
),
842 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
851 wxMessageBox(wxT("Table and index(es) were successfully created."),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
852 } // DatabaseDemoApp::CreateDataTable()
855 BEGIN_EVENT_TABLE(DatabaseDemoFrame
, wxFrame
)
856 EVT_MENU(FILE_CREATE_ID
, DatabaseDemoFrame::OnCreate
)
857 EVT_MENU(FILE_RECREATE_TABLE
, DatabaseDemoFrame::OnRecreateTable
)
858 EVT_MENU(FILE_RECREATE_INDEXES
, DatabaseDemoFrame::OnRecreateIndexes
)
860 EVT_MENU(FILE_DBGRID_TABLE
, DatabaseDemoFrame::OnDbGridTable
)
862 EVT_MENU(FILE_EXIT
, DatabaseDemoFrame::OnExit
)
863 EVT_MENU(EDIT_PARAMETERS
, DatabaseDemoFrame::OnEditParameters
)
864 EVT_MENU(HELP_ABOUT
, DatabaseDemoFrame::OnAbout
)
865 EVT_CLOSE(DatabaseDemoFrame::OnCloseWindow
)
869 // DatabaseDemoFrame constructor
870 DatabaseDemoFrame::DatabaseDemoFrame(wxFrame
*frame
, const wxString
& title
,
871 const wxPoint
& pos
, const wxSize
& size
):
872 wxFrame(frame
, wxID_ANY
, title
, pos
, size
)
874 // Put any code in necessary for initializing the main frame here
879 delete wxLog::SetActiveTarget(new wxLogStderr
);
882 } // DatabaseDemoFrame constructor
884 DatabaseDemoFrame::~DatabaseDemoFrame()
887 delete wxLog::SetActiveTarget(NULL
);
889 } // DatabaseDemoFrame destructor
892 void DatabaseDemoFrame::OnCreate(wxCommandEvent
& WXUNUSED(event
))
894 wxGetApp().CreateDataTable(false);
895 } // DatabaseDemoFrame::OnCreate()
898 void DatabaseDemoFrame::OnRecreateTable(wxCommandEvent
& WXUNUSED(event
))
900 wxGetApp().CreateDataTable(true);
901 } // DatabaseDemoFrame::OnRecreate()
904 void DatabaseDemoFrame::OnRecreateIndexes(wxCommandEvent
& WXUNUSED(event
))
906 wxGetApp().Contact
->GetDb()->RollbackTrans(); // Make sure the current cursor is in a known/stable state
908 if (!wxGetApp().Contact
->CreateIndexes(true))
913 tStr
= wxT("Error creating CONTACTS indexes.\nNew indexes will be unavailable.\n\n");
914 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
915 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
919 wxMessageBox(wxT("Index(es) were successfully recreated."),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
921 } // DatabaseDemoFrame::OnRecreateIndexes()
925 void DatabaseDemoFrame::OnDbGridTable(wxCommandEvent
& WXUNUSED(event
))
927 DbGridFrame
*frame
= new DbGridFrame(this);
928 if (frame
->Initialize())
935 void DatabaseDemoFrame::OnExit(wxCommandEvent
& WXUNUSED(event
))
938 } // DatabaseDemoFrame::OnExit()
941 void DatabaseDemoFrame::OnEditParameters(wxCommandEvent
& WXUNUSED(event
))
943 if ((pEditorDlg
->mode
!= mCreate
) && (pEditorDlg
->mode
!= mEdit
))
944 BuildParameterDialog(this);
946 wxMessageBox(wxT("Cannot change database parameters while creating or editing a record"),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
947 } // DatabaseDemoFrame::OnEditParameters()
950 void DatabaseDemoFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
952 wxMessageBox(wxT("wxWidgets sample program for database classes\n\nContributed on 27 July 1998"),wxT("About..."),wxOK
| wxICON_INFORMATION
);
953 } // DatabaseDemoFrame::OnAbout()
956 // Put any additional checking necessary to make certain it is alright
957 // to close the program here that is not done elsewhere
958 void DatabaseDemoFrame::OnCloseWindow(wxCloseEvent
& event
)
961 if (pEditorDlg
&& pEditorDlg
->Close())
972 wxDELETE(wxGetApp().Contact
);
974 // This function will close all the connections to the database that have been
975 // previously cached.
976 wxDbCloseConnections();
978 // Deletion of the wxDbConnectInf instance must be the LAST thing done that
979 // has anything to do with the database. Deleting this before disconnecting,
980 // freeing/closing connections, etc will result in a crash!
981 wxDELETE(wxGetApp().DbConnectInf
);
985 } // DatabaseDemoFrame::OnCloseWindow()
988 void DatabaseDemoFrame::BuildEditorDialog()
991 pEditorDlg
= new CeditorDlg(this);
994 pEditorDlg
->Initialize();
995 if (!pEditorDlg
->initialized
)
999 wxMessageBox(wxT("Unable to initialize the editor dialog for some reason"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
1005 wxMessageBox(wxT("Unable to create the editor dialog for some reason"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
1008 } // DatabaseDemoFrame::BuildEditorDialog()
1011 void DatabaseDemoFrame::BuildParameterDialog(wxWindow
*parent
)
1013 pParamDlg
= new CparameterDlg(parent
);
1016 wxMessageBox(wxT("Unable to create the parameter dialog for some reason"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
1017 } // DatabaseDemoFrame::BuildParameterDialog()
1021 * Constructor note: If no wxDb object is passed in, a new connection to the database
1022 * is created for this instance of Ccontact. This can be a slow process depending
1023 * on the database engine being used, and some database engines have a limit on the
1024 * number of connections (either hard limits, or license restricted) so care should
1025 * be used to use as few connections as is necessary.
1027 * IMPORTANT: Objects which share a wxDb pointer are ALL acted upon whenever a member
1028 * function of pDb is called (i.e. CommitTrans() or RollbackTrans(), so if modifying
1029 * or creating a table objects which use the same pDb, know that all the objects
1030 * will be committed or rolled back when any of the objects has this function call made.
1032 Ccontact::Ccontact (wxDb
*pwxDb
) : wxDbTable(pwxDb
? pwxDb
: wxDbGetConnection(wxGetApp().DbConnectInf
),
1033 CONTACT_TABLE_NAME
, CONTACT_NO_COLS
, (const wxString
&)wxEmptyString
,
1034 !wxDB_QUERY_ONLY
, wxGetApp().DbConnectInf
->GetDefaultDir())
1036 // This is used to represent whether the database connection should be released
1037 // when this instance of the object is deleted. If using the same connection
1038 // for multiple instance of database objects, then the connection should only be
1039 // released when the last database instance using the connection is deleted
1040 freeDbConn
= !pwxDb
;
1043 GetDb()->SetSqlLogging(sqlLogON
);
1047 } // Ccontact Constructor
1050 void Ccontact::Initialize()
1059 JoinDate
.year
= 1980;
1063 JoinDate
.minute
= 0;
1064 JoinDate
.second
= 0;
1065 JoinDate
.fraction
= 0;
1066 NativeLanguage
= langENGLISH
;
1067 IsDeveloper
= false;
1071 memset(Picture
, 0, MAX_PICTURE_SIZE
);
1072 } // Ccontact::Initialize
1075 Ccontact::~Ccontact()
1079 if (!wxDbFreeConnection(GetDb()))
1082 tStr
= wxT("Unable to Free the Ccontact data table handle\n\n");
1084 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1085 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1088 } // Ccontract destructor
1092 * Handles setting up all the connections for the interface from the wxDbTable
1093 * functions to interface to the data structure used to store records in
1094 * memory, and for all the column definitions that define the table structure
1096 void Ccontact::SetupColumns()
1098 // NOTE: Columns now are 8 character names, as that is all dBase can support. Longer
1099 // names can be used for other database engines
1100 SetColDefs ( 0,wxT("NAME"), DB_DATA_TYPE_VARCHAR
, Name
, SQL_C_WXCHAR
, sizeof(Name
), true, true); // Primary index
1101 SetColDefs ( 1,wxT("ADDRESS1"), DB_DATA_TYPE_VARCHAR
, Addr1
, SQL_C_WXCHAR
, sizeof(Addr1
), false,true);
1102 SetColDefs ( 2,wxT("ADDRESS2"), DB_DATA_TYPE_VARCHAR
, Addr2
, SQL_C_WXCHAR
, sizeof(Addr2
), false,true);
1103 SetColDefs ( 3,wxT("CITY"), DB_DATA_TYPE_VARCHAR
, City
, SQL_C_WXCHAR
, sizeof(City
), false,true);
1104 SetColDefs ( 4,wxT("STATE"), DB_DATA_TYPE_VARCHAR
, State
, SQL_C_WXCHAR
, sizeof(State
), false,true);
1105 SetColDefs ( 5,wxT("POSTCODE"), DB_DATA_TYPE_VARCHAR
, PostalCode
, SQL_C_WXCHAR
, sizeof(PostalCode
), false,true);
1106 SetColDefs ( 6,wxT("COUNTRY"), DB_DATA_TYPE_VARCHAR
, Country
, SQL_C_WXCHAR
, sizeof(Country
), false,true);
1107 SetColDefs ( 7,wxT("JOINDATE"), DB_DATA_TYPE_DATE
, &JoinDate
, SQL_C_TIMESTAMP
, sizeof(JoinDate
), false,true);
1108 SetColDefs ( 8,wxT("IS_DEV"), DB_DATA_TYPE_INTEGER
, &IsDeveloper
, SQL_C_BOOLEAN(IsDeveloper
), sizeof(IsDeveloper
), false,true);
1109 SetColDefs ( 9,wxT("CONTRIBS"), DB_DATA_TYPE_INTEGER
, &Contributions
, SQL_C_UTINYINT
, sizeof(Contributions
), false,true);
1110 SetColDefs (10,wxT("LINE_CNT"), DB_DATA_TYPE_INTEGER
, &LinesOfCode
, SQL_C_ULONG
, sizeof(LinesOfCode
), false,true);
1111 SetColDefs (11,wxT("LANGUAGE"), DB_DATA_TYPE_INTEGER
, &NativeLanguage
, SQL_C_ENUM
, sizeof(NativeLanguage
), false,true);
1112 #ifdef wxODBC_BLOB_SUPPORT
1113 SetColDefs (12,wxT("PICSIZE"), DB_DATA_TYPE_INTEGER
, &BlobSize
, SQL_C_ULONG
, sizeof(BlobSize
), false,true);
1114 SetColDefs (13,wxT("PICTURE"), DB_DATA_TYPE_BLOB
, Picture
, SQL_C_BINARY
, sizeof(Picture
), false,true);
1116 } // Ccontact::SetupColumns
1119 bool Ccontact::CreateIndexes(bool recreate
)
1121 // This index could easily be accomplished with an "orderBy" clause,
1122 // but is done to show how to construct a non-primary index.
1124 wxDbIdxDef idxDef
[2];
1126 wxStrcpy(idxDef
[0].ColName
, wxT("IS_DEV"));
1127 idxDef
[0].Ascending
= true;
1129 wxStrcpy(idxDef
[1].ColName
, wxT("NAME"));
1130 idxDef
[1].Ascending
= true;
1132 indexName
= GetTableName();
1133 indexName
+= wxT("_IDX1");
1135 return CreateIndex(indexName
.c_str(), true, 2, idxDef
, recreate
);
1137 } // Ccontact::CreateIndexes()
1141 * Having a function to do a query on the primary key (and possibly others) is
1142 * very efficient and tighter coding so that it is available where ever the object
1143 * is. Great for use with multiple tables when not using views or outer joins
1145 bool Ccontact::FetchByName(const wxString
&name
)
1147 whereStr
.Printf(wxT("NAME = '%s'"),name
.c_str());
1148 SetWhereClause(whereStr
.c_str());
1149 SetOrderByClause(wxEmptyString
);
1157 } // Ccontact::FetchByName()
1162 * ************* DIALOGS ***************
1167 /* CeditorDlg constructor
1169 * Creates the dialog used for creating/editing/deleting/copying a Ccontact object.
1170 * This dialog actually is drawn in the main frame of the program
1172 * An instance of Ccontact is created - "Contact" - which is used to hold the Ccontact
1173 * object that is currently being worked with.
1176 BEGIN_EVENT_TABLE(CeditorDlg
, wxPanel
)
1177 EVT_BUTTON(wxID_ANY
, CeditorDlg::OnButton
)
1178 EVT_CLOSE(CeditorDlg::OnCloseWindow
)
1181 CeditorDlg::CeditorDlg(wxWindow
*parent
) : wxPanel (parent
, 0, 0, 537, 530)
1183 // Since the ::OnCommand() function is overridden, this prevents the widget
1184 // detection in ::OnCommand() until all widgets have been initialized to prevent
1185 // uninitialized pointers from crashing the program
1186 widgetPtrsSet
= false;
1188 initialized
= false;
1193 } // CeditorDlg constructor
1196 void CeditorDlg::OnCloseWindow(wxCloseEvent
& event
)
1199 if ((mode
!= mCreate
) && (mode
!= mEdit
))
1205 wxMessageBox(wxT("Must finish processing the current record being created/modified before exiting"),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
1208 } // CeditorDlg::OnCloseWindow()
1211 void CeditorDlg::OnButton(wxCommandEvent
&event
)
1213 wxWindow
*win
= (wxWindow
*) event
.GetEventObject();
1214 OnCommand( *win
, event
);
1215 } // CeditorDlg::OnButton()
1218 void CeditorDlg::OnCommand(wxWindow
& win
, wxCommandEvent
& WXUNUSED(event
))
1220 wxString widgetName
;
1222 widgetName
= win
.GetName();
1227 if (widgetName
== pCreateBtn
->GetName())
1229 wxGetApp().Contact
->Initialize();
1232 pNameTxt
->SetValue(wxEmptyString
);
1233 pNameTxt
->SetFocus();
1237 if (widgetName
== pEditBtn
->GetName())
1239 saveName
= wxGetApp().Contact
->Name
;
1241 pNameTxt
->SetFocus();
1245 if (widgetName
== pCopyBtn
->GetName())
1248 pNameTxt
->SetValue(wxEmptyString
);
1249 pNameTxt
->SetFocus();
1253 if (widgetName
== pDeleteBtn
->GetName())
1255 bool Ok
= (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
1260 if (Ok
&& wxGetApp().Contact
->Delete())
1262 // NOTE: Deletions are not finalized until a CommitTrans() is performed.
1263 // If the commit were not performed, the program will continue to
1264 // show the table contents as if they were deleted until this instance
1265 // of Ccontact is deleted. If the Commit wasn't performed, the
1266 // database will automatically Rollback the changes when the database
1267 // connection is terminated
1268 wxGetApp().Contact
->GetDb()->CommitTrans();
1270 // Try to get the row that followed the just deleted row in the orderBy sequence
1273 // There was now row (in sequence) after the just deleted row, so get the
1274 // row which preceded the just deleted row
1277 // There are now no rows remaining, so clear the dialog widgets
1278 wxGetApp().Contact
->Initialize();
1282 SetMode(mode
); // force reset of button enable/disable
1286 wxGetApp().Contact
->GetDb()->RollbackTrans();
1292 if (widgetName
== pSaveBtn
->GetName())
1298 if (widgetName
== pCancelBtn
->GetName())
1300 bool Ok
= (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
1305 if (saveName
.empty())
1307 wxGetApp().Contact
->Initialize();
1314 // Requery previous record
1315 if (wxGetApp().Contact
->FetchByName(saveName
))
1323 // Previous record not available, retrieve first record in table
1324 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1325 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1327 wxGetApp().Contact
->whereStr
= wxT("NAME = (SELECT MIN(NAME) FROM ");
1328 wxGetApp().Contact
->whereStr
+= wxGetApp().Contact
->GetTableName();
1329 wxGetApp().Contact
->whereStr
+= wxT(")");
1330 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
.c_str());
1333 wxGetApp().Contact
->SetWhereClause(wxEmptyString
);
1335 if (!wxGetApp().Contact
->Query())
1338 tStr
= wxT("ODBC error during Query()\n\n");
1339 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1340 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1345 if (wxGetApp().Contact
->GetNext()) // Successfully read first record
1351 // No contacts are available, clear dialog
1352 wxGetApp().Contact
->Initialize();
1358 if (widgetName
== pPrevBtn
->GetName())
1365 if (widgetName
== pNextBtn
->GetName())
1372 if (widgetName
== pQueryBtn
->GetName())
1374 // Display the query dialog box
1375 wxChar qryWhere
[DB_MAX_WHERE_CLAUSE_LEN
+1];
1376 wxStrcpy(qryWhere
, (const wxChar
*) wxGetApp().Contact
->qryWhereStr
);
1377 const wxChar
*tblName
[] = {(const wxChar
*)CONTACT_TABLE_NAME
.c_str(), 0};
1378 new CqueryDlg(GetParent(), wxGetApp().Contact
->GetDb(), (wxChar
**) tblName
, qryWhere
);
1380 // Query the first record in the new record set and
1381 // display it, if the query string has changed.
1382 if (wxStrcmp(qryWhere
, (const wxChar
*) wxGetApp().Contact
->qryWhereStr
))
1384 wxGetApp().Contact
->whereStr
.Empty();
1385 wxGetApp().Contact
->SetOrderByClause(wxT("NAME"));
1387 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1388 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1390 wxGetApp().Contact
->whereStr
= wxT("NAME = (SELECT MIN(NAME) FROM ");
1391 wxGetApp().Contact
->whereStr
+= CONTACT_TABLE_NAME
;
1394 // Append the query where string (if there is one)
1395 wxGetApp().Contact
->qryWhereStr
= qryWhere
;
1396 if (wxStrlen(qryWhere
))
1398 wxGetApp().Contact
->whereStr
+= wxT(" WHERE ");
1399 wxGetApp().Contact
->whereStr
+= wxGetApp().Contact
->qryWhereStr
;
1401 // Close the expression with a right paren
1402 wxGetApp().Contact
->whereStr
+= wxT(")");
1403 // Requery the table
1404 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
.c_str());
1405 if (!wxGetApp().Contact
->Query())
1408 tStr
= wxT("ODBC error during Query()\n\n");
1409 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1410 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1414 // Display the first record from the query set
1415 if (!wxGetApp().Contact
->GetNext())
1416 wxGetApp().Contact
->Initialize();
1420 // Enable/Disable the reset button
1421 pResetBtn
->Enable(!wxGetApp().Contact
->qryWhereStr
.empty());
1427 if (widgetName
== pResetBtn
->GetName())
1429 // Clear the additional where criteria established by the query feature
1430 wxGetApp().Contact
->qryWhereStr
= wxEmptyString
;
1431 wxGetApp().Contact
->SetOrderByClause(wxT("NAME"));
1433 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1434 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1436 wxGetApp().Contact
->whereStr
= wxT("NAME = (SELECT MIN(NAME) FROM ");
1437 wxGetApp().Contact
->whereStr
+= CONTACT_TABLE_NAME
;
1438 wxGetApp().Contact
->whereStr
+= wxT(")");
1441 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
.c_str());
1442 if (!wxGetApp().Contact
->Query())
1445 tStr
= wxT("ODBC error during Query()\n\n");
1446 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1447 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1450 if (!wxGetApp().Contact
->GetNext())
1451 wxGetApp().Contact
->Initialize();
1453 pResetBtn
->Enable(false);
1459 if (widgetName
== pNameListBtn
->GetName())
1461 new ClookUpDlg(/* wxWindow *parent */ this,
1462 /* const wxString &windowTitle */ wxT("Select contact name"),
1463 /* const wxString &tableName */ CONTACT_TABLE_NAME
,
1464 /* const wxString &dispCol1 */ wxT("NAME"),
1465 /* const wxString &dispCol2 */ wxT("JOINDATE"),
1466 /* const wxString &where */ wxT(""),
1467 /* const wxString &orderBy */ wxT("NAME"),
1468 /* wxDb *pDb */ wxGetApp().READONLY_DB
,
1469 /* const wxString &defDir */ wxGetApp().DbConnectInf
->GetDefaultDir(),
1470 /* bool distinctValues*/ true,
1473 if (ListDB_Selection
&& wxStrlen(ListDB_Selection
))
1475 wxString w
= wxT("NAME = '");
1476 w
+= ListDB_Selection
;
1484 if (widgetName
== pDataTypesBtn
->GetName())
1486 CheckSupportForAllDataTypes(wxGetApp().READONLY_DB
);
1487 wxMessageBox(wxT("Support datatypes was dumped to stdout."));
1489 } // Data types Button
1491 if (widgetName
== pDbDiagsBtn
->GetName())
1493 DisplayDbDiagnostics(wxGetApp().READONLY_DB
);
1494 wxMessageBox(wxT("Diagnostics info was dumped to stdout."));
1498 if (widgetName
== pCatalogBtn
->GetName())
1500 if (wxGetApp().Contact
->GetDb()->Catalog(wxEmptyString
, wxT("catalog.txt")))
1501 wxMessageBox(wxT("The file 'catalog.txt' was created."));
1503 wxMessageBox(wxT("Creation of the file 'catalog.txt' failed."));
1507 #ifdef wxODBC_BLOB_SUPPORT
1508 if (widgetName
== pChooseImageBtn
->GetName())
1513 if (widgetName
== pShowImageBtn
->GetName())
1519 } // CeditorDlg::OnCommand()
1522 bool CeditorDlg::Initialize()
1524 // Create the data structure and a new database connection.
1525 // (As there is not a pDb being passed in the constructor, a new database
1526 // connection is created)
1527 wxGetApp().Contact
= new Ccontact();
1529 if (!wxGetApp().Contact
)
1531 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
1535 // Check if the table exists or not. If it doesn't, ask the user if they want to
1536 // create the table. Continue trying to create the table until it exists, or user aborts
1537 while (!wxGetApp().Contact
->GetDb()->TableExists(CONTACT_TABLE_NAME
,
1538 wxGetApp().DbConnectInf
->GetUserID(),
1539 wxGetApp().DbConnectInf
->GetDefaultDir()))
1542 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
.c_str());
1543 bool createTable
= (wxMessageBox(tStr
.c_str(),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
1551 wxGetApp().CreateDataTable(false);
1554 // Tables must be "opened" before anything other than creating/deleting table can be done
1555 if (!wxGetApp().Contact
->Open())
1557 // Table does exist, or there was some problem opening it. Currently this should
1558 // never fail, except in the case of the table not exisiting or the current
1559 // user has insufficent privileges to access the table
1561 // This code is experimenting with a new function that will hopefully be available
1562 // in the 2.4 release. This check will determine whether the open failing was due
1563 // to the table not existing, or the users privileges being insufficient to
1565 if (!wxGetApp().Contact
->GetDb()->TablePrivileges(CONTACT_TABLE_NAME
, wxT("SELECT"),
1566 wxGetApp().Contact
->GetDb()->GetUsername(),
1567 wxGetApp().Contact
->GetDb()->GetUsername(),
1568 wxGetApp().DbConnectInf
->GetDefaultDir()))
1571 tStr
.Printf(wxT("Unable to open the table '%s' (likely due to\ninsufficient privileges of the logged in user).\n\n"),CONTACT_TABLE_NAME
.c_str());
1573 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1574 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1578 if (!wxGetApp().Contact
->GetDb()->TableExists(CONTACT_TABLE_NAME
,
1579 wxGetApp().Contact
->GetDb()->GetUsername(),
1580 wxGetApp().DbConnectInf
->GetDefaultDir()))
1583 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
.c_str());
1584 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1585 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1593 (void)new wxStaticBox(this, EDITOR_DIALOG_FN_GROUP
, wxEmptyString
, wxPoint(15, 1), wxSize(497, 69), 0, wxT("FunctionGrp"));
1594 (void)new wxStaticBox(this, EDITOR_DIALOG_SEARCH_GROUP
, wxEmptyString
, wxPoint(417, 1), wxSize(95, 242), 0, wxT("SearchGrp"));
1596 pCreateBtn
= new wxButton(this, EDITOR_DIALOG_CREATE
, wxT("&Create"), wxPoint( 25, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CreateBtn"));
1597 pEditBtn
= new wxButton(this, EDITOR_DIALOG_EDIT
, wxT("&Edit"), wxPoint(102, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("EditBtn"));
1598 pDeleteBtn
= new wxButton(this, EDITOR_DIALOG_DELETE
, wxT("&Delete"), wxPoint(179, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("DeleteBtn"));
1599 pCopyBtn
= new wxButton(this, EDITOR_DIALOG_COPY
, wxT("Cop&y"), wxPoint(256, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CopyBtn"));
1600 pSaveBtn
= new wxButton(this, EDITOR_DIALOG_SAVE
, wxT("&Save"), wxPoint(333, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("SaveBtn"));
1601 pCancelBtn
= new wxButton(this, EDITOR_DIALOG_CANCEL
, wxT("C&ancel"), wxPoint(430, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CancelBtn"));
1602 pPrevBtn
= new wxButton(this, EDITOR_DIALOG_PREV
, wxT("<< &Prev"), wxPoint(430, 81), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("PrevBtn"));
1603 pNextBtn
= new wxButton(this, EDITOR_DIALOG_NEXT
, wxT("&Next >>"), wxPoint(430, 121), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("NextBtn"));
1604 pQueryBtn
= new wxButton(this, EDITOR_DIALOG_QUERY
, wxT("&Query"), wxPoint(430, 161), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("QueryBtn"));
1605 pResetBtn
= new wxButton(this, EDITOR_DIALOG_RESET
, wxT("&Reset"), wxPoint(430, 200), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("ResetBtn"));
1606 pNameMsg
= new wxStaticText(this, EDITOR_DIALOG_NAME_MSG
, wxT("Name:"), wxPoint( 17, 80), wxDefaultSize
, 0, wxT("NameMsg"));
1607 pNameTxt
= new wxTextCtrl(this, EDITOR_DIALOG_NAME_TEXT
, wxEmptyString
, wxPoint( 17, 97), wxSize(308, 25), 0, wxDefaultValidator
, wxT("NameTxt"));
1608 pNameListBtn
= new wxButton(this, EDITOR_DIALOG_LOOKUP
, wxT("&Lookup"), wxPoint(333, 97), wxSize( 70, 24), 0, wxDefaultValidator
, wxT("LookupBtn"));
1609 pAddress1Msg
= new wxStaticText(this, EDITOR_DIALOG_ADDRESS1_MSG
, wxT("Address:"), wxPoint( 17, 130), wxDefaultSize
, 0, wxT("Address1Msg"));
1610 pAddress1Txt
= new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT
, wxEmptyString
, wxPoint( 17, 147), wxSize(308, 25), 0, wxDefaultValidator
, wxT("Address1Txt"));
1611 pAddress2Msg
= new wxStaticText(this, EDITOR_DIALOG_ADDRESS2_MSG
, wxT("Address:"), wxPoint( 17, 180), wxDefaultSize
, 0, wxT("Address2Msg"));
1612 pAddress2Txt
= new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT
, wxEmptyString
, wxPoint( 17, 197), wxSize(308, 25), 0, wxDefaultValidator
, wxT("Address2Txt"));
1613 pCityMsg
= new wxStaticText(this, EDITOR_DIALOG_CITY_MSG
, wxT("City:"), wxPoint( 17, 230), wxDefaultSize
, 0, wxT("CityMsg"));
1614 pCityTxt
= new wxTextCtrl(this, EDITOR_DIALOG_CITY_TEXT
, wxEmptyString
, wxPoint( 17, 247), wxSize(225, 25), 0, wxDefaultValidator
, wxT("CityTxt"));
1615 pStateMsg
= new wxStaticText(this, EDITOR_DIALOG_STATE_MSG
, wxT("State:"), wxPoint(250, 230), wxDefaultSize
, 0, wxT("StateMsg"));
1616 pStateTxt
= new wxTextCtrl(this, EDITOR_DIALOG_STATE_TEXT
, wxEmptyString
, wxPoint(250, 247), wxSize(153, 25), 0, wxDefaultValidator
, wxT("StateTxt"));
1617 pCountryMsg
= new wxStaticText(this, EDITOR_DIALOG_COUNTRY_MSG
, wxT("Country:"), wxPoint( 17, 280), wxDefaultSize
, 0, wxT("CountryMsg"));
1618 pCountryTxt
= new wxTextCtrl(this, EDITOR_DIALOG_COUNTRY_TEXT
, wxEmptyString
, wxPoint( 17, 297), wxSize(225, 25), 0, wxDefaultValidator
, wxT("CountryTxt"));
1619 pPostalCodeMsg
= new wxStaticText(this, EDITOR_DIALOG_POSTAL_MSG
, wxT("Postal Code:"),wxPoint(250, 280), wxDefaultSize
, 0, wxT("PostalCodeMsg"));
1620 pPostalCodeTxt
= new wxTextCtrl(this, EDITOR_DIALOG_POSTAL_TEXT
, wxEmptyString
, wxPoint(250, 297), wxSize(153, 25), 0, wxDefaultValidator
, wxT("PostalCodeTxt"));
1622 wxString choice_strings
[5];
1623 choice_strings
[0] = wxT("English");
1624 choice_strings
[1] = wxT("French");
1625 choice_strings
[2] = wxT("German");
1626 choice_strings
[3] = wxT("Spanish");
1627 choice_strings
[4] = wxT("Other");
1629 pNativeLangChoice
= new wxChoice(this, EDITOR_DIALOG_LANG_CHOICE
, wxPoint( 17, 346), wxSize(277, wxDefaultCoord
), 5, choice_strings
);
1630 pNativeLangMsg
= new wxStaticText(this, EDITOR_DIALOG_LANG_MSG
, wxT("Native language:"), wxPoint( 17, 330), wxDefaultSize
, 0, wxT("NativeLangMsg"));
1632 wxString radio_strings
[2];
1633 radio_strings
[0] = wxT("No");
1634 radio_strings
[1] = wxT("Yes");
1635 pDeveloperRadio
= new wxRadioBox(this,EDITOR_DIALOG_DEVELOPER
, wxT("Developer:"), wxPoint(303, 330), wxDefaultSize
, 2, radio_strings
, 2, wxHORIZONTAL
);
1636 pJoinDateMsg
= new wxStaticText(this, EDITOR_DIALOG_JOIN_MSG
, wxT("Date joined:"), wxPoint( 17, 380), wxDefaultSize
, 0, wxT("JoinDateMsg"));
1637 pJoinDateTxt
= new wxTextCtrl(this, EDITOR_DIALOG_JOIN_TEXT
, wxEmptyString
, wxPoint( 17, 397), wxSize(150, 25), 0, wxDefaultValidator
, wxT("JoinDateTxt"));
1638 pContribMsg
= new wxStaticText(this, EDITOR_DIALOG_CONTRIB_MSG
,wxT("Contributions:"), wxPoint(175, 380), wxDefaultSize
, 0, wxT("ContribMsg"));
1639 pContribTxt
= new wxTextCtrl(this, EDITOR_DIALOG_CONTRIB_TEXT
, wxEmptyString
, wxPoint(175, 397), wxSize(120, 25), 0, wxDefaultValidator
, wxT("ContribTxt"));
1640 pLinesMsg
= new wxStaticText(this, EDITOR_DIALOG_LINES_MSG
, wxT("Lines of code:"), wxPoint(303, 380), wxDefaultSize
, 0, wxT("LinesMsg"));
1641 pLinesTxt
= new wxTextCtrl(this, EDITOR_DIALOG_LINES_TEXT
, wxEmptyString
, wxPoint(303, 397), wxSize(100, 25), 0, wxDefaultValidator
, wxT("LinesTxt"));
1643 pCatalogBtn
= new wxButton(this, EDITOR_DIALOG_CATALOG
, wxT("Catalo&g"), wxPoint(430, 287), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CatalogBtn"));
1644 pDataTypesBtn
= new wxButton(this, EDITOR_DIALOG_DATATYPES
, wxT("Data&types"), wxPoint(430, 337), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("DataTypesBtn"));
1645 pDbDiagsBtn
= new wxButton(this, EDITOR_DIALOG_DB_DIAGS
, wxT("DB Dia&gs"), wxPoint(430, 387), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("DbDiagsBtn"));
1647 #ifdef wxODBC_BLOB_SUPPORT
1648 pPictureMsg
= new wxStaticText(this, EDITOR_DIALOG_PIC_MSG
, wxT("Picture:"), wxPoint( 17,430), wxDefaultSize
, 0, wxT("PicMsg"));
1649 pPictSizeMsg
= new wxStaticText(this, EDITOR_DIALOG_PICSIZE_MSG
, wxT("Picture Bytes:"), wxPoint(175,430), wxDefaultSize
, 0, wxT("PicSizeMsg"));
1650 pChooseImageBtn
= new wxButton(this, EDITOR_DIALOG_PIC_BROWSE
, wxT("Select..."), wxPoint( 17,447), wxSize( 70, 24), 0, wxDefaultValidator
, wxT("PicBrowseBtn"));
1651 pShowImageBtn
= new wxButton(this, EDITOR_DIALOG_PIC_SHOW
, wxT("Show..."), wxPoint( 97,447), wxSize( 70, 24), 0, wxDefaultValidator
, wxT("PictShowBtn"));
1652 pPictSizeTxt
= new wxTextCtrl(this, EDITOR_DIALOG_PIC_SIZE_TEXT
, wxEmptyString
, wxPoint(175,447), wxSize(120, 25), 0, wxDefaultValidator
, wxT("PictSizeTxt"));
1655 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
1656 // handle all widget processing
1657 widgetPtrsSet
= true;
1659 // Setup the orderBy and where clauses to return back a single record as the result set,
1660 // as there will only be one record being shown on the dialog at a time, this optimizes
1661 // network traffic by only returning a one row result
1663 wxGetApp().Contact
->SetOrderByClause(wxT("NAME")); // field name to sort by
1665 // The wxString "whereStr" is not a member of the wxDbTable object, it is a member variable
1666 // specifically in the Ccontact class. It is used here for simpler construction of a varying
1667 // length string, and then after the string is built, the wxDbTable member variable "where" is
1668 // assigned the pointer to the constructed string.
1670 // The constructed where clause below has a sub-query within it "SELECT MIN(NAME) FROM %s"
1671 // to achieve a single row (in this case the first name in alphabetical order).
1673 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1674 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1676 wxGetApp().Contact
->whereStr
.Printf(wxT("NAME = (SELECT MIN(NAME) FROM %s)"),
1677 wxGetApp().Contact
->GetTableName().c_str());
1678 // NOTE: (const wxChar*) returns a pointer which may not be valid later, so this is short term use only
1679 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
);
1682 wxGetApp().Contact
->SetWhereClause(wxEmptyString
);
1684 // Perform the Query to get the result set.
1685 // NOTE: If there are no rows returned, that is a valid result, so Query() would return true.
1686 // Only if there is a database error will Query() come back as false
1687 if (!wxGetApp().Contact
->Query())
1690 tStr
= wxT("ODBC error during Query()\n\n");
1691 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1692 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1696 // Since Query succeeded, now get the row that was returned
1697 if (!wxGetApp().Contact
->GetNext())
1698 // If the GetNext() failed at this point, then there are no rows to retrieve,
1699 // so clear the values in the members of "Contact" so that PutData() blanks the
1700 // widgets on the dialog
1701 wxGetApp().Contact
->Initialize();
1703 wxGetApp().Contact->GetDb()->RollbackTrans();
1712 } // CeditorDlg::Initialize()
1714 #ifdef wxODBC_BLOB_SUPPORT
1716 void CeditorDlg::OnSelectPict()
1718 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 (*.*)|*.*"), wxFD_OPEN
);
1720 if (dlg
.ShowModal() == wxID_OK
)
1722 wxFile
file(dlg
.GetPath());
1724 if (file
.IsOpened())
1726 // assume not huge file in sample
1727 long iSize
= (long)file
.Length();
1729 if ((iSize
> 0) && (iSize
< MAX_PICTURE_SIZE
))
1731 wxGetApp().Contact
->BlobSize
= (size_t)iSize
;
1733 memset(wxGetApp().Contact
->Picture
, 0, MAX_PICTURE_SIZE
);
1735 wxFileOffset iReadSize
= file
.Read(wxGetApp().Contact
->Picture
, (size_t)iSize
);
1737 if (iReadSize
< iSize
)
1738 wxMessageBox(wxT("Something bad happened while reading..."), wxT("BLOB Loading Error"), wxOK
| wxICON_EXCLAMATION
);
1741 tStr
.Printf(wxT("%ld"),iSize
);
1742 pPictSizeTxt
->SetValue(tStr
);
1745 wxMessageBox(wxT("Selected File is TOO BIG. 60k is the max image size"), wxT("BLOB Loading Error"), wxOK
| wxICON_EXCLAMATION
);
1748 wxMessageBox(wxT("Unable to open the requested image file"), wxT("File Access Error"), wxOK
| wxICON_EXCLAMATION
);
1752 void CeditorDlg::OnShowImage()
1754 if (wxGetApp().Contact
->BlobSize
> 0)
1756 CimageDlg
dlg(this, wxGetApp().Contact
->Picture
, wxGetApp().Contact
->BlobSize
);
1764 void CeditorDlg::FieldsEditable()
1769 pNameTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1770 pAddress1Txt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1771 pAddress2Txt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1772 pCityTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1773 pStateTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1774 pPostalCodeTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1775 pCountryTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1777 pJoinDateTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1778 pContribTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1779 pLinesTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1780 pNativeLangChoice
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1781 pDeveloperRadio
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1783 #ifdef wxODBC_BLOB_SUPPORT
1784 pPictSizeTxt
->Enable(false);
1785 pChooseImageBtn
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1786 pShowImageBtn
->Enable(wxGetApp().Contact
&& wxGetApp().Contact
->BlobSize
> 0); //((mode == mCreate) || (mode == mEdit));
1789 } // CeditorDlg::FieldsEditable()
1792 void CeditorDlg::SetMode(enum DialogModes m
)
1813 pCreateBtn
->Enable( !edit
);
1814 pEditBtn
->Enable( !edit
&& (wxStrcmp(wxGetApp().Contact
->Name
, wxEmptyString
) != 0) );
1815 pDeleteBtn
->Enable( !edit
&& (wxStrcmp(wxGetApp().Contact
->Name
, wxEmptyString
)!=0) );
1816 pCopyBtn
->Enable( !edit
&& (wxStrcmp(wxGetApp().Contact
->Name
, wxEmptyString
)!=0) );
1817 pSaveBtn
->Enable( edit
);
1818 pCancelBtn
->Enable( edit
);
1819 pPrevBtn
->Enable( !edit
);
1820 pNextBtn
->Enable( !edit
);
1821 pQueryBtn
->Enable( !edit
);
1822 pResetBtn
->Enable( !edit
&& !wxGetApp().Contact
->qryWhereStr
.empty() );
1823 pNameListBtn
->Enable( !edit
);
1827 } // CeditorDlg::SetMode()
1830 bool CeditorDlg::PutData()
1834 pNameTxt
->SetValue(wxGetApp().Contact
->Name
);
1835 pAddress1Txt
->SetValue(wxGetApp().Contact
->Addr1
);
1836 pAddress2Txt
->SetValue(wxGetApp().Contact
->Addr2
);
1837 pCityTxt
->SetValue(wxGetApp().Contact
->City
);
1838 pStateTxt
->SetValue(wxGetApp().Contact
->State
);
1839 pCountryTxt
->SetValue(wxGetApp().Contact
->Country
);
1840 pPostalCodeTxt
->SetValue(wxGetApp().Contact
->PostalCode
);
1842 tStr
.Printf(wxT("%d/%d/%d"),wxGetApp().Contact
->JoinDate
.month
,wxGetApp().Contact
->JoinDate
.day
,wxGetApp().Contact
->JoinDate
.year
);
1843 pJoinDateTxt
->SetValue(tStr
);
1845 tStr
.Printf(wxT("%d"),wxGetApp().Contact
->Contributions
);
1846 pContribTxt
->SetValue(tStr
);
1848 tStr
.Printf(wxT("%lu"),wxGetApp().Contact
->LinesOfCode
);
1849 pLinesTxt
->SetValue(tStr
);
1851 pNativeLangChoice
->SetSelection(wxGetApp().Contact
->NativeLanguage
);
1853 pDeveloperRadio
->SetSelection(wxGetApp().Contact
->IsDeveloper
);
1855 #ifdef wxODBC_BLOB_SUPPORT
1856 tStr
.Printf(wxT("%lu"),wxGetApp().Contact
->BlobSize
);
1857 pPictSizeTxt
->SetValue(tStr
);
1858 pShowImageBtn
->Enable(wxGetApp().Contact
->BlobSize
> 0);
1862 } // Ceditor::PutData()
1866 * Reads the data out of all the widgets on the dialog. Some data evaluation is done
1867 * to ensure that there is a name entered and that the date field is valid.
1869 * A return value of true means that valid data was retrieved from the dialog, otherwise
1870 * invalid data was found (and a message was displayed telling the user what to fix), and
1871 * the data was not placed into the appropraite fields of Ccontact
1873 bool CeditorDlg::GetData()
1875 // Validate that the data currently entered into the widgets is valid data
1878 tStr
= pNameTxt
->GetValue();
1879 if (!wxStrcmp((const wxChar
*) tStr
, wxEmptyString
))
1881 wxMessageBox(wxT("A name is required for entry into the contact table"), wxT("Notice..."), wxOK
| wxICON_INFORMATION
);
1885 bool invalid
= false;
1886 int mm
= 1,dd
= 1,yyyy
= 2001;
1889 tStr
= pJoinDateTxt
->GetValue();
1890 if (tStr
.Freq(wxT('/')) != 2)
1893 // Find the month, day, and year tokens
1896 first
= tStr
.First(wxT('/'));
1897 second
= tStr
.Last(wxT('/'));
1899 mm
= wxAtoi(tStr
.SubString(0,first
));
1900 dd
= wxAtoi(tStr
.SubString(first
+1,second
));
1901 yyyy
= wxAtoi(tStr
.SubString(second
+1,tStr
.Length()-1));
1903 invalid
= !(mm
&& dd
&& yyyy
);
1906 // Force Year 2000 compliance
1907 if (!invalid
&& (yyyy
< 1000))
1910 // Check the token ranges for validity
1915 else if ((mm
< 1) || (mm
> 12))
1923 int days
[12] = {31,28,31,30,31,30,
1925 if (dd
> days
[mm
-1])
1928 if ((dd
== 29) && (mm
== 2))
1930 if (((yyyy
% 4) == 0) && (((yyyy
% 100) != 0) || ((yyyy
% 400) == 0)))
1940 wxGetApp().Contact
->JoinDate
.month
= (unsigned short) mm
;
1941 wxGetApp().Contact
->JoinDate
.day
= (unsigned short) dd
;
1942 wxGetApp().Contact
->JoinDate
.year
= (short) yyyy
;
1946 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
);
1950 tStr
= pNameTxt
->GetValue();
1951 wxStrcpy(wxGetApp().Contact
->Name
,(const wxChar
*) tStr
);
1952 wxStrcpy(wxGetApp().Contact
->Addr1
,pAddress1Txt
->GetValue());
1953 wxStrcpy(wxGetApp().Contact
->Addr2
,pAddress2Txt
->GetValue());
1954 wxStrcpy(wxGetApp().Contact
->City
,pCityTxt
->GetValue());
1955 wxStrcpy(wxGetApp().Contact
->State
,pStateTxt
->GetValue());
1956 wxStrcpy(wxGetApp().Contact
->Country
,pCountryTxt
->GetValue());
1957 wxStrcpy(wxGetApp().Contact
->PostalCode
,pPostalCodeTxt
->GetValue());
1959 wxGetApp().Contact
->Contributions
= (UCHAR
)wxAtoi(pContribTxt
->GetValue());
1960 wxGetApp().Contact
->LinesOfCode
= wxAtol(pLinesTxt
->GetValue());
1962 wxGetApp().Contact
->NativeLanguage
= (enum Language
) pNativeLangChoice
->GetSelection();
1963 wxGetApp().Contact
->IsDeveloper
= pDeveloperRadio
->GetSelection() > 0;
1966 } // CeditorDlg::GetData()
1970 * Retrieve data from the dialog, verify the validity of the data, and if it is valid,
1971 * try to insert/update the data to the table based on the current 'mode' the dialog
1974 * A return value of true means the insert/update was completed successfully, a return
1975 * value of false means that Save() failed. If returning false, then this function
1976 * has displayed a detailed error message for the user.
1978 bool CeditorDlg::Save()
1980 bool failed
= false;
1982 // Read the data in the widgets of the dialog to get the user's data
1986 // Perform any other required validations necessary before saving
1989 wxBeginBusyCursor();
1991 if (mode
== mCreate
)
1993 RETCODE result
= (RETCODE
)wxGetApp().Contact
->Insert();
1995 failed
= (result
!= DB_SUCCESS
);
1998 // Some errors may be expected, like a duplicate key, so handle those instances with
1999 // specific error messages.
2000 if (result
== DB_ERR_INTEGRITY_CONSTRAINT_VIOL
)
2003 tStr
= wxT("A duplicate key value already exists in the table.\nUnable to save record\n\n");
2004 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2005 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2009 // Some other unexpected error occurred
2011 tStr
= wxT("Database insert failed\n\n");
2012 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2013 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2017 else // mode == mEdit
2019 wxGetApp().Contact
->GetDb()->RollbackTrans();
2020 wxGetApp().Contact
->whereStr
.Printf(wxT("NAME = '%s'"),saveName
.c_str());
2021 if (!wxGetApp().Contact
->UpdateWhere(wxGetApp().Contact
->whereStr
))
2024 tStr
= wxT("Database update failed\n\n");
2025 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2026 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2033 wxGetApp().Contact
->GetDb()->CommitTrans();
2034 SetMode(mView
); // Sets the dialog mode back to viewing after save is successful
2037 wxGetApp().Contact
->GetDb()->RollbackTrans();
2043 } // CeditorDlg::Save()
2047 * Where this program is only showing a single row at a time in the dialog,
2048 * a special where clause must be built to find just the single row which,
2049 * in sequence, would follow the currently displayed row.
2051 bool CeditorDlg::GetNextRec()
2055 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
2056 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
2058 w
= wxT("NAME = (SELECT MIN(NAME) FROM ");
2059 w
+= wxGetApp().Contact
->GetTableName();
2060 w
+= wxT(" WHERE NAME > '");
2063 w
= wxT("(NAME > '");
2065 w
+= wxGetApp().Contact
->Name
;
2068 // If a query where string is currently set, append that criteria
2069 if (!wxGetApp().Contact
->qryWhereStr
.empty())
2072 w
+= wxGetApp().Contact
->qryWhereStr
;
2079 } // CeditorDlg::GetNextRec()
2083 * Where this program is only showing a single row at a time in the dialog,
2084 * a special where clause must be built to find just the single row which,
2085 * in sequence, would precede the currently displayed row.
2087 bool CeditorDlg::GetPrevRec()
2091 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
2092 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
2094 w
= wxT("NAME = (SELECT MAX(NAME) FROM ");
2095 w
+= wxGetApp().Contact
->GetTableName();
2096 w
+= wxT(" WHERE NAME < '");
2099 w
= wxT("(NAME < '");
2101 w
+= wxGetApp().Contact
->Name
;
2104 // If a query where string is currently set, append that criteria
2105 if (!wxGetApp().Contact
->qryWhereStr
.empty())
2108 w
+= wxGetApp().Contact
->qryWhereStr
;
2116 } // CeditorDlg::GetPrevRec()
2120 * This function is here to avoid duplicating this same code in both the
2121 * GetPrevRec() and GetNextRec() functions
2123 bool CeditorDlg::GetRec(const wxString
&whereStr
)
2125 wxGetApp().Contact
->SetWhereClause(whereStr
);
2126 wxGetApp().Contact
->SetOrderByClause(wxT("NAME"));
2128 if (!wxGetApp().Contact
->Query())
2131 tStr
= wxT("ODBC error during Query()\n\n");
2132 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2133 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2138 if (wxGetApp().Contact
->GetNext())
2145 } // CeditorDlg::GetRec()
2150 * CparameterDlg constructor
2153 BEGIN_EVENT_TABLE(CparameterDlg
, wxDialog
)
2154 EVT_BUTTON(PARAMETER_DIALOG_SAVE
, CparameterDlg::OnButton
)
2155 EVT_BUTTON(PARAMETER_DIALOG_CANCEL
, CparameterDlg::OnButton
)
2156 EVT_CLOSE(CparameterDlg::OnCloseWindow
)
2159 CparameterDlg::CparameterDlg(wxWindow
*parent
) : wxDialog (parent
, PARAMETER_DIALOG
, wxT("ODBC parameter settings"), wxDefaultPosition
, wxSize(400, 325))
2161 // Since the ::OnCommand() function is overridden, this prevents the widget
2162 // detection in ::OnCommand() until all widgets have been initialized to prevent
2163 // uninitialized pointers from crashing the program
2164 widgetPtrsSet
= false;
2166 pParamODBCSourceMsg
= new wxStaticText(this, PARAMETER_DIALOG_SOURCE_MSG
, wxT("ODBC data sources:"), wxPoint( 10, 10), wxDefaultSize
, 0, wxT("ParamODBCSourceMsg"));
2167 pParamODBCSourceList
= new wxListBox(this, PARAMETER_DIALOG_SOURCE_LISTBOX
, wxPoint( 10, 29), wxSize(285, 150), 0, 0, wxLB_SINGLE
|wxLB_ALWAYS_SB
, wxDefaultValidator
, wxT("ParamODBCSourceList"));
2168 pParamUserNameMsg
= new wxStaticText(this, PARAMETER_DIALOG_NAME_MSG
, wxT("Database user name:"), wxPoint( 10, 193), wxDefaultSize
, 0, wxT("ParamUserNameMsg"));
2169 pParamUserNameTxt
= new wxTextCtrl(this, PARAMETER_DIALOG_NAME_TEXT
, wxEmptyString
, wxPoint(10, 209), wxSize( 140, 25), 0, wxDefaultValidator
, wxT("ParamUserNameTxt"));
2170 pParamPasswordMsg
= new wxStaticText(this, PARAMETER_DIALOG_PASSWORD_MSG
, wxT("Password:"), wxPoint(156, 193), wxDefaultSize
, 0, wxT("ParamPasswordMsg"));
2171 pParamPasswordTxt
= new wxTextCtrl(this, PARAMETER_DIALOG_PASSWORD_TEXT
, wxEmptyString
, wxPoint(156, 209), wxSize( 140, 25), 0, wxDefaultValidator
, wxT("ParamPasswordTxt"));
2172 pParamDirPathMsg
= new wxStaticText(this, PARAMETER_DIALOG_DIRPATH_MSG
, wxT("Directory:"), wxPoint( 10, 243), wxDefaultSize
, 0, wxT("ParamDirPathMsg"));
2173 pParamDirPathTxt
= new wxTextCtrl(this, PARAMETER_DIALOG_DIRPATH_TEXT
, wxEmptyString
, wxPoint( 10, 259), wxSize(140, 25), 0, wxDefaultValidator
, wxT("ParamDirPathTxt"));
2174 pParamSaveBtn
= new wxButton(this, PARAMETER_DIALOG_SAVE
, wxT("&Save"), wxPoint(310, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("ParamSaveBtn"));
2175 pParamCancelBtn
= new wxButton(this, PARAMETER_DIALOG_CANCEL
, wxT("C&ancel"), wxPoint(310, 66), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("ParamCancelBtn"));
2177 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
2178 // handle all widget processing
2179 widgetPtrsSet
= true;
2182 savedParamSettings
= wxGetApp().params
;
2187 } // CparameterDlg constructor
2190 void CparameterDlg::OnCloseWindow(wxCloseEvent
& event
)
2192 // Put any additional checking necessary to make certain it is alright
2193 // to close the program here that is not done elsewhere
2196 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
);
2204 wxGetApp().params
= savedParamSettings
;
2207 if (GetParent() != NULL
)
2208 GetParent()->SetFocus();
2214 SetReturnCode(0); // added so BoundsChecker would not report use of uninitialized variable
2217 } // CparameterDlg::OnCloseWindow()
2220 void CparameterDlg::OnButton( wxCommandEvent
&event
)
2222 wxWindow
*win
= (wxWindow
*) event
.GetEventObject();
2223 OnCommand( *win
, event
);
2227 void CparameterDlg::OnCommand(wxWindow
& win
, wxCommandEvent
& WXUNUSED(event
))
2229 wxString widgetName
;
2231 widgetName
= win
.GetName();
2236 if (widgetName
== pParamSaveBtn
->GetName())
2241 tStr
= wxT("Database parameters have been saved.");
2242 if (GetParent() != NULL
) // The parameter dialog was not called during startup due to a missing cfg file
2243 tStr
+= wxT("\nNew parameters will take effect the next time the program is started.");
2244 wxMessageBox(tStr
,wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
2251 if (widgetName
== pParamCancelBtn
->GetName())
2256 } // CparameterDlg::OnCommand()
2259 bool CparameterDlg::PutData()
2261 // Fill the data source list box
2262 FillDataSourceList();
2264 // Fill in the fields from the params object
2265 if (wxGetApp().params
.ODBCSource
&& wxStrlen(wxGetApp().params
.ODBCSource
))
2267 int index
= pParamODBCSourceList
->FindString(wxGetApp().params
.ODBCSource
);
2268 if (index
!= wxNOT_FOUND
)
2269 pParamODBCSourceList
->SetSelection(index
);
2271 pParamUserNameTxt
->SetValue(wxGetApp().params
.UserName
);
2272 pParamPasswordTxt
->SetValue(wxGetApp().params
.Password
);
2273 pParamDirPathTxt
->SetValue(wxGetApp().params
.DirPath
);
2275 } // CparameterDlg::PutData()
2278 bool CparameterDlg::GetData()
2281 if (pParamODBCSourceList
->GetStringSelection() != wxEmptyString
)
2283 tStr
= pParamODBCSourceList
->GetStringSelection();
2284 if (tStr
.Length() > ((int)(sizeof(wxGetApp().params
.ODBCSource
) / sizeof(wxChar
))-1))
2287 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());
2288 wxMessageBox(errmsg
, wxT("Internal program error..."), wxOK
| wxICON_EXCLAMATION
);
2291 wxStrcpy(wxGetApp().params
.ODBCSource
, tStr
);
2296 tStr
= pParamUserNameTxt
->GetValue();
2297 if (tStr
.Length() > ((int)(sizeof(wxGetApp().params
.UserName
) / sizeof(wxChar
))-1))
2300 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());
2301 wxMessageBox(errmsg
, wxT("Internal program error..."), wxOK
| wxICON_EXCLAMATION
);
2304 wxStrcpy(wxGetApp().params
.UserName
, tStr
);
2306 tStr
= pParamPasswordTxt
->GetValue();
2307 if (tStr
.Length() > ((int)(sizeof(wxGetApp().params
.Password
) / sizeof(wxChar
))-1))
2310 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());
2311 wxMessageBox(errmsg
, wxT("Internal program error..."), wxOK
| wxICON_EXCLAMATION
);
2314 wxStrcpy(wxGetApp().params
.Password
,tStr
);
2316 tStr
= pParamDirPathTxt
->GetValue();
2317 tStr
.Replace(wxT("\\"),wxT("/"));
2318 if (tStr
.Length() > ((int)(sizeof(wxGetApp().params
.DirPath
) / sizeof(wxChar
))-1))
2321 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());
2322 wxMessageBox(errmsg
, wxT("Internal program error..."), wxOK
| wxICON_EXCLAMATION
);
2325 wxStrcpy(wxGetApp().params
.DirPath
,tStr
);
2327 } // CparameterDlg::GetData()
2330 bool CparameterDlg::Save()
2332 // Copy the current params in case user cancels changing
2333 // the params, so that we can reset them.
2336 wxGetApp().params
= savedParamSettings
;
2340 wxGetApp().WriteParamFile(wxGetApp().params
);
2343 } // CparameterDlg::Save()
2346 void CparameterDlg::FillDataSourceList()
2348 wxChar Dsn
[SQL_MAX_DSN_LENGTH
+1];
2349 wxChar DsDesc
[254+1];
2350 wxSortedArrayString strArr
;
2352 while (wxDbGetDataSource(wxGetApp().DbConnectInf
->GetHenv(), Dsn
,
2353 SQL_MAX_DSN_LENGTH
, DsDesc
, 254))
2358 for (size_t i
=0; i
< strArr
.GetCount(); i
++)
2360 pParamODBCSourceList
->Append(strArr
[i
].c_str());
2363 } // CparameterDlg::FillDataSourceList()
2366 BEGIN_EVENT_TABLE(CqueryDlg
, wxDialog
)
2367 EVT_BUTTON(wxID_ANY
, CqueryDlg::OnButton
)
2368 EVT_CLOSE(CqueryDlg::OnCloseWindow
)
2372 // CqueryDlg() constructor
2373 CqueryDlg::CqueryDlg(wxWindow
*parent
, wxDb
*pDb
, wxChar
*tblName
[],
2374 const wxString
&pWhereArg
) :
2375 wxDialog (parent
, QUERY_DIALOG
, wxT("Query"), wxDefaultPosition
, wxSize(480, 360))
2377 wxBeginBusyCursor();
2381 masterTableName
= tblName
[0];
2382 widgetPtrsSet
= false;
2385 // Initialize the WHERE clause from the string passed in
2386 pWhere
= pWhereArg
; // Save a pointer to the output buffer
2387 if (pWhere
.Length() > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN
) // Check the length of the buffer passed in
2390 s
.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN
+1);
2391 wxMessageBox(s
,wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2396 pQueryCol1Msg
= new wxStaticText(this, QUERY_DIALOG_COL_MSG
, wxT("Column 1:"), wxPoint( 10, 10), wxSize( 69, 16), 0, wxT("QueryCol1Msg"));
2397 pQueryCol1Choice
= new wxChoice(this, QUERY_DIALOG_COL_CHOICE
, wxPoint( 10, 27), wxSize(250, 27), 0, 0, 0, wxDefaultValidator
, wxT("QueryCol1Choice"));
2398 pQueryNotMsg
= new wxStaticText(this, QUERY_DIALOG_NOT_MSG
, wxT("NOT"), wxPoint(268, 10), wxDefaultSize
, 0, wxT("QueryNotMsg"));
2399 pQueryNotCheck
= new wxCheckBox(this, QUERY_DIALOG_NOT_CHECKBOX
, wxEmptyString
, wxPoint(275, 37), wxSize( 20, 20), 0, wxDefaultValidator
, wxT("QueryNotCheck"));
2401 wxString choice_strings
[9];
2402 choice_strings
[0] = wxT("=");
2403 choice_strings
[1] = wxT("<");
2404 choice_strings
[2] = wxT(">");
2405 choice_strings
[3] = wxT("<=");
2406 choice_strings
[4] = wxT(">=");
2407 choice_strings
[5] = wxT("Begins");
2408 choice_strings
[6] = wxT("Contains");
2409 choice_strings
[7] = wxT("Like");
2410 choice_strings
[8] = wxT("Between");
2412 pQueryOperatorMsg
= new wxStaticText(this, QUERY_DIALOG_OP_MSG
, wxT("Operator:"), wxPoint(305, 10), wxDefaultSize
, 0, wxT("QueryOperatorMsg"));
2413 pQueryOperatorChoice
= new wxChoice(this, QUERY_DIALOG_OP_CHOICE
, wxPoint(305, 27), wxSize( 80, 27), 9, choice_strings
, 0, wxDefaultValidator
, wxT("QueryOperatorChoice"));
2414 pQueryCol2Msg
= new wxStaticText(this, QUERY_DIALOG_COL2_MSG
, wxT("Column 2:"), wxPoint( 10, 65), wxSize( 69, 16), 0, wxT("QueryCol2Msg"));
2415 pQueryCol2Choice
= new wxChoice(this, QUERY_DIALOG_COL2_CHOICE
, wxPoint( 10, 82), wxSize(250, 27), 0, 0, 0, wxDefaultValidator
, wxT("QueryCol2Choice"));
2416 pQuerySqlWhereMsg
= new wxStaticText(this, QUERY_DIALOG_WHERE_MSG
, wxT("SQL where clause:"), wxPoint( 10, 141), wxDefaultSize
, 0, wxT("QuerySqlWhereMsg"));
2417 pQuerySqlWhereMtxt
= new wxTextCtrl(this, QUERY_DIALOG_WHERE_TEXT
, wxEmptyString
, wxPoint( 10, 159), wxSize(377, 134), wxTE_MULTILINE
, wxDefaultValidator
, wxT("QuerySqlWhereMtxt"));
2418 pQueryAddBtn
= new wxButton(this, QUERY_DIALOG_ADD
, wxT("&Add"), wxPoint(406, 24), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryAddBtn"));
2419 pQueryAndBtn
= new wxButton(this, QUERY_DIALOG_AND
, wxT("A&nd"), wxPoint(406, 58), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryAndBtn"));
2420 pQueryOrBtn
= new wxButton(this, QUERY_DIALOG_OR
, wxT("&Or"), wxPoint(406, 92), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryOrBtn"));
2421 pQueryLParenBtn
= new wxButton(this, QUERY_DIALOG_LPAREN
, wxT("("), wxPoint(406, 126), wxSize( 26, 26), 0, wxDefaultValidator
, wxT("QueryLParenBtn"));
2422 pQueryRParenBtn
= new wxButton(this, QUERY_DIALOG_RPAREN
, wxT(")"), wxPoint(436, 126), wxSize( 26, 26), 0, wxDefaultValidator
, wxT("QueryRParenBtn"));
2423 pQueryDoneBtn
= new wxButton(this, QUERY_DIALOG_DONE
, wxT("&Done"), wxPoint(406, 185), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryDoneBtn"));
2424 pQueryClearBtn
= new wxButton(this, QUERY_DIALOG_CLEAR
, wxT("C&lear"), wxPoint(406, 218), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryClearBtn"));
2425 pQueryCountBtn
= new wxButton(this, QUERY_DIALOG_COUNT
, wxT("&Count"), wxPoint(406, 252), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryCountBtn"));
2426 pQueryValue1Msg
= new wxStaticText(this, QUERY_DIALOG_VALUE1_MSG
, wxT("Value:"), wxPoint(277, 66), wxDefaultSize
, 0, wxT("QueryValue1Msg"));
2427 pQueryValue1Txt
= new wxTextCtrl(this, QUERY_DIALOG_VALUE1_TEXT
, wxEmptyString
, wxPoint(277, 83), wxSize(108, 25), 0, wxDefaultValidator
, wxT("QueryValue1Txt"));
2428 pQueryValue2Msg
= new wxStaticText(this, QUERY_DIALOG_VALUE2_MSG
, wxT("AND"), wxPoint(238, 126), wxDefaultSize
, 0, wxT("QueryValue2Msg"));
2429 pQueryValue2Txt
= new wxTextCtrl(this, QUERY_DIALOG_VALUE2_TEXT
, wxEmptyString
, wxPoint(277, 120), wxSize(108, 25), 0, wxDefaultValidator
, wxT("QueryValue2Txt"));
2430 pQueryHintGrp
= new wxStaticBox(this, QUERY_DIALOG_HINT_GROUP
, wxEmptyString
, wxPoint( 10, 291), wxSize(377, 40), 0, wxT("QueryHintGrp"));
2431 pQueryHintMsg
= new wxStaticText(this, QUERY_DIALOG_HINT_MSG
, wxEmptyString
, wxPoint( 16, 306), wxDefaultSize
, 0, wxT("QueryHintMsg"));
2433 widgetPtrsSet
= true;
2434 // Initialize the dialog
2436 pQueryCol2Choice
->Append(wxT("VALUE -->"));
2437 colInf
= pDB
->GetColumns(tblName
);
2443 tStr
= wxT("ODBC error during GetColumns()\n\n");
2444 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2445 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2450 for (i
= 0; colInf
[i
].colName
&& wxStrlen(colInf
[i
].colName
); i
++)
2452 // If there is more than one table being queried, qualify
2453 // the column names with the table name prefix.
2454 if (tblName
[1] && wxStrlen(tblName
[1]))
2456 qualName
.Printf(wxT("%s.%s"), colInf
[i
].tableName
, colInf
[i
].colName
);
2457 pQueryCol1Choice
->Append(qualName
);
2458 pQueryCol2Choice
->Append(qualName
);
2460 else // Single table query, append just the column names
2462 pQueryCol1Choice
->Append(colInf
[i
].colName
);
2463 pQueryCol2Choice
->Append(colInf
[i
].colName
);
2467 pQueryCol1Choice
->SetSelection(0);
2468 pQueryCol2Choice
->SetSelection(0);
2469 pQueryOperatorChoice
->SetSelection(0);
2471 pQueryValue2Msg
->Show(false);
2472 pQueryValue2Txt
->Show(false);
2474 pQueryHintMsg
->SetLabel(langQRY_EQ
);
2476 pQuerySqlWhereMtxt
->SetValue(pWhere
.c_str());
2480 // Display the dialog window
2483 } // CqueryDlg() constructor
2486 CqueryDlg::~CqueryDlg()
2488 } // CqueryDlg::~CqueryDlg() destructor
2491 void CqueryDlg::OnButton(wxCommandEvent
&event
)
2493 wxWindow
*win
= (wxWindow
*) event
.GetEventObject();
2494 OnCommand( *win
, event
);
2495 } // CqueryDlg::OnButton()
2498 void CqueryDlg::OnCommand(wxWindow
& win
, wxCommandEvent
& WXUNUSED(event
))
2500 // Widget pointers won't be set when the dialog is constructed.
2501 // Control is passed through this function once for each widget on
2502 // a dialog as the dialog is constructed.
2506 wxString widgetName
= win
.GetName();
2508 // Operator choice box
2509 if (widgetName
== pQueryOperatorChoice
->GetName())
2511 // Set the help text
2512 switch((qryOp
) pQueryOperatorChoice
->GetSelection())
2515 pQueryHintMsg
->SetLabel(langQRY_EQ
);
2518 pQueryHintMsg
->SetLabel(langQRY_LT
);
2521 pQueryHintMsg
->SetLabel(langQRY_GT
);
2524 pQueryHintMsg
->SetLabel(langQRY_LE
);
2527 pQueryHintMsg
->SetLabel(langQRY_GE
);
2530 pQueryHintMsg
->SetLabel(langQRY_BEGINS
);
2533 pQueryHintMsg
->SetLabel(langQRY_CONTAINS
);
2536 pQueryHintMsg
->SetLabel(langQRY_LIKE
);
2539 pQueryHintMsg
->SetLabel(langQRY_BETWEEN
);
2543 // Hide the value2 widget
2544 pQueryValue2Msg
->Show(false); // BETWEEN will show this widget
2545 pQueryValue2Txt
->Show(false); // BETWEEN will show this widget
2547 // Disable the NOT operator for <, <=, >, >=
2548 switch((qryOp
) pQueryOperatorChoice
->GetSelection())
2554 pQueryNotCheck
->SetValue(0);
2555 pQueryNotCheck
->Enable(false);
2558 pQueryNotCheck
->Enable(true);
2562 // Manipulate the dialog to handle the selected operator
2563 switch((qryOp
) pQueryOperatorChoice
->GetSelection())
2570 pQueryCol2Choice
->Enable(true);
2571 if (pQueryCol2Choice
->GetSelection()) // Column name is highlighted
2573 pQueryValue1Msg
->Show(false);
2574 pQueryValue1Txt
->Show(false);
2576 else // "Value" is highlighted
2578 pQueryValue1Msg
->Show(true);
2579 pQueryValue1Txt
->Show(true);
2580 pQueryValue1Txt
->SetFocus();
2586 pQueryCol2Choice
->SetSelection(0);
2587 pQueryCol2Choice
->Enable(false);
2588 pQueryValue1Msg
->Show(true);
2589 pQueryValue1Txt
->Show(true);
2590 pQueryValue1Txt
->SetFocus();
2593 pQueryCol2Choice
->SetSelection(0);
2594 pQueryCol2Choice
->Enable(false);
2595 pQueryValue2Msg
->Show(true);
2596 pQueryValue2Txt
->Show(true);
2597 pQueryValue1Msg
->Show(true);
2598 pQueryValue1Txt
->Show(true);
2599 pQueryValue1Txt
->SetFocus();
2605 } // Operator choice box
2608 if (widgetName
== pQueryCol2Choice
->GetName())
2610 if (pQueryCol2Choice
->GetSelection()) // Column name is highlighted
2612 pQueryValue1Msg
->Show(false);
2613 pQueryValue1Txt
->Show(false);
2615 else // "Value" is highlighted
2617 pQueryValue1Msg
->Show(true);
2618 pQueryValue1Txt
->Show(true);
2619 pQueryValue1Txt
->SetFocus();
2622 } // Column 2 choice
2625 if (widgetName
== pQueryAddBtn
->GetName())
2632 if (widgetName
== pQueryAndBtn
->GetName())
2634 AppendToWhere(wxT(" AND\n"));
2639 if (widgetName
== pQueryOrBtn
->GetName())
2641 AppendToWhere(wxT(" OR\n"));
2645 // Left Paren button
2646 if (widgetName
== pQueryLParenBtn
->GetName())
2648 AppendToWhere(wxT("("));
2650 } // Left Paren button
2652 // Right paren button
2653 if (widgetName
== pQueryRParenBtn
->GetName())
2655 AppendToWhere(wxT(")"));
2657 } // Right Paren button
2660 if (widgetName
== pQueryDoneBtn
->GetName())
2662 // Be sure the where clause will not overflow the output buffer
2663 if (wxStrlen(pQuerySqlWhereMtxt
->GetValue()) > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN
)
2666 s
.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN
+1);
2667 wxMessageBox(s
,wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2670 // Validate the where clause for things such as matching parens
2671 if (!ValidateWhereClause())
2673 // Copy the where clause to the output buffer and exit
2674 pWhere
= pQuerySqlWhereMtxt
->GetValue();
2680 if (widgetName
== pQueryClearBtn
->GetName())
2682 bool Ok
= (wxMessageBox(wxT("Are you sure you wish to clear the Query?"), wxT("Confirm"), wxYES_NO
|wxICON_QUESTION
) == wxYES
);
2685 pQuerySqlWhereMtxt
->SetValue(wxEmptyString
);
2691 if (widgetName
== pQueryCountBtn
->GetName())
2693 wxBeginBusyCursor();
2699 } // CqueryDlg::OnCommand
2702 void CqueryDlg::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
2709 GetParent()->SetFocus();
2714 SetReturnCode(1); // added so BoundsChecker would not report use of uninitialized variable
2717 } // CqueryDlg::OnCloseWindow()
2720 void CqueryDlg::AppendToWhere(wxChar
*s
)
2722 wxString whereStr
= pQuerySqlWhereMtxt
->GetValue();
2724 pQuerySqlWhereMtxt
->SetValue(whereStr
);
2725 } // CqueryDlg::AppendToWhere()
2728 void CqueryDlg::ProcessAddBtn()
2730 qryOp oper
= (qryOp
) pQueryOperatorChoice
->GetSelection();
2732 // Verify that eveything is filled in correctly
2733 if (pQueryCol2Choice
->GetSelection() == 0) // "Value" is selected
2735 // Verify that value 1 is filled in
2736 if (wxStrlen(pQueryValue1Txt
->GetValue()) == 0)
2739 pQueryValue1Txt
->SetFocus();
2742 // For the BETWEEN operator, value 2 must be filled in as well
2743 if (oper
== qryOpBETWEEN
&&
2744 wxStrlen(pQueryValue2Txt
->GetValue()) == 0)
2747 pQueryValue2Txt
->SetFocus();
2752 // Build the expression and append it to the where clause window
2753 wxString s
= pQueryCol1Choice
->GetStringSelection();
2755 if (pQueryNotCheck
->GetValue() && (oper
!= qryOpEQ
))
2761 if (pQueryNotCheck
->GetValue()) // NOT box is checked
2784 s
+= wxT(" BETWEEN");
2790 int col1Idx
= pQueryCol1Choice
->GetSelection();
2793 if (colInf
[col1Idx
].sqlDataType
== SQL_VARCHAR
||
2794 oper
== qryOpBEGINS
||
2795 oper
== qryOpCONTAINS
||
2799 if (pQueryCol2Choice
->GetSelection()) // Column name
2800 s
+= pQueryCol2Choice
->GetStringSelection();
2801 else // Column 2 is a "value"
2805 if (oper
== qryOpCONTAINS
)
2807 s
+= pQueryValue1Txt
->GetValue();
2808 if (oper
== qryOpCONTAINS
|| oper
== qryOpBEGINS
)
2814 if (oper
== qryOpBETWEEN
)
2819 s
+= pQueryValue2Txt
->GetValue();
2824 AppendToWhere((wxChar
*) (const wxChar
*) s
);
2826 } // CqueryDlg::ProcessAddBtn()
2829 void CqueryDlg::ProcessCountBtn()
2831 if (!ValidateWhereClause())
2834 if (!dbTable
) // wxDbTable object needs to be created and opened
2836 dbTable
= new wxDbTable(pDB
, masterTableName
, 0, (const wxString
&)wxEmptyString
,
2838 wxGetApp().DbConnectInf
->GetDefaultDir());
2841 wxMessageBox(wxT("Memory allocation failed creating a wxDbTable object."),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2844 if (!dbTable
->Open())
2847 tStr
= wxT("ODBC error during Open()\n\n");
2848 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2849 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2854 // Count() with WHERE clause
2857 whereStr
= pQuerySqlWhereMtxt
->GetValue();
2858 dbTable
->SetWhereClause(whereStr
.c_str());
2860 ULONG whereCnt
= dbTable
->Count();
2862 // Count() of all records in the table
2863 dbTable
->SetWhereClause(wxEmptyString
);
2864 ULONG totalCnt
= dbTable
->Count();
2866 if (whereCnt
> 0 || totalCnt
== 0)
2869 tStr
.Printf(wxT("%lu of %lu records match the query criteria."),whereCnt
,totalCnt
);
2870 wxMessageBox(tStr
,wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
2875 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
);
2876 wxMessageBox(tStr
,wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
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
2884 } // CqueryDlg::ProcessCountBtn()
2887 bool CqueryDlg::ValidateWhereClause()
2889 wxString where
= pQuerySqlWhereMtxt
->GetValue();
2891 if (where
.Freq(wxT('(')) != where
.Freq(wxT(')')))
2893 wxMessageBox(wxT("There are mismatched parenthesis in the constructed where clause"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2896 // After a wxMessageBox, the focus does not necessarily return to the
2897 // window which was the focus when the message box popped up, so return
2898 // focus to the Query dialog for certain
2903 } // CqueryDlg::ValidateWhereClause()
2905 #ifdef wxODBC_BLOB_SUPPORT
2907 BEGIN_EVENT_TABLE(CimageDlg
, wxDialog
)
2908 EVT_CLOSE(CimageDlg::OnCloseWindow
)
2911 CimageDlg::CimageDlg(wxWindow
*parent
, wxChar
*pImageData
, off_t iSize
)
2912 : wxDialog(parent
, IMAGE_DIALOG
, wxT("BLOB Image"), wxDefaultPosition
, wxDefaultSize
),
2913 m_pDisplayBmp(NULL
),
2917 wxMemoryInputStream
inStream(pImageData
, iSize
);
2921 m_pImage
= new wxImage(inStream
, wxBITMAP_TYPE_ANY
);
2925 m_pBmp
= new wxBitmap(*m_pImage
);
2926 m_pDisplayBmp
= new wxStaticBitmap(this, IMAGE_DIALOG_STATIC_BMP
, *m_pBmp
, wxPoint(5,5), wxDefaultSize
);
2928 SetSize(m_pBmp
->GetWidth() + 10, m_pBmp
->GetHeight() + 30);
2933 CimageDlg::~CimageDlg()
2942 delete m_pDisplayBmp
;
2945 void CimageDlg::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
2947 GetParent()->SetFocus();
2956 void DisplayDbDiagnostics(wxDb
*pDb
)
2961 s
= wxT("Diagnostics Output\n");
2962 s
+= langDBINF_DB_NAME
;
2963 s
+= pDb
->dbInf
.dbmsName
;
2966 s
+= langDBINF_DB_VER
;
2967 s
+= pDb
->dbInf
.dbmsVer
;
2970 s
+= langDBINF_DRIVER_NAME
;
2971 s
+= pDb
->dbInf
.driverName
;
2974 s
+= langDBINF_DRIVER_ODBC_VER
;
2975 s
+= pDb
->dbInf
.odbcVer
;
2978 s
+= langDBINF_DRIVER_MGR_ODBC_VER
;
2979 s
+= pDb
->dbInf
.drvMgrOdbcVer
;
2982 s
+= langDBINF_DRIVER_VER
;
2983 s
+= pDb
->dbInf
.driverVer
;
2986 s
+= langDBINF_SERVER_NAME
;
2987 s
+= pDb
->dbInf
.serverName
;
2990 s
+= langDBINF_FILENAME
;
2991 s
+= pDb
->dbInf
.databaseName
;
2994 s
+= langDBINF_OUTER_JOINS
;
2995 s
+= pDb
->dbInf
.outerJoins
;
2998 s
+= langDBINF_STORED_PROC
;
2999 s
+= pDb
->dbInf
.procedureSupport
;
3002 if (pDb
->dbInf
.maxConnections
)
3003 t
.sprintf(wxT("%s%d\n"), langDBINF_MAX_HDBC
, pDb
->dbInf
.maxConnections
);
3005 t
.sprintf(wxT("%s%s\n"), langDBINF_MAX_HDBC
, langDBINF_UNLIMITED
);
3008 if (pDb
->dbInf
.maxStmts
)
3009 t
.sprintf(wxT("%s%d\n"), langDBINF_MAX_HSTMT
, pDb
->dbInf
.maxStmts
);
3011 t
.sprintf(wxT("%s%s\n"), langDBINF_MAX_HSTMT
, langDBINF_UNLIMITED
);
3014 s
+= langDBINF_API_LVL
;
3015 switch(pDb
->dbInf
.apiConfLvl
)
3017 case SQL_OAC_NONE
: s
+= langDBINF_NONE
; break;
3018 case SQL_OAC_LEVEL1
: s
+= langDBINF_LEVEL1
; break;
3019 case SQL_OAC_LEVEL2
: s
+= langDBINF_LEVEL2
; break;
3023 s
+= langDBINF_CLI_LVL
;
3024 switch(pDb
->dbInf
.cliConfLvl
)
3026 case SQL_OSCC_NOT_COMPLIANT
: s
+= langDBINF_NOT_COMPLIANT
; break;
3027 case SQL_OSCC_COMPLIANT
: s
+= langDBINF_COMPLIANT
; break;
3031 s
+= langDBINF_SQL_LVL
;
3032 switch(pDb
->dbInf
.sqlConfLvl
)
3034 case SQL_OSC_MINIMUM
: s
+= langDBINF_MIN_GRAMMAR
; break;
3035 case SQL_OSC_CORE
: s
+= langDBINF_CORE_GRAMMAR
; break;
3036 case SQL_OSC_EXTENDED
: s
+= langDBINF_EXT_GRAMMAR
; break;
3040 s
+= langDBINF_COMMIT_BEHAVIOR
;
3041 switch(pDb
->dbInf
.cursorCommitBehavior
)
3043 case SQL_CB_DELETE
: s
+= langDBINF_DELETE_CURSORS
; break;
3044 case SQL_CB_CLOSE
: s
+= langDBINF_CLOSE_CURSORS
; break;
3045 case SQL_CB_PRESERVE
: s
+= langDBINF_PRESERVE_CURSORS
; break;
3049 s
+= langDBINF_ROLLBACK_BEHAVIOR
;
3050 switch(pDb
->dbInf
.cursorRollbackBehavior
)
3052 case SQL_CB_DELETE
: s
+= langDBINF_DELETE_CURSORS
; break;
3053 case SQL_CB_CLOSE
: s
+= langDBINF_CLOSE_CURSORS
; break;
3054 case SQL_CB_PRESERVE
: s
+= langDBINF_PRESERVE_CURSORS
; break;
3058 s
+= langDBINF_SUPP_NOT_NULL
;
3059 switch(pDb
->dbInf
.supportNotNullClause
)
3061 case SQL_NNC_NULL
: s
+= langNO
; break;
3062 case SQL_NNC_NON_NULL
: s
+= langYES
; break;
3066 s
+= langDBINF_SUPP_IEF
;
3067 s
+= pDb
->dbInf
.supportIEF
;
3070 // DEFAULT setting for "Transaction Isolation Level"
3071 s
+= langDBINF_TXN_ISOLATION
;
3072 switch(pDb
->dbInf
.txnIsolation
)
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;
3084 // CURRENT setting for "Transaction Isolation Level"
3086 s
+= langDBINF_TXN_ISOLATION_CURR
;
3087 if (SQLGetConnectOption(pDb
->GetHDBC(),SQL_TXN_ISOLATION
,&txnIsoLvl
) == SQL_SUCCESS
)
3091 case SQL_TXN_READ_UNCOMMITTED
: s
+= langDBINF_READ_UNCOMMITTED
; break;
3092 case SQL_TXN_READ_COMMITTED
: s
+= langDBINF_READ_COMMITTED
; break;
3093 case SQL_TXN_REPEATABLE_READ
: s
+= langDBINF_REPEATABLE_READ
; break;
3094 case SQL_TXN_SERIALIZABLE
: s
+= langDBINF_SERIALIZABLE
; break;
3096 case SQL_TXN_VERSIONING
: s
+= langDBINF_VERSIONING
; break;
3103 #pragma message disable incboodep
3106 s
+= langDBINF_TXN_ISOLATION_OPTS
;
3107 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_READ_UNCOMMITTED
)
3108 {s
+= langDBINF_READ_UNCOMMITTED
; comma
++;}
3109 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_READ_COMMITTED
)
3110 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_READ_COMMITTED
;}
3111 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_REPEATABLE_READ
)
3112 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_REPEATABLE_READ
;}
3113 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_SERIALIZABLE
)
3114 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_SERIALIZABLE
;}
3116 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_VERSIONING
)
3117 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_VERSIONING
;}
3122 s
+= langDBINF_FETCH_DIRS
;
3123 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_NEXT
)
3124 {s
+= langDBINF_NEXT
; comma
++;}
3125 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_PRIOR
)
3126 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_PREV
;}
3127 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_FIRST
)
3128 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_FIRST
;}
3129 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_LAST
)
3130 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_LAST
;}
3131 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_ABSOLUTE
)
3132 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_ABSOLUTE
;}
3133 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_RELATIVE
)
3134 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_RELATIVE
;}
3136 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_RESUME
)
3137 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_RESUME
;}
3139 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_BOOKMARK
)
3140 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_BOOKMARK
;}
3144 s
+= langDBINF_LOCK_TYPES
;
3145 if (pDb
->dbInf
.lockTypes
& SQL_LCK_NO_CHANGE
)
3146 {s
+= langDBINF_NO_CHANGE
; comma
++;}
3147 if (pDb
->dbInf
.lockTypes
& SQL_LCK_EXCLUSIVE
)
3148 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_EXCLUSIVE
;}
3149 if (pDb
->dbInf
.lockTypes
& SQL_LCK_UNLOCK
)
3150 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_UNLOCK
;}
3154 s
+= langDBINF_POS_OPERS
;
3155 if (pDb
->dbInf
.posOperations
& SQL_POS_POSITION
)
3156 {s
+= langDBINF_POSITION
; comma
++;}
3157 if (pDb
->dbInf
.posOperations
& SQL_POS_REFRESH
)
3158 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_REFRESH
;}
3159 if (pDb
->dbInf
.posOperations
& SQL_POS_UPDATE
)
3160 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_UPD
;}
3161 if (pDb
->dbInf
.posOperations
& SQL_POS_DELETE
)
3162 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_DEL
;}
3163 if (pDb
->dbInf
.posOperations
& SQL_POS_ADD
)
3164 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_ADD
;}
3168 s
+= langDBINF_POS_STMTS
;
3169 if (pDb
->dbInf
.posStmts
& SQL_PS_POSITIONED_DELETE
)
3170 {s
+= langDBINF_POS_DEL
; comma
++;}
3171 if (pDb
->dbInf
.posStmts
& SQL_PS_POSITIONED_UPDATE
)
3172 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_POS_UPD
;}
3173 if (pDb
->dbInf
.posStmts
& SQL_PS_SELECT_FOR_UPDATE
)
3174 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_SELECT_FOR_UPD
;}
3178 s
+= langDBINF_SCROLL_CONCURR
;
3179 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_READ_ONLY
)
3180 {s
+= langDBINF_READ_ONLY
; comma
++;}
3181 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_LOCK
)
3182 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_LOCK
;}
3183 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_OPT_ROWVER
)
3184 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_OPT_ROWVER
;}
3185 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_OPT_VALUES
)
3186 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_OPT_VALUES
;}
3190 s
+= langDBINF_SCROLL_OPTS
;
3191 if (pDb
->dbInf
.scrollOptions
& SQL_SO_FORWARD_ONLY
)
3192 {s
+= langDBINF_FWD_ONLY
; comma
++;}
3193 if (pDb
->dbInf
.scrollOptions
& SQL_SO_STATIC
)
3194 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_STATIC
;}
3195 if (pDb
->dbInf
.scrollOptions
& SQL_SO_KEYSET_DRIVEN
)
3196 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_KEYSET_DRIVEN
;}
3197 if (pDb
->dbInf
.scrollOptions
& SQL_SO_DYNAMIC
)
3198 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_DYNAMIC
;}
3199 if (pDb
->dbInf
.scrollOptions
& SQL_SO_MIXED
)
3200 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_MIXED
;}
3204 s
+= langDBINF_STATIC_SENS
;
3205 if (pDb
->dbInf
.staticSensitivity
& SQL_SS_ADDITIONS
)
3206 {s
+= langDBINF_ADDITIONS
; comma
++;}
3207 if (pDb
->dbInf
.staticSensitivity
& SQL_SS_DELETIONS
)
3208 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_DELETIONS
;}
3209 if (pDb
->dbInf
.staticSensitivity
& SQL_SS_UPDATES
)
3210 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_UPDATES
;}
3213 #pragma message enable incboodep
3217 s
+= langDBINF_TXN_CAPABLE
;
3218 switch(pDb
->dbInf
.txnCapable
)
3220 case SQL_TC_NONE
: s
+= langNO
; break;
3221 case SQL_TC_DML
: s
+= langDBINF_DML_ONLY
; break;
3222 case SQL_TC_DDL_COMMIT
: s
+= langDBINF_DDL_COMMIT
; break;
3223 case SQL_TC_DDL_IGNORE
: s
+= langDBINF_DDL_IGNORE
; break;
3224 case SQL_TC_ALL
: s
+= langDBINF_DDL_AND_DML
; break;
3228 t
.sprintf(wxT("%s%lu\n"), langDBINF_LOGIN_TIMEOUT
, pDb
->dbInf
.loginTimeout
);
3231 // Oracle specific information
3232 if (pDb
->Dbms() == dbmsORACLE
)
3235 s
+= langDBINF_ORACLE_BANNER
;
3238 // Oracle cache hit ratio
3241 pDb
->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'db block gets'"));
3243 if (pDb
->GetData(1, SQL_C_ULONG
, &dbBlockGets
, 0, &cb
))
3245 t
.sprintf(wxT("%s: %lu\n"), langDBINF_DB_BLOCK_GETS
, dbBlockGets
);
3249 ULONG consistentGets
;
3250 pDb
->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'consistent gets'"));
3252 if (pDb
->GetData(1, SQL_C_ULONG
, &consistentGets
, 0, &cb
))
3254 t
.sprintf(wxT("%s: %lu\n"), langDBINF_CONSISTENT_GETS
, consistentGets
);
3259 pDb
->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'physical reads'"));
3261 if (pDb
->GetData(1, SQL_C_ULONG
, &physReads
, 0, &cb
))
3263 t
.sprintf(wxT("%s: %lu\n"), langDBINF_PHYSICAL_READS
, physReads
);
3267 ULONG hitRatio
= (ULONG
)((1.00 - ((float)physReads
/ (float)(dbBlockGets
+ consistentGets
))) * 100.00);
3268 t
.sprintf(wxT("*** %s: %lu%%\n"), langDBINF_CACHE_HIT_RATIO
, hitRatio
);
3271 // Tablespace information
3273 s
+= langDBINF_TABLESPACE_IO
;
3276 char tablespaceName
[256+1];
3277 pDb
->ExecSql(wxT("SELECT NAME,PHYRDS,PHYWRTS FROM V$DATAFILE, V$FILESTAT WHERE V$DATAFILE.FILE# = V$FILESTAT.FILE#"));
3278 while (pDb
->GetNext())
3280 pDb
->GetData(1, SQL_C_WXCHAR
, tablespaceName
, 256, &cb
);
3281 pDb
->GetData(2, SQL_C_ULONG
, &physReads
, 0, &cb
);
3282 pDb
->GetData(3, SQL_C_ULONG
, &physWrites
, 0, &cb
);
3283 t
.sprintf(wxT("%s\n\t%s: %lu\t%s: %lu\n"), tablespaceName
,
3284 langDBINF_PHYSICAL_READS
, physReads
, langDBINF_PHYSICAL_WRITES
, physWrites
);
3291 s
+= wxT("End of Diagnostics\n");
3294 } // DisplayDbDiagnostics()
3298 BEGIN_EVENT_TABLE(DbGridFrame
, wxFrame
)
3299 // EVT_CLOSE(DbGridFrame::OnCloseWindow)
3303 DbGridFrame::DbGridFrame(wxWindow
*parent
)
3304 : wxFrame (parent
, wxID_ANY
, wxT("Database Table"),
3305 wxDefaultPosition
, wxSize(400, 325))
3307 initialized
= false;
3311 void DbGridFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
3317 bool DbGridFrame::Initialize()
3319 wxGrid
*grid
= new wxGrid(this, wxID_ANY
, wxDefaultPosition
);
3321 grid
->RegisterDataType(wxGRID_VALUE_DATETIME
,
3322 new wxGridCellDateTimeRenderer(wxT("%d %b %Y")),
3323 new wxGridCellTextEditor
);
3325 grid
->RegisterDataType(wxGRID_VALUE_CHOICEINT
,
3326 new wxGridCellEnumRenderer
,
3327 new wxGridCellEnumEditor
);
3329 wxString
NativeLangChoice( wxString::Format(wxT("%s:%s,%s,%s,%s,%s"),wxGRID_VALUE_CHOICEINT
,
3337 // Columns must match the sequence specified in SetColDef() calls
3338 wxDbGridColInfo
* cols
=
3339 new wxDbGridColInfo( 0,wxGRID_VALUE_STRING
,wxT("Name"),
3340 new wxDbGridColInfo( 1,wxGRID_VALUE_STRING
,wxT("Address 1"),
3341 new wxDbGridColInfo( 2,wxGRID_VALUE_STRING
,wxT("Address 2"),
3342 new wxDbGridColInfo( 3,wxGRID_VALUE_STRING
,wxT("City"),
3343 new wxDbGridColInfo( 4,wxGRID_VALUE_STRING
,wxT("State"),
3344 new wxDbGridColInfo( 5,wxGRID_VALUE_STRING
,wxT("PostCode"),
3345 new wxDbGridColInfo( 6,wxGRID_VALUE_STRING
,wxT("Country"),
3346 new wxDbGridColInfo( 7,wxGRID_VALUE_DBAUTO
,wxT("Join Date"),
3347 new wxDbGridColInfo( 8,wxGRID_VALUE_BOOL
, wxT("Developer"),
3348 new wxDbGridColInfo( 9,wxGRID_VALUE_NUMBER
,wxT("Contributions"),
3349 new wxDbGridColInfo(10,wxGRID_VALUE_NUMBER
,wxT("Lines Of Code"),
3351 new wxDbGridColInfo(11,NativeLangChoice
, wxT("Native Language"),NULL
))))))))))));
3353 new wxDbGridColInfo(11,wxGRID_VALUE_NUMBER
,wxT("Native Language"),NULL
))))))))))));
3356 Ccontact
*Contact
= new Ccontact();
3357 //wxGetApp().Contact
3361 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"), wxT("Error..."), wxOK
| wxICON_EXCLAMATION
);
3365 if (!Contact
->Open())
3367 if (Contact
->GetDb()->TableExists(CONTACT_TABLE_NAME
, Contact
->GetDb()->GetUsername(),
3368 wxGetApp().DbConnectInf
->GetDefaultDir()))
3371 tStr
.Printf(wxT("Unable to open the table '%s'.\n\n"),CONTACT_TABLE_NAME
.c_str());
3372 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
3373 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
3379 // Execute the following query using the cursor designated
3380 // for full table query
3381 Contact
->SetRowMode(wxDbTable::WX_ROW_MODE_QUERY
);
3383 if (!Contact
->Query())
3386 tStr
= wxT("ODBC error during Query()\n\n");
3387 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
3388 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
3392 // No data has been read in from the database yet, so
3393 // we need to initialize the data members to valid values
3394 // so Fit() can correctly size the grid
3395 Contact
->Initialize();
3397 wxDbGridTableBase
* db
= new wxDbGridTableBase(Contact
, cols
, wxUSE_QUERY
, true);
3401 grid
->SetTable(db
,true);
3402 grid
->SetMargins(0, 0);
3405 wxSize size
= grid
->GetSize();
3408 SetClientSize(size
);
3411 } // DbGridFrame::Initialize()
3413 #endif // #if wxUSE_GRID
3416 TEST CODE FOR TESTING THE wxDbCreateDataSource() FUNCTION
3419 result = wxDbCreateDataSource(wxT("Microsoft Access Driver (*.mdb)"), wxT("GLT-TEST2"), wxT("GLT-Descrip"), false, wxEmptyString, this);
3422 // check for errors caused by ConfigDSN based functions
3425 wxChar errMsg[500+1];
3426 errMsg[0] = wxT('\0');
3428 SQLInstallerError(1, &retcode, errMsg, 500, &cb);
3430 wxMessageBox(wxT("FAILED creating data source"), wxT("FAILED"));
3433 wxMessageBox(wxT("SUCCEEDED creating data source"), wxT("SUCCESS"));