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()
641 // Create the main frame window
642 DemoFrame
= new DatabaseDemoFrame(NULL
, wxT("wxWidgets Database Demo"), wxPoint(50, 50), wxSize(537, 530));
645 DemoFrame
->SetIcon(wxICON(db
));
648 wxMenu
*file_menu
= new wxMenu
;
649 file_menu
->Append(FILE_CREATE_ID
, wxT("&Create CONTACT table"));
650 file_menu
->Append(FILE_RECREATE_TABLE
, wxT("&Recreate CONTACT table"));
651 file_menu
->Append(FILE_RECREATE_INDEXES
, wxT("&Recreate CONTACT indexes"));
653 file_menu
->Append(FILE_DBGRID_TABLE
, wxT("&Open DB Grid example"));
655 file_menu
->Append(FILE_EXIT
, wxT("E&xit"));
657 wxMenu
*edit_menu
= new wxMenu
;
658 edit_menu
->Append(EDIT_PARAMETERS
, wxT("&Parameters..."));
660 wxMenu
*help_menu
= new wxMenu
;
661 help_menu
->Append(HELP_ABOUT
, wxT("&About"));
663 wxMenuBar
*menu_bar
= new wxMenuBar
;
664 menu_bar
->Append(file_menu
, wxT("&File"));
665 menu_bar
->Append(edit_menu
, wxT("&Edit"));
666 menu_bar
->Append(help_menu
, wxT("&Help"));
667 DemoFrame
->SetMenuBar(menu_bar
);
669 params
.ODBCSource
[0] = 0;
670 params
.UserName
[0] = 0;
671 params
.Password
[0] = 0;
672 params
.DirPath
[0] = 0;
674 #ifdef wxODBC_BLOB_SUPPORT
675 wxInitAllImageHandlers();
676 wxImage::InitStandardHandlers();
677 wxBitmap::InitStandardHandlers();
681 DemoFrame
->Show(true);
683 // Passing NULL for the SQL environment handle causes
684 // the wxDbConnectInf constructor to obtain a handle
687 // WARNING: Be certain that you do not free this handle
688 // directly with SQLFreeEnv(). Use either the
689 // method ::FreeHenv() or delete the DbConnectInf.
690 DbConnectInf
= new wxDbConnectInf(NULL
, params
.ODBCSource
, params
.UserName
,
691 params
.Password
, params
.DirPath
);
693 if (!DbConnectInf
|| !DbConnectInf
->GetHenv())
695 wxMessageBox(wxT("Unable to define data source connection info."), wxT("DB CONNECTION ERROR..."),wxOK
| wxICON_EXCLAMATION
);
696 wxDELETE(DbConnectInf
);
699 if (!ReadParamFile(params
))
700 DemoFrame
->BuildParameterDialog(NULL
);
702 if (!wxStrlen(params
.ODBCSource
))
704 wxDELETE(DbConnectInf
);
708 DbConnectInf
->SetDsn(params
.ODBCSource
);
709 DbConnectInf
->SetUserID(params
.UserName
);
710 DbConnectInf
->SetPassword(params
.Password
);
711 DbConnectInf
->SetDefaultDir(params
.DirPath
);
713 READONLY_DB
= wxDbGetConnection(DbConnectInf
);
714 if (READONLY_DB
== 0)
716 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
);
717 DemoFrame
->BuildParameterDialog(NULL
);
718 wxDELETE(DbConnectInf
);
719 wxMessageBox(wxT("Now exiting program.\n\nRestart program to try any new settings."),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
723 DemoFrame
->BuildEditorDialog();
726 DemoFrame
->Refresh();
729 } // DatabaseDemoApp::OnInit()
733 * Remove CR or CR/LF from a character string.
735 wxChar
* wxRemoveLineTerminator(wxChar
* aString
)
737 int len
= wxStrlen(aString
);
738 while (len
> 0 && (aString
[len
-1] == wxT('\r') || aString
[len
-1] == wxT('\n'))) {
739 aString
[len
-1] = wxT('\0');
746 bool DatabaseDemoApp::ReadParamFile(Cparameters
¶ms
)
749 if ((paramFile
= wxFopen(PARAM_FILENAME
, wxT("r"))) == NULL
)
752 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());
753 wxMessageBox(tStr
,wxT("File I/O Error..."),wxOK
| wxICON_EXCLAMATION
);
758 wxChar buffer
[1000+1];
759 wxFgets(buffer
, sizeof(params
.ODBCSource
), paramFile
);
760 wxRemoveLineTerminator(buffer
);
761 wxStrcpy(params
.ODBCSource
,buffer
);
763 wxFgets(buffer
, sizeof(params
.UserName
), paramFile
);
764 wxRemoveLineTerminator(buffer
);
765 wxStrcpy(params
.UserName
,buffer
);
767 wxFgets(buffer
, sizeof(params
.Password
), paramFile
);
768 wxRemoveLineTerminator(buffer
);
769 wxStrcpy(params
.Password
,buffer
);
771 wxFgets(buffer
, sizeof(params
.DirPath
), paramFile
);
772 wxRemoveLineTerminator(buffer
);
773 wxStrcpy(params
.DirPath
,buffer
);
778 } // DatabaseDemoApp::ReadParamFile()
781 bool DatabaseDemoApp::WriteParamFile(Cparameters
&WXUNUSED(params
))
784 if ((paramFile
= wxFopen(PARAM_FILENAME
, wxT("wt"))) == NULL
)
787 tStr
.Printf(wxT("Unable to write/overwrite '%s'."),PARAM_FILENAME
.c_str());
788 wxMessageBox(tStr
,wxT("File I/O Error..."),wxOK
| wxICON_EXCLAMATION
);
792 wxFputs(wxGetApp().params
.ODBCSource
, paramFile
);
793 wxFputc(wxT('\n'), paramFile
);
794 wxFputs(wxGetApp().params
.UserName
, paramFile
);
795 wxFputc(wxT('\n'), paramFile
);
796 wxFputs(wxGetApp().params
.Password
, paramFile
);
797 wxFputc(wxT('\n'), paramFile
);
798 wxFputs(wxGetApp().params
.DirPath
, paramFile
);
799 wxFputc(wxT('\n'), paramFile
);
803 } // DatabaseDemoApp::WriteParamFile()
806 void DatabaseDemoApp::CreateDataTable(bool recreate
)
810 Ok
= (wxMessageBox(wxT("Any data currently residing in the table will be erased.\n\nAre you sure?"),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
819 Contact
->GetDb()->RollbackTrans(); // Make sure the current cursor is in a known/stable state
821 if (!Contact
->CreateTable(recreate
))
825 tStr
= wxT("Error creating CONTACTS table.\nTable was not created.\n\n");
826 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),Contact
->GetDb(),__TFILE__
,__LINE__
),
827 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
833 if (!Contact
->CreateIndexes(recreate
))
837 tStr
= wxT("Error creating CONTACTS indexes.\nIndexes will be unavailable.\n\n");
838 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),Contact
->GetDb(),__TFILE__
,__LINE__
),
839 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
848 wxMessageBox(wxT("Table and index(es) were successfully created."),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
849 } // DatabaseDemoApp::CreateDataTable()
852 BEGIN_EVENT_TABLE(DatabaseDemoFrame
, wxFrame
)
853 EVT_MENU(FILE_CREATE_ID
, DatabaseDemoFrame::OnCreate
)
854 EVT_MENU(FILE_RECREATE_TABLE
, DatabaseDemoFrame::OnRecreateTable
)
855 EVT_MENU(FILE_RECREATE_INDEXES
, DatabaseDemoFrame::OnRecreateIndexes
)
857 EVT_MENU(FILE_DBGRID_TABLE
, DatabaseDemoFrame::OnDbGridTable
)
859 EVT_MENU(FILE_EXIT
, DatabaseDemoFrame::OnExit
)
860 EVT_MENU(EDIT_PARAMETERS
, DatabaseDemoFrame::OnEditParameters
)
861 EVT_MENU(HELP_ABOUT
, DatabaseDemoFrame::OnAbout
)
862 EVT_CLOSE(DatabaseDemoFrame::OnCloseWindow
)
866 // DatabaseDemoFrame constructor
867 DatabaseDemoFrame::DatabaseDemoFrame(wxFrame
*frame
, const wxString
& title
,
868 const wxPoint
& pos
, const wxSize
& size
):
869 wxFrame(frame
, wxID_ANY
, title
, pos
, size
)
871 // Put any code in necessary for initializing the main frame here
876 delete wxLog::SetActiveTarget(new wxLogStderr
);
879 } // DatabaseDemoFrame constructor
881 DatabaseDemoFrame::~DatabaseDemoFrame()
884 delete wxLog::SetActiveTarget(NULL
);
886 } // DatabaseDemoFrame destructor
889 void DatabaseDemoFrame::OnCreate(wxCommandEvent
& WXUNUSED(event
))
891 wxGetApp().CreateDataTable(false);
892 } // DatabaseDemoFrame::OnCreate()
895 void DatabaseDemoFrame::OnRecreateTable(wxCommandEvent
& WXUNUSED(event
))
897 wxGetApp().CreateDataTable(true);
898 } // DatabaseDemoFrame::OnRecreate()
901 void DatabaseDemoFrame::OnRecreateIndexes(wxCommandEvent
& WXUNUSED(event
))
903 wxGetApp().Contact
->GetDb()->RollbackTrans(); // Make sure the current cursor is in a known/stable state
905 if (!wxGetApp().Contact
->CreateIndexes(true))
910 tStr
= wxT("Error creating CONTACTS indexes.\nNew indexes will be unavailable.\n\n");
911 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
912 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
916 wxMessageBox(wxT("Index(es) were successfully recreated."),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
918 } // DatabaseDemoFrame::OnRecreateIndexes()
922 void DatabaseDemoFrame::OnDbGridTable(wxCommandEvent
& WXUNUSED(event
))
924 DbGridFrame
*frame
= new DbGridFrame(this);
925 if (frame
->Initialize())
932 void DatabaseDemoFrame::OnExit(wxCommandEvent
& WXUNUSED(event
))
935 } // DatabaseDemoFrame::OnExit()
938 void DatabaseDemoFrame::OnEditParameters(wxCommandEvent
& WXUNUSED(event
))
940 if ((pEditorDlg
->mode
!= mCreate
) && (pEditorDlg
->mode
!= mEdit
))
941 BuildParameterDialog(this);
943 wxMessageBox(wxT("Cannot change database parameters while creating or editing a record"),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
944 } // DatabaseDemoFrame::OnEditParameters()
947 void DatabaseDemoFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
949 wxMessageBox(wxT("wxWidgets sample program for database classes\n\nContributed on 27 July 1998"),wxT("About..."),wxOK
| wxICON_INFORMATION
);
950 } // DatabaseDemoFrame::OnAbout()
953 // Put any additional checking necessary to make certain it is alright
954 // to close the program here that is not done elsewhere
955 void DatabaseDemoFrame::OnCloseWindow(wxCloseEvent
& event
)
958 if (pEditorDlg
&& pEditorDlg
->Close())
969 wxDELETE(wxGetApp().Contact
);
971 // This function will close all the connections to the database that have been
972 // previously cached.
973 wxDbCloseConnections();
975 // Deletion of the wxDbConnectInf instance must be the LAST thing done that
976 // has anything to do with the database. Deleting this before disconnecting,
977 // freeing/closing connections, etc will result in a crash!
978 wxDELETE(wxGetApp().DbConnectInf
);
982 } // DatabaseDemoFrame::OnCloseWindow()
985 void DatabaseDemoFrame::BuildEditorDialog()
988 pEditorDlg
= new CeditorDlg(this);
991 pEditorDlg
->Initialize();
992 if (!pEditorDlg
->initialized
)
996 wxMessageBox(wxT("Unable to initialize the editor dialog for some reason"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
1002 wxMessageBox(wxT("Unable to create the editor dialog for some reason"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
1005 } // DatabaseDemoFrame::BuildEditorDialog()
1008 void DatabaseDemoFrame::BuildParameterDialog(wxWindow
*parent
)
1010 pParamDlg
= new CparameterDlg(parent
);
1013 wxMessageBox(wxT("Unable to create the parameter dialog for some reason"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
1014 } // DatabaseDemoFrame::BuildParameterDialog()
1018 * Constructor note: If no wxDb object is passed in, a new connection to the database
1019 * is created for this instance of Ccontact. This can be a slow process depending
1020 * on the database engine being used, and some database engines have a limit on the
1021 * number of connections (either hard limits, or license restricted) so care should
1022 * be used to use as few connections as is necessary.
1024 * IMPORTANT: Objects which share a wxDb pointer are ALL acted upon whenever a member
1025 * function of pDb is called (i.e. CommitTrans() or RollbackTrans(), so if modifying
1026 * or creating a table objects which use the same pDb, know that all the objects
1027 * will be committed or rolled back when any of the objects has this function call made.
1029 Ccontact::Ccontact (wxDb
*pwxDb
) : wxDbTable(pwxDb
? pwxDb
: wxDbGetConnection(wxGetApp().DbConnectInf
),
1030 CONTACT_TABLE_NAME
, CONTACT_NO_COLS
, (const wxString
&)wxEmptyString
,
1031 !wxDB_QUERY_ONLY
, wxGetApp().DbConnectInf
->GetDefaultDir())
1033 // This is used to represent whether the database connection should be released
1034 // when this instance of the object is deleted. If using the same connection
1035 // for multiple instance of database objects, then the connection should only be
1036 // released when the last database instance using the connection is deleted
1037 freeDbConn
= !pwxDb
;
1040 GetDb()->SetSqlLogging(sqlLogON
);
1044 } // Ccontact Constructor
1047 void Ccontact::Initialize()
1056 JoinDate
.year
= 1980;
1060 JoinDate
.minute
= 0;
1061 JoinDate
.second
= 0;
1062 JoinDate
.fraction
= 0;
1063 NativeLanguage
= langENGLISH
;
1064 IsDeveloper
= false;
1068 memset(Picture
, 0, MAX_PICTURE_SIZE
);
1069 } // Ccontact::Initialize
1072 Ccontact::~Ccontact()
1076 if (!wxDbFreeConnection(GetDb()))
1079 tStr
= wxT("Unable to Free the Ccontact data table handle\n\n");
1081 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1082 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1085 } // Ccontract destructor
1089 * Handles setting up all the connections for the interface from the wxDbTable
1090 * functions to interface to the data structure used to store records in
1091 * memory, and for all the column definitions that define the table structure
1093 void Ccontact::SetupColumns()
1095 // NOTE: Columns now are 8 character names, as that is all dBase can support. Longer
1096 // names can be used for other database engines
1097 SetColDefs ( 0,wxT("NAME"), DB_DATA_TYPE_VARCHAR
, Name
, SQL_C_WXCHAR
, sizeof(Name
), true, true); // Primary index
1098 SetColDefs ( 1,wxT("ADDRESS1"), DB_DATA_TYPE_VARCHAR
, Addr1
, SQL_C_WXCHAR
, sizeof(Addr1
), false,true);
1099 SetColDefs ( 2,wxT("ADDRESS2"), DB_DATA_TYPE_VARCHAR
, Addr2
, SQL_C_WXCHAR
, sizeof(Addr2
), false,true);
1100 SetColDefs ( 3,wxT("CITY"), DB_DATA_TYPE_VARCHAR
, City
, SQL_C_WXCHAR
, sizeof(City
), false,true);
1101 SetColDefs ( 4,wxT("STATE"), DB_DATA_TYPE_VARCHAR
, State
, SQL_C_WXCHAR
, sizeof(State
), false,true);
1102 SetColDefs ( 5,wxT("POSTCODE"), DB_DATA_TYPE_VARCHAR
, PostalCode
, SQL_C_WXCHAR
, sizeof(PostalCode
), false,true);
1103 SetColDefs ( 6,wxT("COUNTRY"), DB_DATA_TYPE_VARCHAR
, Country
, SQL_C_WXCHAR
, sizeof(Country
), false,true);
1104 SetColDefs ( 7,wxT("JOINDATE"), DB_DATA_TYPE_DATE
, &JoinDate
, SQL_C_TIMESTAMP
, sizeof(JoinDate
), false,true);
1105 SetColDefs ( 8,wxT("IS_DEV"), DB_DATA_TYPE_INTEGER
, &IsDeveloper
, SQL_C_BOOLEAN(IsDeveloper
), sizeof(IsDeveloper
), false,true);
1106 SetColDefs ( 9,wxT("CONTRIBS"), DB_DATA_TYPE_INTEGER
, &Contributions
, SQL_C_UTINYINT
, sizeof(Contributions
), false,true);
1107 SetColDefs (10,wxT("LINE_CNT"), DB_DATA_TYPE_INTEGER
, &LinesOfCode
, SQL_C_ULONG
, sizeof(LinesOfCode
), false,true);
1108 SetColDefs (11,wxT("LANGUAGE"), DB_DATA_TYPE_INTEGER
, &NativeLanguage
, SQL_C_ENUM
, sizeof(NativeLanguage
), false,true);
1109 #ifdef wxODBC_BLOB_SUPPORT
1110 SetColDefs (12,wxT("PICSIZE"), DB_DATA_TYPE_INTEGER
, &BlobSize
, SQL_C_ULONG
, sizeof(BlobSize
), false,true);
1111 SetColDefs (13,wxT("PICTURE"), DB_DATA_TYPE_BLOB
, Picture
, SQL_C_BINARY
, sizeof(Picture
), false,true);
1113 } // Ccontact::SetupColumns
1116 bool Ccontact::CreateIndexes(bool recreate
)
1118 // This index could easily be accomplished with an "orderBy" clause,
1119 // but is done to show how to construct a non-primary index.
1121 wxDbIdxDef idxDef
[2];
1123 wxStrcpy(idxDef
[0].ColName
, wxT("IS_DEV"));
1124 idxDef
[0].Ascending
= true;
1126 wxStrcpy(idxDef
[1].ColName
, wxT("NAME"));
1127 idxDef
[1].Ascending
= true;
1129 indexName
= GetTableName();
1130 indexName
+= wxT("_IDX1");
1132 return CreateIndex(indexName
.c_str(), true, 2, idxDef
, recreate
);
1134 } // Ccontact::CreateIndexes()
1138 * Having a function to do a query on the primary key (and possibly others) is
1139 * very efficient and tighter coding so that it is available where ever the object
1140 * is. Great for use with multiple tables when not using views or outer joins
1142 bool Ccontact::FetchByName(const wxString
&name
)
1144 whereStr
.Printf(wxT("NAME = '%s'"),name
.c_str());
1145 SetWhereClause(whereStr
.c_str());
1146 SetOrderByClause(wxEmptyString
);
1154 } // Ccontact::FetchByName()
1159 * ************* DIALOGS ***************
1164 /* CeditorDlg constructor
1166 * Creates the dialog used for creating/editing/deleting/copying a Ccontact object.
1167 * This dialog actually is drawn in the main frame of the program
1169 * An instance of Ccontact is created - "Contact" - which is used to hold the Ccontact
1170 * object that is currently being worked with.
1173 BEGIN_EVENT_TABLE(CeditorDlg
, wxPanel
)
1174 EVT_BUTTON(wxID_ANY
, CeditorDlg::OnButton
)
1175 EVT_CLOSE(CeditorDlg::OnCloseWindow
)
1178 CeditorDlg::CeditorDlg(wxWindow
*parent
) : wxPanel (parent
, 0, 0, 537, 530)
1180 // Since the ::OnCommand() function is overridden, this prevents the widget
1181 // detection in ::OnCommand() until all widgets have been initialized to prevent
1182 // uninitialized pointers from crashing the program
1183 widgetPtrsSet
= false;
1185 initialized
= false;
1190 } // CeditorDlg constructor
1193 void CeditorDlg::OnCloseWindow(wxCloseEvent
& event
)
1196 if ((mode
!= mCreate
) && (mode
!= mEdit
))
1202 wxMessageBox(wxT("Must finish processing the current record being created/modified before exiting"),wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
1205 } // CeditorDlg::OnCloseWindow()
1208 void CeditorDlg::OnButton(wxCommandEvent
&event
)
1210 wxWindow
*win
= (wxWindow
*) event
.GetEventObject();
1211 OnCommand( *win
, event
);
1212 } // CeditorDlg::OnButton()
1215 void CeditorDlg::OnCommand(wxWindow
& win
, wxCommandEvent
& WXUNUSED(event
))
1217 wxString widgetName
;
1219 widgetName
= win
.GetName();
1224 if (widgetName
== pCreateBtn
->GetName())
1226 wxGetApp().Contact
->Initialize();
1229 pNameTxt
->SetValue(wxEmptyString
);
1230 pNameTxt
->SetFocus();
1234 if (widgetName
== pEditBtn
->GetName())
1236 saveName
= wxGetApp().Contact
->Name
;
1238 pNameTxt
->SetFocus();
1242 if (widgetName
== pCopyBtn
->GetName())
1245 pNameTxt
->SetValue(wxEmptyString
);
1246 pNameTxt
->SetFocus();
1250 if (widgetName
== pDeleteBtn
->GetName())
1252 bool Ok
= (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
1257 if (Ok
&& wxGetApp().Contact
->Delete())
1259 // NOTE: Deletions are not finalized until a CommitTrans() is performed.
1260 // If the commit were not performed, the program will continue to
1261 // show the table contents as if they were deleted until this instance
1262 // of Ccontact is deleted. If the Commit wasn't performed, the
1263 // database will automatically Rollback the changes when the database
1264 // connection is terminated
1265 wxGetApp().Contact
->GetDb()->CommitTrans();
1267 // Try to get the row that followed the just deleted row in the orderBy sequence
1270 // There was now row (in sequence) after the just deleted row, so get the
1271 // row which preceded the just deleted row
1274 // There are now no rows remaining, so clear the dialog widgets
1275 wxGetApp().Contact
->Initialize();
1279 SetMode(mode
); // force reset of button enable/disable
1283 wxGetApp().Contact
->GetDb()->RollbackTrans();
1289 if (widgetName
== pSaveBtn
->GetName())
1295 if (widgetName
== pCancelBtn
->GetName())
1297 bool Ok
= (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
1302 if (saveName
.empty())
1304 wxGetApp().Contact
->Initialize();
1311 // Requery previous record
1312 if (wxGetApp().Contact
->FetchByName(saveName
))
1320 // Previous record not available, retrieve first record in table
1321 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1322 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1324 wxGetApp().Contact
->whereStr
= wxT("NAME = (SELECT MIN(NAME) FROM ");
1325 wxGetApp().Contact
->whereStr
+= wxGetApp().Contact
->GetTableName();
1326 wxGetApp().Contact
->whereStr
+= wxT(")");
1327 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
.c_str());
1330 wxGetApp().Contact
->SetWhereClause(wxEmptyString
);
1332 if (!wxGetApp().Contact
->Query())
1335 tStr
= wxT("ODBC error during Query()\n\n");
1336 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1337 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1342 if (wxGetApp().Contact
->GetNext()) // Successfully read first record
1348 // No contacts are available, clear dialog
1349 wxGetApp().Contact
->Initialize();
1355 if (widgetName
== pPrevBtn
->GetName())
1362 if (widgetName
== pNextBtn
->GetName())
1369 if (widgetName
== pQueryBtn
->GetName())
1371 // Display the query dialog box
1372 wxChar qryWhere
[DB_MAX_WHERE_CLAUSE_LEN
+1];
1373 wxStrcpy(qryWhere
, (const wxChar
*) wxGetApp().Contact
->qryWhereStr
);
1374 wxChar
*tblName
[] = {(wxChar
*)CONTACT_TABLE_NAME
.c_str(), 0};
1375 new CqueryDlg(GetParent(), wxGetApp().Contact
->GetDb(), tblName
, qryWhere
);
1377 // Query the first record in the new record set and
1378 // display it, if the query string has changed.
1379 if (wxStrcmp(qryWhere
, (const wxChar
*) wxGetApp().Contact
->qryWhereStr
))
1381 wxGetApp().Contact
->whereStr
.Empty();
1382 wxGetApp().Contact
->SetOrderByClause(wxT("NAME"));
1384 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1385 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1387 wxGetApp().Contact
->whereStr
= wxT("NAME = (SELECT MIN(NAME) FROM ");
1388 wxGetApp().Contact
->whereStr
+= CONTACT_TABLE_NAME
;
1391 // Append the query where string (if there is one)
1392 wxGetApp().Contact
->qryWhereStr
= qryWhere
;
1393 if (wxStrlen(qryWhere
))
1395 wxGetApp().Contact
->whereStr
+= wxT(" WHERE ");
1396 wxGetApp().Contact
->whereStr
+= wxGetApp().Contact
->qryWhereStr
;
1398 // Close the expression with a right paren
1399 wxGetApp().Contact
->whereStr
+= wxT(")");
1400 // Requery the table
1401 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
.c_str());
1402 if (!wxGetApp().Contact
->Query())
1405 tStr
= wxT("ODBC error during Query()\n\n");
1406 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1407 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1411 // Display the first record from the query set
1412 if (!wxGetApp().Contact
->GetNext())
1413 wxGetApp().Contact
->Initialize();
1417 // Enable/Disable the reset button
1418 pResetBtn
->Enable(!wxGetApp().Contact
->qryWhereStr
.empty());
1424 if (widgetName
== pResetBtn
->GetName())
1426 // Clear the additional where criteria established by the query feature
1427 wxGetApp().Contact
->qryWhereStr
= wxEmptyString
;
1428 wxGetApp().Contact
->SetOrderByClause(wxT("NAME"));
1430 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1431 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1433 wxGetApp().Contact
->whereStr
= wxT("NAME = (SELECT MIN(NAME) FROM ");
1434 wxGetApp().Contact
->whereStr
+= CONTACT_TABLE_NAME
;
1435 wxGetApp().Contact
->whereStr
+= wxT(")");
1438 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
.c_str());
1439 if (!wxGetApp().Contact
->Query())
1442 tStr
= wxT("ODBC error during Query()\n\n");
1443 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1444 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1447 if (!wxGetApp().Contact
->GetNext())
1448 wxGetApp().Contact
->Initialize();
1450 pResetBtn
->Enable(false);
1456 if (widgetName
== pNameListBtn
->GetName())
1458 new ClookUpDlg(/* wxWindow *parent */ this,
1459 /* const wxString &windowTitle */ wxT("Select contact name"),
1460 /* const wxString &tableName */ CONTACT_TABLE_NAME
,
1461 /* const wxString &dispCol1 */ wxT("NAME"),
1462 /* const wxString &dispCol2 */ wxT("JOINDATE"),
1463 /* const wxString &where */ wxT(""),
1464 /* const wxString &orderBy */ wxT("NAME"),
1465 /* wxDb *pDb */ wxGetApp().READONLY_DB
,
1466 /* const wxString &defDir */ wxGetApp().DbConnectInf
->GetDefaultDir(),
1467 /* bool distinctValues*/ true,
1470 if (ListDB_Selection
&& wxStrlen(ListDB_Selection
))
1472 wxString w
= wxT("NAME = '");
1473 w
+= ListDB_Selection
;
1481 if (widgetName
== pDataTypesBtn
->GetName())
1483 CheckSupportForAllDataTypes(wxGetApp().READONLY_DB
);
1484 wxMessageBox(wxT("Support datatypes was dumped to stdout."));
1486 } // Data types Button
1488 if (widgetName
== pDbDiagsBtn
->GetName())
1490 DisplayDbDiagnostics(wxGetApp().READONLY_DB
);
1491 wxMessageBox(wxT("Diagnostics info was dumped to stdout."));
1495 if (widgetName
== pCatalogBtn
->GetName())
1497 if (wxGetApp().Contact
->GetDb()->Catalog(wxEmptyString
, wxT("catalog.txt")))
1498 wxMessageBox(wxT("The file 'catalog.txt' was created."));
1500 wxMessageBox(wxT("Creation of the file 'catalog.txt' failed."));
1504 #ifdef wxODBC_BLOB_SUPPORT
1505 if (widgetName
== pChooseImageBtn
->GetName())
1510 if (widgetName
== pShowImageBtn
->GetName())
1516 } // CeditorDlg::OnCommand()
1519 bool CeditorDlg::Initialize()
1521 // Create the data structure and a new database connection.
1522 // (As there is not a pDb being passed in the constructor, a new database
1523 // connection is created)
1524 wxGetApp().Contact
= new Ccontact();
1526 if (!wxGetApp().Contact
)
1528 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
1532 // Check if the table exists or not. If it doesn't, ask the user if they want to
1533 // create the table. Continue trying to create the table until it exists, or user aborts
1534 while (!wxGetApp().Contact
->GetDb()->TableExists(CONTACT_TABLE_NAME
,
1535 wxGetApp().DbConnectInf
->GetUserID(),
1536 wxGetApp().DbConnectInf
->GetDefaultDir()))
1539 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());
1540 bool createTable
= (wxMessageBox(tStr
.c_str(),wxT("Confirm"),wxYES_NO
|wxICON_QUESTION
) == wxYES
);
1548 wxGetApp().CreateDataTable(false);
1551 // Tables must be "opened" before anything other than creating/deleting table can be done
1552 if (!wxGetApp().Contact
->Open())
1554 // Table does exist, or there was some problem opening it. Currently this should
1555 // never fail, except in the case of the table not exisiting or the current
1556 // user has insufficent privileges to access the table
1558 // This code is experimenting with a new function that will hopefully be available
1559 // in the 2.4 release. This check will determine whether the open failing was due
1560 // to the table not existing, or the users privileges being insufficient to
1562 if (!wxGetApp().Contact
->GetDb()->TablePrivileges(CONTACT_TABLE_NAME
, wxT("SELECT"),
1563 wxGetApp().Contact
->GetDb()->GetUsername(),
1564 wxGetApp().Contact
->GetDb()->GetUsername(),
1565 wxGetApp().DbConnectInf
->GetDefaultDir()))
1568 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());
1570 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1571 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1575 if (!wxGetApp().Contact
->GetDb()->TableExists(CONTACT_TABLE_NAME
,
1576 wxGetApp().Contact
->GetDb()->GetUsername(),
1577 wxGetApp().DbConnectInf
->GetDefaultDir()))
1580 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());
1581 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1582 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1590 (void)new wxStaticBox(this, EDITOR_DIALOG_FN_GROUP
, wxEmptyString
, wxPoint(15, 1), wxSize(497, 69), 0, wxT("FunctionGrp"));
1591 (void)new wxStaticBox(this, EDITOR_DIALOG_SEARCH_GROUP
, wxEmptyString
, wxPoint(417, 1), wxSize(95, 242), 0, wxT("SearchGrp"));
1593 pCreateBtn
= new wxButton(this, EDITOR_DIALOG_CREATE
, wxT("&Create"), wxPoint( 25, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CreateBtn"));
1594 pEditBtn
= new wxButton(this, EDITOR_DIALOG_EDIT
, wxT("&Edit"), wxPoint(102, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("EditBtn"));
1595 pDeleteBtn
= new wxButton(this, EDITOR_DIALOG_DELETE
, wxT("&Delete"), wxPoint(179, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("DeleteBtn"));
1596 pCopyBtn
= new wxButton(this, EDITOR_DIALOG_COPY
, wxT("Cop&y"), wxPoint(256, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CopyBtn"));
1597 pSaveBtn
= new wxButton(this, EDITOR_DIALOG_SAVE
, wxT("&Save"), wxPoint(333, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("SaveBtn"));
1598 pCancelBtn
= new wxButton(this, EDITOR_DIALOG_CANCEL
, wxT("C&ancel"), wxPoint(430, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CancelBtn"));
1599 pPrevBtn
= new wxButton(this, EDITOR_DIALOG_PREV
, wxT("<< &Prev"), wxPoint(430, 81), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("PrevBtn"));
1600 pNextBtn
= new wxButton(this, EDITOR_DIALOG_NEXT
, wxT("&Next >>"), wxPoint(430, 121), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("NextBtn"));
1601 pQueryBtn
= new wxButton(this, EDITOR_DIALOG_QUERY
, wxT("&Query"), wxPoint(430, 161), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("QueryBtn"));
1602 pResetBtn
= new wxButton(this, EDITOR_DIALOG_RESET
, wxT("&Reset"), wxPoint(430, 200), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("ResetBtn"));
1603 pNameMsg
= new wxStaticText(this, EDITOR_DIALOG_NAME_MSG
, wxT("Name:"), wxPoint( 17, 80), wxDefaultSize
, 0, wxT("NameMsg"));
1604 pNameTxt
= new wxTextCtrl(this, EDITOR_DIALOG_NAME_TEXT
, wxEmptyString
, wxPoint( 17, 97), wxSize(308, 25), 0, wxDefaultValidator
, wxT("NameTxt"));
1605 pNameListBtn
= new wxButton(this, EDITOR_DIALOG_LOOKUP
, wxT("&Lookup"), wxPoint(333, 97), wxSize( 70, 24), 0, wxDefaultValidator
, wxT("LookupBtn"));
1606 pAddress1Msg
= new wxStaticText(this, EDITOR_DIALOG_ADDRESS1_MSG
, wxT("Address:"), wxPoint( 17, 130), wxDefaultSize
, 0, wxT("Address1Msg"));
1607 pAddress1Txt
= new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT
, wxEmptyString
, wxPoint( 17, 147), wxSize(308, 25), 0, wxDefaultValidator
, wxT("Address1Txt"));
1608 pAddress2Msg
= new wxStaticText(this, EDITOR_DIALOG_ADDRESS2_MSG
, wxT("Address:"), wxPoint( 17, 180), wxDefaultSize
, 0, wxT("Address2Msg"));
1609 pAddress2Txt
= new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT
, wxEmptyString
, wxPoint( 17, 197), wxSize(308, 25), 0, wxDefaultValidator
, wxT("Address2Txt"));
1610 pCityMsg
= new wxStaticText(this, EDITOR_DIALOG_CITY_MSG
, wxT("City:"), wxPoint( 17, 230), wxDefaultSize
, 0, wxT("CityMsg"));
1611 pCityTxt
= new wxTextCtrl(this, EDITOR_DIALOG_CITY_TEXT
, wxEmptyString
, wxPoint( 17, 247), wxSize(225, 25), 0, wxDefaultValidator
, wxT("CityTxt"));
1612 pStateMsg
= new wxStaticText(this, EDITOR_DIALOG_STATE_MSG
, wxT("State:"), wxPoint(250, 230), wxDefaultSize
, 0, wxT("StateMsg"));
1613 pStateTxt
= new wxTextCtrl(this, EDITOR_DIALOG_STATE_TEXT
, wxEmptyString
, wxPoint(250, 247), wxSize(153, 25), 0, wxDefaultValidator
, wxT("StateTxt"));
1614 pCountryMsg
= new wxStaticText(this, EDITOR_DIALOG_COUNTRY_MSG
, wxT("Country:"), wxPoint( 17, 280), wxDefaultSize
, 0, wxT("CountryMsg"));
1615 pCountryTxt
= new wxTextCtrl(this, EDITOR_DIALOG_COUNTRY_TEXT
, wxEmptyString
, wxPoint( 17, 297), wxSize(225, 25), 0, wxDefaultValidator
, wxT("CountryTxt"));
1616 pPostalCodeMsg
= new wxStaticText(this, EDITOR_DIALOG_POSTAL_MSG
, wxT("Postal Code:"),wxPoint(250, 280), wxDefaultSize
, 0, wxT("PostalCodeMsg"));
1617 pPostalCodeTxt
= new wxTextCtrl(this, EDITOR_DIALOG_POSTAL_TEXT
, wxEmptyString
, wxPoint(250, 297), wxSize(153, 25), 0, wxDefaultValidator
, wxT("PostalCodeTxt"));
1619 wxString choice_strings
[5];
1620 choice_strings
[0] = wxT("English");
1621 choice_strings
[1] = wxT("French");
1622 choice_strings
[2] = wxT("German");
1623 choice_strings
[3] = wxT("Spanish");
1624 choice_strings
[4] = wxT("Other");
1626 pNativeLangChoice
= new wxChoice(this, EDITOR_DIALOG_LANG_CHOICE
, wxPoint( 17, 346), wxSize(277, wxDefaultCoord
), 5, choice_strings
);
1627 pNativeLangMsg
= new wxStaticText(this, EDITOR_DIALOG_LANG_MSG
, wxT("Native language:"), wxPoint( 17, 330), wxDefaultSize
, 0, wxT("NativeLangMsg"));
1629 wxString radio_strings
[2];
1630 radio_strings
[0] = wxT("No");
1631 radio_strings
[1] = wxT("Yes");
1632 pDeveloperRadio
= new wxRadioBox(this,EDITOR_DIALOG_DEVELOPER
, wxT("Developer:"), wxPoint(303, 330), wxDefaultSize
, 2, radio_strings
, 2, wxHORIZONTAL
);
1633 pJoinDateMsg
= new wxStaticText(this, EDITOR_DIALOG_JOIN_MSG
, wxT("Date joined:"), wxPoint( 17, 380), wxDefaultSize
, 0, wxT("JoinDateMsg"));
1634 pJoinDateTxt
= new wxTextCtrl(this, EDITOR_DIALOG_JOIN_TEXT
, wxEmptyString
, wxPoint( 17, 397), wxSize(150, 25), 0, wxDefaultValidator
, wxT("JoinDateTxt"));
1635 pContribMsg
= new wxStaticText(this, EDITOR_DIALOG_CONTRIB_MSG
,wxT("Contributions:"), wxPoint(175, 380), wxDefaultSize
, 0, wxT("ContribMsg"));
1636 pContribTxt
= new wxTextCtrl(this, EDITOR_DIALOG_CONTRIB_TEXT
, wxEmptyString
, wxPoint(175, 397), wxSize(120, 25), 0, wxDefaultValidator
, wxT("ContribTxt"));
1637 pLinesMsg
= new wxStaticText(this, EDITOR_DIALOG_LINES_MSG
, wxT("Lines of code:"), wxPoint(303, 380), wxDefaultSize
, 0, wxT("LinesMsg"));
1638 pLinesTxt
= new wxTextCtrl(this, EDITOR_DIALOG_LINES_TEXT
, wxEmptyString
, wxPoint(303, 397), wxSize(100, 25), 0, wxDefaultValidator
, wxT("LinesTxt"));
1640 pCatalogBtn
= new wxButton(this, EDITOR_DIALOG_CATALOG
, wxT("Catalo&g"), wxPoint(430, 287), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("CatalogBtn"));
1641 pDataTypesBtn
= new wxButton(this, EDITOR_DIALOG_DATATYPES
, wxT("Data&types"), wxPoint(430, 337), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("DataTypesBtn"));
1642 pDbDiagsBtn
= new wxButton(this, EDITOR_DIALOG_DB_DIAGS
, wxT("DB Dia&gs"), wxPoint(430, 387), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("DbDiagsBtn"));
1644 #ifdef wxODBC_BLOB_SUPPORT
1645 pPictureMsg
= new wxStaticText(this, EDITOR_DIALOG_PIC_MSG
, wxT("Picture:"), wxPoint( 17,430), wxDefaultSize
, 0, wxT("PicMsg"));
1646 pPictSizeMsg
= new wxStaticText(this, EDITOR_DIALOG_PICSIZE_MSG
, wxT("Picture Bytes:"), wxPoint(175,430), wxDefaultSize
, 0, wxT("PicSizeMsg"));
1647 pChooseImageBtn
= new wxButton(this, EDITOR_DIALOG_PIC_BROWSE
, wxT("Select..."), wxPoint( 17,447), wxSize( 70, 24), 0, wxDefaultValidator
, wxT("PicBrowseBtn"));
1648 pShowImageBtn
= new wxButton(this, EDITOR_DIALOG_PIC_SHOW
, wxT("Show..."), wxPoint( 97,447), wxSize( 70, 24), 0, wxDefaultValidator
, wxT("PictShowBtn"));
1649 pPictSizeTxt
= new wxTextCtrl(this, EDITOR_DIALOG_PIC_SIZE_TEXT
, wxEmptyString
, wxPoint(175,447), wxSize(120, 25), 0, wxDefaultValidator
, wxT("PictSizeTxt"));
1652 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
1653 // handle all widget processing
1654 widgetPtrsSet
= true;
1656 // Setup the orderBy and where clauses to return back a single record as the result set,
1657 // as there will only be one record being shown on the dialog at a time, this optimizes
1658 // network traffic by only returning a one row result
1660 wxGetApp().Contact
->SetOrderByClause(wxT("NAME")); // field name to sort by
1662 // The wxString "whereStr" is not a member of the wxDbTable object, it is a member variable
1663 // specifically in the Ccontact class. It is used here for simpler construction of a varying
1664 // length string, and then after the string is built, the wxDbTable member variable "where" is
1665 // assigned the pointer to the constructed string.
1667 // The constructed where clause below has a sub-query within it "SELECT MIN(NAME) FROM %s"
1668 // to achieve a single row (in this case the first name in alphabetical order).
1670 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
1671 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
1673 wxGetApp().Contact
->whereStr
.Printf(wxT("NAME = (SELECT MIN(NAME) FROM %s)"),
1674 wxGetApp().Contact
->GetTableName().c_str());
1675 // NOTE: (const wxChar*) returns a pointer which may not be valid later, so this is short term use only
1676 wxGetApp().Contact
->SetWhereClause(wxGetApp().Contact
->whereStr
);
1679 wxGetApp().Contact
->SetWhereClause(wxEmptyString
);
1681 // Perform the Query to get the result set.
1682 // NOTE: If there are no rows returned, that is a valid result, so Query() would return true.
1683 // Only if there is a database error will Query() come back as false
1684 if (!wxGetApp().Contact
->Query())
1687 tStr
= wxT("ODBC error during Query()\n\n");
1688 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
1689 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
1693 // Since Query succeeded, now get the row that was returned
1694 if (!wxGetApp().Contact
->GetNext())
1695 // If the GetNext() failed at this point, then there are no rows to retrieve,
1696 // so clear the values in the members of "Contact" so that PutData() blanks the
1697 // widgets on the dialog
1698 wxGetApp().Contact
->Initialize();
1700 wxGetApp().Contact->GetDb()->RollbackTrans();
1709 } // CeditorDlg::Initialize()
1711 #ifdef wxODBC_BLOB_SUPPORT
1713 void CeditorDlg::OnSelectPict()
1715 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
);
1717 if (dlg
.ShowModal() == wxID_OK
)
1719 wxFile
file(dlg
.GetPath());
1721 if (file
.IsOpened())
1723 // assume not huge file in sample
1724 long iSize
= (long)file
.Length();
1726 if ((iSize
> 0) && (iSize
< MAX_PICTURE_SIZE
))
1728 wxGetApp().Contact
->BlobSize
= (size_t)iSize
;
1730 memset(wxGetApp().Contact
->Picture
, 0, MAX_PICTURE_SIZE
);
1732 wxFileOffset iReadSize
= file
.Read(wxGetApp().Contact
->Picture
, (size_t)iSize
);
1734 if (iReadSize
< iSize
)
1735 wxMessageBox(wxT("Something bad happened while reading..."), wxT("BLOB Loading Error"), wxOK
| wxICON_EXCLAMATION
);
1738 tStr
.Printf(wxT("%ld"),iSize
);
1739 pPictSizeTxt
->SetValue(tStr
);
1742 wxMessageBox(wxT("Selected File is TOO BIG. 60k is the max image size"), wxT("BLOB Loading Error"), wxOK
| wxICON_EXCLAMATION
);
1745 wxMessageBox(wxT("Unable to open the requested image file"), wxT("File Access Error"), wxOK
| wxICON_EXCLAMATION
);
1749 void CeditorDlg::OnShowImage()
1751 if (wxGetApp().Contact
->BlobSize
> 0)
1753 CimageDlg
dlg(this, wxGetApp().Contact
->Picture
, wxGetApp().Contact
->BlobSize
);
1761 void CeditorDlg::FieldsEditable()
1766 pNameTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1767 pAddress1Txt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1768 pAddress2Txt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1769 pCityTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1770 pStateTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1771 pPostalCodeTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1772 pCountryTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1774 pJoinDateTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1775 pContribTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1776 pLinesTxt
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1777 pNativeLangChoice
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1778 pDeveloperRadio
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1780 #ifdef wxODBC_BLOB_SUPPORT
1781 pPictSizeTxt
->Enable(false);
1782 pChooseImageBtn
->Enable((mode
== mCreate
) || (mode
== mEdit
));
1783 pShowImageBtn
->Enable(wxGetApp().Contact
&& wxGetApp().Contact
->BlobSize
> 0); //((mode == mCreate) || (mode == mEdit));
1786 } // CeditorDlg::FieldsEditable()
1789 void CeditorDlg::SetMode(enum DialogModes m
)
1810 pCreateBtn
->Enable( !edit
);
1811 pEditBtn
->Enable( !edit
&& (wxStrcmp(wxGetApp().Contact
->Name
, wxEmptyString
) != 0) );
1812 pDeleteBtn
->Enable( !edit
&& (wxStrcmp(wxGetApp().Contact
->Name
, wxEmptyString
)!=0) );
1813 pCopyBtn
->Enable( !edit
&& (wxStrcmp(wxGetApp().Contact
->Name
, wxEmptyString
)!=0) );
1814 pSaveBtn
->Enable( edit
);
1815 pCancelBtn
->Enable( edit
);
1816 pPrevBtn
->Enable( !edit
);
1817 pNextBtn
->Enable( !edit
);
1818 pQueryBtn
->Enable( !edit
);
1819 pResetBtn
->Enable( !edit
&& !wxGetApp().Contact
->qryWhereStr
.empty() );
1820 pNameListBtn
->Enable( !edit
);
1824 } // CeditorDlg::SetMode()
1827 bool CeditorDlg::PutData()
1831 pNameTxt
->SetValue(wxGetApp().Contact
->Name
);
1832 pAddress1Txt
->SetValue(wxGetApp().Contact
->Addr1
);
1833 pAddress2Txt
->SetValue(wxGetApp().Contact
->Addr2
);
1834 pCityTxt
->SetValue(wxGetApp().Contact
->City
);
1835 pStateTxt
->SetValue(wxGetApp().Contact
->State
);
1836 pCountryTxt
->SetValue(wxGetApp().Contact
->Country
);
1837 pPostalCodeTxt
->SetValue(wxGetApp().Contact
->PostalCode
);
1839 tStr
.Printf(wxT("%d/%d/%d"),wxGetApp().Contact
->JoinDate
.month
,wxGetApp().Contact
->JoinDate
.day
,wxGetApp().Contact
->JoinDate
.year
);
1840 pJoinDateTxt
->SetValue(tStr
);
1842 tStr
.Printf(wxT("%d"),wxGetApp().Contact
->Contributions
);
1843 pContribTxt
->SetValue(tStr
);
1845 tStr
.Printf(wxT("%lu"),wxGetApp().Contact
->LinesOfCode
);
1846 pLinesTxt
->SetValue(tStr
);
1848 pNativeLangChoice
->SetSelection(wxGetApp().Contact
->NativeLanguage
);
1850 pDeveloperRadio
->SetSelection(wxGetApp().Contact
->IsDeveloper
);
1852 #ifdef wxODBC_BLOB_SUPPORT
1853 tStr
.Printf(wxT("%lu"),wxGetApp().Contact
->BlobSize
);
1854 pPictSizeTxt
->SetValue(tStr
);
1855 pShowImageBtn
->Enable(wxGetApp().Contact
->BlobSize
> 0);
1859 } // Ceditor::PutData()
1863 * Reads the data out of all the widgets on the dialog. Some data evaluation is done
1864 * to ensure that there is a name entered and that the date field is valid.
1866 * A return value of true means that valid data was retrieved from the dialog, otherwise
1867 * invalid data was found (and a message was displayed telling the user what to fix), and
1868 * the data was not placed into the appropraite fields of Ccontact
1870 bool CeditorDlg::GetData()
1872 // Validate that the data currently entered into the widgets is valid data
1875 tStr
= pNameTxt
->GetValue();
1876 if (!wxStrcmp((const wxChar
*) tStr
, wxEmptyString
))
1878 wxMessageBox(wxT("A name is required for entry into the contact table"), wxT("Notice..."), wxOK
| wxICON_INFORMATION
);
1882 bool invalid
= false;
1883 int mm
= 1,dd
= 1,yyyy
= 2001;
1886 tStr
= pJoinDateTxt
->GetValue();
1887 if (tStr
.Freq(wxT('/')) != 2)
1890 // Find the month, day, and year tokens
1893 first
= tStr
.First(wxT('/'));
1894 second
= tStr
.Last(wxT('/'));
1896 mm
= wxAtoi(tStr
.SubString(0,first
));
1897 dd
= wxAtoi(tStr
.SubString(first
+1,second
));
1898 yyyy
= wxAtoi(tStr
.SubString(second
+1,tStr
.Length()-1));
1900 invalid
= !(mm
&& dd
&& yyyy
);
1903 // Force Year 2000 compliance
1904 if (!invalid
&& (yyyy
< 1000))
1907 // Check the token ranges for validity
1912 else if ((mm
< 1) || (mm
> 12))
1920 int days
[12] = {31,28,31,30,31,30,
1922 if (dd
> days
[mm
-1])
1925 if ((dd
== 29) && (mm
== 2))
1927 if (((yyyy
% 4) == 0) && (((yyyy
% 100) != 0) || ((yyyy
% 400) == 0)))
1937 wxGetApp().Contact
->JoinDate
.month
= (unsigned short) mm
;
1938 wxGetApp().Contact
->JoinDate
.day
= (unsigned short) dd
;
1939 wxGetApp().Contact
->JoinDate
.year
= (short) yyyy
;
1943 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
);
1947 tStr
= pNameTxt
->GetValue();
1948 wxStrcpy(wxGetApp().Contact
->Name
,(const wxChar
*) tStr
);
1949 wxStrcpy(wxGetApp().Contact
->Addr1
,pAddress1Txt
->GetValue());
1950 wxStrcpy(wxGetApp().Contact
->Addr2
,pAddress2Txt
->GetValue());
1951 wxStrcpy(wxGetApp().Contact
->City
,pCityTxt
->GetValue());
1952 wxStrcpy(wxGetApp().Contact
->State
,pStateTxt
->GetValue());
1953 wxStrcpy(wxGetApp().Contact
->Country
,pCountryTxt
->GetValue());
1954 wxStrcpy(wxGetApp().Contact
->PostalCode
,pPostalCodeTxt
->GetValue());
1956 wxGetApp().Contact
->Contributions
= (UCHAR
)wxAtoi(pContribTxt
->GetValue());
1957 wxGetApp().Contact
->LinesOfCode
= wxAtol(pLinesTxt
->GetValue());
1959 wxGetApp().Contact
->NativeLanguage
= (enum Language
) pNativeLangChoice
->GetSelection();
1960 wxGetApp().Contact
->IsDeveloper
= pDeveloperRadio
->GetSelection() > 0;
1963 } // CeditorDlg::GetData()
1967 * Retrieve data from the dialog, verify the validity of the data, and if it is valid,
1968 * try to insert/update the data to the table based on the current 'mode' the dialog
1971 * A return value of true means the insert/update was completed successfully, a return
1972 * value of false means that Save() failed. If returning false, then this function
1973 * has displayed a detailed error message for the user.
1975 bool CeditorDlg::Save()
1977 bool failed
= false;
1979 // Read the data in the widgets of the dialog to get the user's data
1983 // Perform any other required validations necessary before saving
1986 wxBeginBusyCursor();
1988 if (mode
== mCreate
)
1990 RETCODE result
= (RETCODE
)wxGetApp().Contact
->Insert();
1992 failed
= (result
!= DB_SUCCESS
);
1995 // Some errors may be expected, like a duplicate key, so handle those instances with
1996 // specific error messages.
1997 if (result
== DB_ERR_INTEGRITY_CONSTRAINT_VIOL
)
2000 tStr
= wxT("A duplicate key value already exists in the table.\nUnable to save record\n\n");
2001 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2002 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2006 // Some other unexpected error occurred
2008 tStr
= wxT("Database insert failed\n\n");
2009 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2010 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2014 else // mode == mEdit
2016 wxGetApp().Contact
->GetDb()->RollbackTrans();
2017 wxGetApp().Contact
->whereStr
.Printf(wxT("NAME = '%s'"),saveName
.c_str());
2018 if (!wxGetApp().Contact
->UpdateWhere(wxGetApp().Contact
->whereStr
))
2021 tStr
= wxT("Database update failed\n\n");
2022 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2023 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2030 wxGetApp().Contact
->GetDb()->CommitTrans();
2031 SetMode(mView
); // Sets the dialog mode back to viewing after save is successful
2034 wxGetApp().Contact
->GetDb()->RollbackTrans();
2040 } // CeditorDlg::Save()
2044 * Where this program is only showing a single row at a time in the dialog,
2045 * a special where clause must be built to find just the single row which,
2046 * in sequence, would follow the currently displayed row.
2048 bool CeditorDlg::GetNextRec()
2052 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
2053 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
2055 w
= wxT("NAME = (SELECT MIN(NAME) FROM ");
2056 w
+= wxGetApp().Contact
->GetTableName();
2057 w
+= wxT(" WHERE NAME > '");
2060 w
= wxT("(NAME > '");
2062 w
+= wxGetApp().Contact
->Name
;
2065 // If a query where string is currently set, append that criteria
2066 if (!wxGetApp().Contact
->qryWhereStr
.empty())
2069 w
+= wxGetApp().Contact
->qryWhereStr
;
2076 } // CeditorDlg::GetNextRec()
2080 * Where this program is only showing a single row at a time in the dialog,
2081 * a special where clause must be built to find just the single row which,
2082 * in sequence, would precede the currently displayed row.
2084 bool CeditorDlg::GetPrevRec()
2088 if (wxGetApp().Contact
->GetDb()->Dbms() != dbmsPOSTGRES
&&
2089 wxGetApp().Contact
->GetDb()->Dbms() != dbmsMY_SQL
)
2091 w
= wxT("NAME = (SELECT MAX(NAME) FROM ");
2092 w
+= wxGetApp().Contact
->GetTableName();
2093 w
+= wxT(" WHERE NAME < '");
2096 w
= wxT("(NAME < '");
2098 w
+= wxGetApp().Contact
->Name
;
2101 // If a query where string is currently set, append that criteria
2102 if (!wxGetApp().Contact
->qryWhereStr
.empty())
2105 w
+= wxGetApp().Contact
->qryWhereStr
;
2113 } // CeditorDlg::GetPrevRec()
2117 * This function is here to avoid duplicating this same code in both the
2118 * GetPrevRec() and GetNextRec() functions
2120 bool CeditorDlg::GetRec(const wxString
&whereStr
)
2122 wxGetApp().Contact
->SetWhereClause(whereStr
);
2123 wxGetApp().Contact
->SetOrderByClause(wxT("NAME"));
2125 if (!wxGetApp().Contact
->Query())
2128 tStr
= wxT("ODBC error during Query()\n\n");
2129 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2130 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2135 if (wxGetApp().Contact
->GetNext())
2142 } // CeditorDlg::GetRec()
2147 * CparameterDlg constructor
2150 BEGIN_EVENT_TABLE(CparameterDlg
, wxDialog
)
2151 EVT_BUTTON(PARAMETER_DIALOG_SAVE
, CparameterDlg::OnButton
)
2152 EVT_BUTTON(PARAMETER_DIALOG_CANCEL
, CparameterDlg::OnButton
)
2153 EVT_CLOSE(CparameterDlg::OnCloseWindow
)
2156 CparameterDlg::CparameterDlg(wxWindow
*parent
) : wxDialog (parent
, PARAMETER_DIALOG
, wxT("ODBC parameter settings"), wxDefaultPosition
, wxSize(400, 325))
2158 // Since the ::OnCommand() function is overridden, this prevents the widget
2159 // detection in ::OnCommand() until all widgets have been initialized to prevent
2160 // uninitialized pointers from crashing the program
2161 widgetPtrsSet
= false;
2163 pParamODBCSourceMsg
= new wxStaticText(this, PARAMETER_DIALOG_SOURCE_MSG
, wxT("ODBC data sources:"), wxPoint( 10, 10), wxDefaultSize
, 0, wxT("ParamODBCSourceMsg"));
2164 pParamODBCSourceList
= new wxListBox(this, PARAMETER_DIALOG_SOURCE_LISTBOX
, wxPoint( 10, 29), wxSize(285, 150), 0, 0, wxLB_SINGLE
|wxLB_ALWAYS_SB
, wxDefaultValidator
, wxT("ParamODBCSourceList"));
2165 pParamUserNameMsg
= new wxStaticText(this, PARAMETER_DIALOG_NAME_MSG
, wxT("Database user name:"), wxPoint( 10, 193), wxDefaultSize
, 0, wxT("ParamUserNameMsg"));
2166 pParamUserNameTxt
= new wxTextCtrl(this, PARAMETER_DIALOG_NAME_TEXT
, wxEmptyString
, wxPoint(10, 209), wxSize( 140, 25), 0, wxDefaultValidator
, wxT("ParamUserNameTxt"));
2167 pParamPasswordMsg
= new wxStaticText(this, PARAMETER_DIALOG_PASSWORD_MSG
, wxT("Password:"), wxPoint(156, 193), wxDefaultSize
, 0, wxT("ParamPasswordMsg"));
2168 pParamPasswordTxt
= new wxTextCtrl(this, PARAMETER_DIALOG_PASSWORD_TEXT
, wxEmptyString
, wxPoint(156, 209), wxSize( 140, 25), 0, wxDefaultValidator
, wxT("ParamPasswordTxt"));
2169 pParamDirPathMsg
= new wxStaticText(this, PARAMETER_DIALOG_DIRPATH_MSG
, wxT("Directory:"), wxPoint( 10, 243), wxDefaultSize
, 0, wxT("ParamDirPathMsg"));
2170 pParamDirPathTxt
= new wxTextCtrl(this, PARAMETER_DIALOG_DIRPATH_TEXT
, wxEmptyString
, wxPoint( 10, 259), wxSize(140, 25), 0, wxDefaultValidator
, wxT("ParamDirPathTxt"));
2171 pParamSaveBtn
= new wxButton(this, PARAMETER_DIALOG_SAVE
, wxT("&Save"), wxPoint(310, 21), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("ParamSaveBtn"));
2172 pParamCancelBtn
= new wxButton(this, PARAMETER_DIALOG_CANCEL
, wxT("C&ancel"), wxPoint(310, 66), wxSize( 70, 35), 0, wxDefaultValidator
, wxT("ParamCancelBtn"));
2174 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
2175 // handle all widget processing
2176 widgetPtrsSet
= true;
2179 savedParamSettings
= wxGetApp().params
;
2184 } // CparameterDlg constructor
2187 void CparameterDlg::OnCloseWindow(wxCloseEvent
& event
)
2189 // Put any additional checking necessary to make certain it is alright
2190 // to close the program here that is not done elsewhere
2193 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
);
2201 wxGetApp().params
= savedParamSettings
;
2204 if (GetParent() != NULL
)
2205 GetParent()->SetFocus();
2211 SetReturnCode(0); // added so BoundsChecker would not report use of uninitialized variable
2214 } // CparameterDlg::OnCloseWindow()
2217 void CparameterDlg::OnButton( wxCommandEvent
&event
)
2219 wxWindow
*win
= (wxWindow
*) event
.GetEventObject();
2220 OnCommand( *win
, event
);
2224 void CparameterDlg::OnCommand(wxWindow
& win
, wxCommandEvent
& WXUNUSED(event
))
2226 wxString widgetName
;
2228 widgetName
= win
.GetName();
2233 if (widgetName
== pParamSaveBtn
->GetName())
2238 tStr
= wxT("Database parameters have been saved.");
2239 if (GetParent() != NULL
) // The parameter dialog was not called during startup due to a missing cfg file
2240 tStr
+= wxT("\nNew parameters will take effect the next time the program is started.");
2241 wxMessageBox(tStr
,wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
2248 if (widgetName
== pParamCancelBtn
->GetName())
2253 } // CparameterDlg::OnCommand()
2256 bool CparameterDlg::PutData()
2258 // Fill the data source list box
2259 FillDataSourceList();
2261 // Fill in the fields from the params object
2262 if (wxGetApp().params
.ODBCSource
&& wxStrlen(wxGetApp().params
.ODBCSource
))
2264 int index
= pParamODBCSourceList
->FindString(wxGetApp().params
.ODBCSource
);
2265 if (index
!= wxNOT_FOUND
)
2266 pParamODBCSourceList
->SetSelection(index
);
2268 pParamUserNameTxt
->SetValue(wxGetApp().params
.UserName
);
2269 pParamPasswordTxt
->SetValue(wxGetApp().params
.Password
);
2270 pParamDirPathTxt
->SetValue(wxGetApp().params
.DirPath
);
2272 } // CparameterDlg::PutData()
2275 bool CparameterDlg::GetData()
2278 if (pParamODBCSourceList
->GetStringSelection() != wxEmptyString
)
2280 tStr
= pParamODBCSourceList
->GetStringSelection();
2281 if (tStr
.Length() > ((int)(sizeof(wxGetApp().params
.ODBCSource
) / sizeof(wxChar
))-1))
2284 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());
2285 wxMessageBox(errmsg
, wxT("Internal program error..."), wxOK
| wxICON_EXCLAMATION
);
2288 wxStrcpy(wxGetApp().params
.ODBCSource
, tStr
);
2293 tStr
= pParamUserNameTxt
->GetValue();
2294 if (tStr
.Length() > ((int)(sizeof(wxGetApp().params
.UserName
) / sizeof(wxChar
))-1))
2297 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());
2298 wxMessageBox(errmsg
, wxT("Internal program error..."), wxOK
| wxICON_EXCLAMATION
);
2301 wxStrcpy(wxGetApp().params
.UserName
, tStr
);
2303 tStr
= pParamPasswordTxt
->GetValue();
2304 if (tStr
.Length() > ((int)(sizeof(wxGetApp().params
.Password
) / sizeof(wxChar
))-1))
2307 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());
2308 wxMessageBox(errmsg
, wxT("Internal program error..."), wxOK
| wxICON_EXCLAMATION
);
2311 wxStrcpy(wxGetApp().params
.Password
,tStr
);
2313 tStr
= pParamDirPathTxt
->GetValue();
2314 tStr
.Replace(wxT("\\"),wxT("/"));
2315 if (tStr
.Length() > ((int)(sizeof(wxGetApp().params
.DirPath
) / sizeof(wxChar
))-1))
2318 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());
2319 wxMessageBox(errmsg
, wxT("Internal program error..."), wxOK
| wxICON_EXCLAMATION
);
2322 wxStrcpy(wxGetApp().params
.DirPath
,tStr
);
2324 } // CparameterDlg::GetData()
2327 bool CparameterDlg::Save()
2329 // Copy the current params in case user cancels changing
2330 // the params, so that we can reset them.
2333 wxGetApp().params
= savedParamSettings
;
2337 wxGetApp().WriteParamFile(wxGetApp().params
);
2340 } // CparameterDlg::Save()
2343 void CparameterDlg::FillDataSourceList()
2345 wxChar Dsn
[SQL_MAX_DSN_LENGTH
+1];
2346 wxChar DsDesc
[254+1];
2347 wxSortedArrayString strArr
;
2349 while (wxDbGetDataSource(wxGetApp().DbConnectInf
->GetHenv(), Dsn
,
2350 SQL_MAX_DSN_LENGTH
, DsDesc
, 254))
2355 for (size_t i
=0; i
< strArr
.GetCount(); i
++)
2357 pParamODBCSourceList
->Append(strArr
[i
].c_str());
2360 } // CparameterDlg::FillDataSourceList()
2363 BEGIN_EVENT_TABLE(CqueryDlg
, wxDialog
)
2364 EVT_BUTTON(wxID_ANY
, CqueryDlg::OnButton
)
2365 EVT_CLOSE(CqueryDlg::OnCloseWindow
)
2369 // CqueryDlg() constructor
2370 CqueryDlg::CqueryDlg(wxWindow
*parent
, wxDb
*pDb
, wxChar
*tblName
[],
2371 const wxString
&pWhereArg
) :
2372 wxDialog (parent
, QUERY_DIALOG
, wxT("Query"), wxDefaultPosition
, wxSize(480, 360))
2374 wxBeginBusyCursor();
2378 masterTableName
= tblName
[0];
2379 widgetPtrsSet
= false;
2382 // Initialize the WHERE clause from the string passed in
2383 pWhere
= pWhereArg
; // Save a pointer to the output buffer
2384 if (pWhere
.Length() > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN
) // Check the length of the buffer passed in
2387 s
.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN
+1);
2388 wxMessageBox(s
,wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2393 pQueryCol1Msg
= new wxStaticText(this, QUERY_DIALOG_COL_MSG
, wxT("Column 1:"), wxPoint( 10, 10), wxSize( 69, 16), 0, wxT("QueryCol1Msg"));
2394 pQueryCol1Choice
= new wxChoice(this, QUERY_DIALOG_COL_CHOICE
, wxPoint( 10, 27), wxSize(250, 27), 0, 0, 0, wxDefaultValidator
, wxT("QueryCol1Choice"));
2395 pQueryNotMsg
= new wxStaticText(this, QUERY_DIALOG_NOT_MSG
, wxT("NOT"), wxPoint(268, 10), wxDefaultSize
, 0, wxT("QueryNotMsg"));
2396 pQueryNotCheck
= new wxCheckBox(this, QUERY_DIALOG_NOT_CHECKBOX
, wxEmptyString
, wxPoint(275, 37), wxSize( 20, 20), 0, wxDefaultValidator
, wxT("QueryNotCheck"));
2398 wxString choice_strings
[9];
2399 choice_strings
[0] = wxT("=");
2400 choice_strings
[1] = wxT("<");
2401 choice_strings
[2] = wxT(">");
2402 choice_strings
[3] = wxT("<=");
2403 choice_strings
[4] = wxT(">=");
2404 choice_strings
[5] = wxT("Begins");
2405 choice_strings
[6] = wxT("Contains");
2406 choice_strings
[7] = wxT("Like");
2407 choice_strings
[8] = wxT("Between");
2409 pQueryOperatorMsg
= new wxStaticText(this, QUERY_DIALOG_OP_MSG
, wxT("Operator:"), wxPoint(305, 10), wxDefaultSize
, 0, wxT("QueryOperatorMsg"));
2410 pQueryOperatorChoice
= new wxChoice(this, QUERY_DIALOG_OP_CHOICE
, wxPoint(305, 27), wxSize( 80, 27), 9, choice_strings
, 0, wxDefaultValidator
, wxT("QueryOperatorChoice"));
2411 pQueryCol2Msg
= new wxStaticText(this, QUERY_DIALOG_COL2_MSG
, wxT("Column 2:"), wxPoint( 10, 65), wxSize( 69, 16), 0, wxT("QueryCol2Msg"));
2412 pQueryCol2Choice
= new wxChoice(this, QUERY_DIALOG_COL2_CHOICE
, wxPoint( 10, 82), wxSize(250, 27), 0, 0, 0, wxDefaultValidator
, wxT("QueryCol2Choice"));
2413 pQuerySqlWhereMsg
= new wxStaticText(this, QUERY_DIALOG_WHERE_MSG
, wxT("SQL where clause:"), wxPoint( 10, 141), wxDefaultSize
, 0, wxT("QuerySqlWhereMsg"));
2414 pQuerySqlWhereMtxt
= new wxTextCtrl(this, QUERY_DIALOG_WHERE_TEXT
, wxEmptyString
, wxPoint( 10, 159), wxSize(377, 134), wxTE_MULTILINE
, wxDefaultValidator
, wxT("QuerySqlWhereMtxt"));
2415 pQueryAddBtn
= new wxButton(this, QUERY_DIALOG_ADD
, wxT("&Add"), wxPoint(406, 24), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryAddBtn"));
2416 pQueryAndBtn
= new wxButton(this, QUERY_DIALOG_AND
, wxT("A&nd"), wxPoint(406, 58), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryAndBtn"));
2417 pQueryOrBtn
= new wxButton(this, QUERY_DIALOG_OR
, wxT("&Or"), wxPoint(406, 92), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryOrBtn"));
2418 pQueryLParenBtn
= new wxButton(this, QUERY_DIALOG_LPAREN
, wxT("("), wxPoint(406, 126), wxSize( 26, 26), 0, wxDefaultValidator
, wxT("QueryLParenBtn"));
2419 pQueryRParenBtn
= new wxButton(this, QUERY_DIALOG_RPAREN
, wxT(")"), wxPoint(436, 126), wxSize( 26, 26), 0, wxDefaultValidator
, wxT("QueryRParenBtn"));
2420 pQueryDoneBtn
= new wxButton(this, QUERY_DIALOG_DONE
, wxT("&Done"), wxPoint(406, 185), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryDoneBtn"));
2421 pQueryClearBtn
= new wxButton(this, QUERY_DIALOG_CLEAR
, wxT("C&lear"), wxPoint(406, 218), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryClearBtn"));
2422 pQueryCountBtn
= new wxButton(this, QUERY_DIALOG_COUNT
, wxT("&Count"), wxPoint(406, 252), wxSize( 56, 26), 0, wxDefaultValidator
, wxT("QueryCountBtn"));
2423 pQueryValue1Msg
= new wxStaticText(this, QUERY_DIALOG_VALUE1_MSG
, wxT("Value:"), wxPoint(277, 66), wxDefaultSize
, 0, wxT("QueryValue1Msg"));
2424 pQueryValue1Txt
= new wxTextCtrl(this, QUERY_DIALOG_VALUE1_TEXT
, wxEmptyString
, wxPoint(277, 83), wxSize(108, 25), 0, wxDefaultValidator
, wxT("QueryValue1Txt"));
2425 pQueryValue2Msg
= new wxStaticText(this, QUERY_DIALOG_VALUE2_MSG
, wxT("AND"), wxPoint(238, 126), wxDefaultSize
, 0, wxT("QueryValue2Msg"));
2426 pQueryValue2Txt
= new wxTextCtrl(this, QUERY_DIALOG_VALUE2_TEXT
, wxEmptyString
, wxPoint(277, 120), wxSize(108, 25), 0, wxDefaultValidator
, wxT("QueryValue2Txt"));
2427 pQueryHintGrp
= new wxStaticBox(this, QUERY_DIALOG_HINT_GROUP
, wxEmptyString
, wxPoint( 10, 291), wxSize(377, 40), 0, wxT("QueryHintGrp"));
2428 pQueryHintMsg
= new wxStaticText(this, QUERY_DIALOG_HINT_MSG
, wxEmptyString
, wxPoint( 16, 306), wxDefaultSize
, 0, wxT("QueryHintMsg"));
2430 widgetPtrsSet
= true;
2431 // Initialize the dialog
2433 pQueryCol2Choice
->Append(wxT("VALUE -->"));
2434 colInf
= pDB
->GetColumns(tblName
);
2440 tStr
= wxT("ODBC error during GetColumns()\n\n");
2441 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2442 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2447 for (i
= 0; colInf
[i
].colName
&& wxStrlen(colInf
[i
].colName
); i
++)
2449 // If there is more than one table being queried, qualify
2450 // the column names with the table name prefix.
2451 if (tblName
[1] && wxStrlen(tblName
[1]))
2453 qualName
.Printf(wxT("%s.%s"), colInf
[i
].tableName
, colInf
[i
].colName
);
2454 pQueryCol1Choice
->Append(qualName
);
2455 pQueryCol2Choice
->Append(qualName
);
2457 else // Single table query, append just the column names
2459 pQueryCol1Choice
->Append(colInf
[i
].colName
);
2460 pQueryCol2Choice
->Append(colInf
[i
].colName
);
2464 pQueryCol1Choice
->SetSelection(0);
2465 pQueryCol2Choice
->SetSelection(0);
2466 pQueryOperatorChoice
->SetSelection(0);
2468 pQueryValue2Msg
->Show(false);
2469 pQueryValue2Txt
->Show(false);
2471 pQueryHintMsg
->SetLabel(langQRY_EQ
);
2473 pQuerySqlWhereMtxt
->SetValue(pWhere
.c_str());
2477 // Display the dialog window
2480 } // CqueryDlg() constructor
2483 CqueryDlg::~CqueryDlg()
2485 } // CqueryDlg::~CqueryDlg() destructor
2488 void CqueryDlg::OnButton(wxCommandEvent
&event
)
2490 wxWindow
*win
= (wxWindow
*) event
.GetEventObject();
2491 OnCommand( *win
, event
);
2492 } // CqueryDlg::OnButton()
2495 void CqueryDlg::OnCommand(wxWindow
& win
, wxCommandEvent
& WXUNUSED(event
))
2497 // Widget pointers won't be set when the dialog is constructed.
2498 // Control is passed through this function once for each widget on
2499 // a dialog as the dialog is constructed.
2503 wxString widgetName
= win
.GetName();
2505 // Operator choice box
2506 if (widgetName
== pQueryOperatorChoice
->GetName())
2508 // Set the help text
2509 switch((qryOp
) pQueryOperatorChoice
->GetSelection())
2512 pQueryHintMsg
->SetLabel(langQRY_EQ
);
2515 pQueryHintMsg
->SetLabel(langQRY_LT
);
2518 pQueryHintMsg
->SetLabel(langQRY_GT
);
2521 pQueryHintMsg
->SetLabel(langQRY_LE
);
2524 pQueryHintMsg
->SetLabel(langQRY_GE
);
2527 pQueryHintMsg
->SetLabel(langQRY_BEGINS
);
2530 pQueryHintMsg
->SetLabel(langQRY_CONTAINS
);
2533 pQueryHintMsg
->SetLabel(langQRY_LIKE
);
2536 pQueryHintMsg
->SetLabel(langQRY_BETWEEN
);
2540 // Hide the value2 widget
2541 pQueryValue2Msg
->Show(false); // BETWEEN will show this widget
2542 pQueryValue2Txt
->Show(false); // BETWEEN will show this widget
2544 // Disable the NOT operator for <, <=, >, >=
2545 switch((qryOp
) pQueryOperatorChoice
->GetSelection())
2551 pQueryNotCheck
->SetValue(0);
2552 pQueryNotCheck
->Enable(false);
2555 pQueryNotCheck
->Enable(true);
2559 // Manipulate the dialog to handle the selected operator
2560 switch((qryOp
) pQueryOperatorChoice
->GetSelection())
2567 pQueryCol2Choice
->Enable(true);
2568 if (pQueryCol2Choice
->GetSelection()) // Column name is highlighted
2570 pQueryValue1Msg
->Show(false);
2571 pQueryValue1Txt
->Show(false);
2573 else // "Value" is highlighted
2575 pQueryValue1Msg
->Show(true);
2576 pQueryValue1Txt
->Show(true);
2577 pQueryValue1Txt
->SetFocus();
2583 pQueryCol2Choice
->SetSelection(0);
2584 pQueryCol2Choice
->Enable(false);
2585 pQueryValue1Msg
->Show(true);
2586 pQueryValue1Txt
->Show(true);
2587 pQueryValue1Txt
->SetFocus();
2590 pQueryCol2Choice
->SetSelection(0);
2591 pQueryCol2Choice
->Enable(false);
2592 pQueryValue2Msg
->Show(true);
2593 pQueryValue2Txt
->Show(true);
2594 pQueryValue1Msg
->Show(true);
2595 pQueryValue1Txt
->Show(true);
2596 pQueryValue1Txt
->SetFocus();
2602 } // Operator choice box
2605 if (widgetName
== pQueryCol2Choice
->GetName())
2607 if (pQueryCol2Choice
->GetSelection()) // Column name is highlighted
2609 pQueryValue1Msg
->Show(false);
2610 pQueryValue1Txt
->Show(false);
2612 else // "Value" is highlighted
2614 pQueryValue1Msg
->Show(true);
2615 pQueryValue1Txt
->Show(true);
2616 pQueryValue1Txt
->SetFocus();
2619 } // Column 2 choice
2622 if (widgetName
== pQueryAddBtn
->GetName())
2629 if (widgetName
== pQueryAndBtn
->GetName())
2631 AppendToWhere(wxT(" AND\n"));
2636 if (widgetName
== pQueryOrBtn
->GetName())
2638 AppendToWhere(wxT(" OR\n"));
2642 // Left Paren button
2643 if (widgetName
== pQueryLParenBtn
->GetName())
2645 AppendToWhere(wxT("("));
2647 } // Left Paren button
2649 // Right paren button
2650 if (widgetName
== pQueryRParenBtn
->GetName())
2652 AppendToWhere(wxT(")"));
2654 } // Right Paren button
2657 if (widgetName
== pQueryDoneBtn
->GetName())
2659 // Be sure the where clause will not overflow the output buffer
2660 if (wxStrlen(pQuerySqlWhereMtxt
->GetValue()) > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN
)
2663 s
.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN
+1);
2664 wxMessageBox(s
,wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2667 // Validate the where clause for things such as matching parens
2668 if (!ValidateWhereClause())
2670 // Copy the where clause to the output buffer and exit
2671 pWhere
= pQuerySqlWhereMtxt
->GetValue();
2677 if (widgetName
== pQueryClearBtn
->GetName())
2679 bool Ok
= (wxMessageBox(wxT("Are you sure you wish to clear the Query?"), wxT("Confirm"), wxYES_NO
|wxICON_QUESTION
) == wxYES
);
2682 pQuerySqlWhereMtxt
->SetValue(wxEmptyString
);
2688 if (widgetName
== pQueryCountBtn
->GetName())
2690 wxBeginBusyCursor();
2696 } // CqueryDlg::OnCommand
2699 void CqueryDlg::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
2706 GetParent()->SetFocus();
2711 SetReturnCode(1); // added so BoundsChecker would not report use of uninitialized variable
2714 } // CqueryDlg::OnCloseWindow()
2717 void CqueryDlg::AppendToWhere(wxChar
*s
)
2719 wxString whereStr
= pQuerySqlWhereMtxt
->GetValue();
2721 pQuerySqlWhereMtxt
->SetValue(whereStr
);
2722 } // CqueryDlg::AppendToWhere()
2725 void CqueryDlg::ProcessAddBtn()
2727 qryOp oper
= (qryOp
) pQueryOperatorChoice
->GetSelection();
2729 // Verify that eveything is filled in correctly
2730 if (pQueryCol2Choice
->GetSelection() == 0) // "Value" is selected
2732 // Verify that value 1 is filled in
2733 if (wxStrlen(pQueryValue1Txt
->GetValue()) == 0)
2736 pQueryValue1Txt
->SetFocus();
2739 // For the BETWEEN operator, value 2 must be filled in as well
2740 if (oper
== qryOpBETWEEN
&&
2741 wxStrlen(pQueryValue2Txt
->GetValue()) == 0)
2744 pQueryValue2Txt
->SetFocus();
2749 // Build the expression and append it to the where clause window
2750 wxString s
= pQueryCol1Choice
->GetStringSelection();
2752 if (pQueryNotCheck
->GetValue() && (oper
!= qryOpEQ
))
2758 if (pQueryNotCheck
->GetValue()) // NOT box is checked
2781 s
+= wxT(" BETWEEN");
2787 int col1Idx
= pQueryCol1Choice
->GetSelection();
2790 if (colInf
[col1Idx
].sqlDataType
== SQL_VARCHAR
||
2791 oper
== qryOpBEGINS
||
2792 oper
== qryOpCONTAINS
||
2796 if (pQueryCol2Choice
->GetSelection()) // Column name
2797 s
+= pQueryCol2Choice
->GetStringSelection();
2798 else // Column 2 is a "value"
2802 if (oper
== qryOpCONTAINS
)
2804 s
+= pQueryValue1Txt
->GetValue();
2805 if (oper
== qryOpCONTAINS
|| oper
== qryOpBEGINS
)
2811 if (oper
== qryOpBETWEEN
)
2816 s
+= pQueryValue2Txt
->GetValue();
2821 AppendToWhere((wxChar
*) (const wxChar
*) s
);
2823 } // CqueryDlg::ProcessAddBtn()
2826 void CqueryDlg::ProcessCountBtn()
2828 if (!ValidateWhereClause())
2831 if (!dbTable
) // wxDbTable object needs to be created and opened
2833 dbTable
= new wxDbTable(pDB
, masterTableName
, 0, (const wxString
&)wxEmptyString
,
2835 wxGetApp().DbConnectInf
->GetDefaultDir());
2838 wxMessageBox(wxT("Memory allocation failed creating a wxDbTable object."),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2841 if (!dbTable
->Open())
2844 tStr
= wxT("ODBC error during Open()\n\n");
2845 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
2846 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
2851 // Count() with WHERE clause
2854 whereStr
= pQuerySqlWhereMtxt
->GetValue();
2855 dbTable
->SetWhereClause(whereStr
.c_str());
2857 ULONG whereCnt
= dbTable
->Count();
2859 // Count() of all records in the table
2860 dbTable
->SetWhereClause(wxEmptyString
);
2861 ULONG totalCnt
= dbTable
->Count();
2863 if (whereCnt
> 0 || totalCnt
== 0)
2866 tStr
.Printf(wxT("%lu of %lu records match the query criteria."),whereCnt
,totalCnt
);
2867 wxMessageBox(tStr
,wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
2872 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
);
2873 wxMessageBox(tStr
,wxT("Notice..."),wxOK
| wxICON_INFORMATION
);
2876 // After a wxMessageBox, the focus does not necessarily return to the
2877 // window which was the focus when the message box popped up, so return
2878 // focus to the Query dialog for certain
2881 } // CqueryDlg::ProcessCountBtn()
2884 bool CqueryDlg::ValidateWhereClause()
2886 wxString where
= pQuerySqlWhereMtxt
->GetValue();
2888 if (where
.Freq(wxT('(')) != where
.Freq(wxT(')')))
2890 wxMessageBox(wxT("There are mismatched parenthesis in the constructed where clause"),wxT("Error..."),wxOK
| wxICON_EXCLAMATION
);
2893 // After a wxMessageBox, the focus does not necessarily return to the
2894 // window which was the focus when the message box popped up, so return
2895 // focus to the Query dialog for certain
2900 } // CqueryDlg::ValidateWhereClause()
2902 #ifdef wxODBC_BLOB_SUPPORT
2904 BEGIN_EVENT_TABLE(CimageDlg
, wxDialog
)
2905 EVT_CLOSE(CimageDlg::OnCloseWindow
)
2908 CimageDlg::CimageDlg(wxWindow
*parent
, wxChar
*pImageData
, off_t iSize
)
2909 : wxDialog(parent
, IMAGE_DIALOG
, wxT("BLOB Image"), wxDefaultPosition
, wxDefaultSize
),
2910 m_pDisplayBmp(NULL
),
2914 wxMemoryInputStream
inStream(pImageData
, iSize
);
2918 m_pImage
= new wxImage(inStream
, wxBITMAP_TYPE_ANY
);
2922 m_pBmp
= new wxBitmap(*m_pImage
);
2923 m_pDisplayBmp
= new wxStaticBitmap(this, IMAGE_DIALOG_STATIC_BMP
, *m_pBmp
, wxPoint(5,5), wxDefaultSize
);
2925 SetSize(m_pBmp
->GetWidth() + 10, m_pBmp
->GetHeight() + 30);
2930 CimageDlg::~CimageDlg()
2939 delete m_pDisplayBmp
;
2942 void CimageDlg::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
2944 GetParent()->SetFocus();
2953 void DisplayDbDiagnostics(wxDb
*pDb
)
2958 s
= wxT("Diagnostics Output\n");
2959 s
+= langDBINF_DB_NAME
;
2960 s
+= pDb
->dbInf
.dbmsName
;
2963 s
+= langDBINF_DB_VER
;
2964 s
+= pDb
->dbInf
.dbmsVer
;
2967 s
+= langDBINF_DRIVER_NAME
;
2968 s
+= pDb
->dbInf
.driverName
;
2971 s
+= langDBINF_DRIVER_ODBC_VER
;
2972 s
+= pDb
->dbInf
.odbcVer
;
2975 s
+= langDBINF_DRIVER_MGR_ODBC_VER
;
2976 s
+= pDb
->dbInf
.drvMgrOdbcVer
;
2979 s
+= langDBINF_DRIVER_VER
;
2980 s
+= pDb
->dbInf
.driverVer
;
2983 s
+= langDBINF_SERVER_NAME
;
2984 s
+= pDb
->dbInf
.serverName
;
2987 s
+= langDBINF_FILENAME
;
2988 s
+= pDb
->dbInf
.databaseName
;
2991 s
+= langDBINF_OUTER_JOINS
;
2992 s
+= pDb
->dbInf
.outerJoins
;
2995 s
+= langDBINF_STORED_PROC
;
2996 s
+= pDb
->dbInf
.procedureSupport
;
2999 if (pDb
->dbInf
.maxConnections
)
3000 t
.sprintf(wxT("%s%d\n"), langDBINF_MAX_HDBC
, pDb
->dbInf
.maxConnections
);
3002 t
.sprintf(wxT("%s%s\n"), langDBINF_MAX_HDBC
, langDBINF_UNLIMITED
);
3005 if (pDb
->dbInf
.maxStmts
)
3006 t
.sprintf(wxT("%s%d\n"), langDBINF_MAX_HSTMT
, pDb
->dbInf
.maxStmts
);
3008 t
.sprintf(wxT("%s%s\n"), langDBINF_MAX_HSTMT
, langDBINF_UNLIMITED
);
3011 s
+= langDBINF_API_LVL
;
3012 switch(pDb
->dbInf
.apiConfLvl
)
3014 case SQL_OAC_NONE
: s
+= langDBINF_NONE
; break;
3015 case SQL_OAC_LEVEL1
: s
+= langDBINF_LEVEL1
; break;
3016 case SQL_OAC_LEVEL2
: s
+= langDBINF_LEVEL2
; break;
3020 s
+= langDBINF_CLI_LVL
;
3021 switch(pDb
->dbInf
.cliConfLvl
)
3023 case SQL_OSCC_NOT_COMPLIANT
: s
+= langDBINF_NOT_COMPLIANT
; break;
3024 case SQL_OSCC_COMPLIANT
: s
+= langDBINF_COMPLIANT
; break;
3028 s
+= langDBINF_SQL_LVL
;
3029 switch(pDb
->dbInf
.sqlConfLvl
)
3031 case SQL_OSC_MINIMUM
: s
+= langDBINF_MIN_GRAMMAR
; break;
3032 case SQL_OSC_CORE
: s
+= langDBINF_CORE_GRAMMAR
; break;
3033 case SQL_OSC_EXTENDED
: s
+= langDBINF_EXT_GRAMMAR
; break;
3037 s
+= langDBINF_COMMIT_BEHAVIOR
;
3038 switch(pDb
->dbInf
.cursorCommitBehavior
)
3040 case SQL_CB_DELETE
: s
+= langDBINF_DELETE_CURSORS
; break;
3041 case SQL_CB_CLOSE
: s
+= langDBINF_CLOSE_CURSORS
; break;
3042 case SQL_CB_PRESERVE
: s
+= langDBINF_PRESERVE_CURSORS
; break;
3046 s
+= langDBINF_ROLLBACK_BEHAVIOR
;
3047 switch(pDb
->dbInf
.cursorRollbackBehavior
)
3049 case SQL_CB_DELETE
: s
+= langDBINF_DELETE_CURSORS
; break;
3050 case SQL_CB_CLOSE
: s
+= langDBINF_CLOSE_CURSORS
; break;
3051 case SQL_CB_PRESERVE
: s
+= langDBINF_PRESERVE_CURSORS
; break;
3055 s
+= langDBINF_SUPP_NOT_NULL
;
3056 switch(pDb
->dbInf
.supportNotNullClause
)
3058 case SQL_NNC_NULL
: s
+= langNO
; break;
3059 case SQL_NNC_NON_NULL
: s
+= langYES
; break;
3063 s
+= langDBINF_SUPP_IEF
;
3064 s
+= pDb
->dbInf
.supportIEF
;
3067 // DEFAULT setting for "Transaction Isolation Level"
3068 s
+= langDBINF_TXN_ISOLATION
;
3069 switch(pDb
->dbInf
.txnIsolation
)
3071 case SQL_TXN_READ_UNCOMMITTED
: s
+= langDBINF_READ_UNCOMMITTED
; break;
3072 case SQL_TXN_READ_COMMITTED
: s
+= langDBINF_READ_COMMITTED
; break;
3073 case SQL_TXN_REPEATABLE_READ
: s
+= langDBINF_REPEATABLE_READ
; break;
3074 case SQL_TXN_SERIALIZABLE
: s
+= langDBINF_SERIALIZABLE
; break;
3076 case SQL_TXN_VERSIONING
: s
+= langDBINF_VERSIONING
; break;
3081 // CURRENT setting for "Transaction Isolation Level"
3083 s
+= langDBINF_TXN_ISOLATION_CURR
;
3084 if (SQLGetConnectOption(pDb
->GetHDBC(),SQL_TXN_ISOLATION
,&txnIsoLvl
) == SQL_SUCCESS
)
3088 case SQL_TXN_READ_UNCOMMITTED
: s
+= langDBINF_READ_UNCOMMITTED
; break;
3089 case SQL_TXN_READ_COMMITTED
: s
+= langDBINF_READ_COMMITTED
; break;
3090 case SQL_TXN_REPEATABLE_READ
: s
+= langDBINF_REPEATABLE_READ
; break;
3091 case SQL_TXN_SERIALIZABLE
: s
+= langDBINF_SERIALIZABLE
; break;
3093 case SQL_TXN_VERSIONING
: s
+= langDBINF_VERSIONING
; break;
3100 #pragma message disable incboodep
3103 s
+= langDBINF_TXN_ISOLATION_OPTS
;
3104 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_READ_UNCOMMITTED
)
3105 {s
+= langDBINF_READ_UNCOMMITTED
; comma
++;}
3106 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_READ_COMMITTED
)
3107 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_READ_COMMITTED
;}
3108 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_REPEATABLE_READ
)
3109 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_REPEATABLE_READ
;}
3110 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_SERIALIZABLE
)
3111 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_SERIALIZABLE
;}
3113 if (pDb
->dbInf
.txnIsolationOptions
& SQL_TXN_VERSIONING
)
3114 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_VERSIONING
;}
3119 s
+= langDBINF_FETCH_DIRS
;
3120 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_NEXT
)
3121 {s
+= langDBINF_NEXT
; comma
++;}
3122 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_PRIOR
)
3123 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_PREV
;}
3124 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_FIRST
)
3125 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_FIRST
;}
3126 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_LAST
)
3127 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_LAST
;}
3128 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_ABSOLUTE
)
3129 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_ABSOLUTE
;}
3130 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_RELATIVE
)
3131 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_RELATIVE
;}
3133 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_RESUME
)
3134 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_RESUME
;}
3136 if (pDb
->dbInf
.fetchDirections
& SQL_FD_FETCH_BOOKMARK
)
3137 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_BOOKMARK
;}
3141 s
+= langDBINF_LOCK_TYPES
;
3142 if (pDb
->dbInf
.lockTypes
& SQL_LCK_NO_CHANGE
)
3143 {s
+= langDBINF_NO_CHANGE
; comma
++;}
3144 if (pDb
->dbInf
.lockTypes
& SQL_LCK_EXCLUSIVE
)
3145 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_EXCLUSIVE
;}
3146 if (pDb
->dbInf
.lockTypes
& SQL_LCK_UNLOCK
)
3147 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_UNLOCK
;}
3151 s
+= langDBINF_POS_OPERS
;
3152 if (pDb
->dbInf
.posOperations
& SQL_POS_POSITION
)
3153 {s
+= langDBINF_POSITION
; comma
++;}
3154 if (pDb
->dbInf
.posOperations
& SQL_POS_REFRESH
)
3155 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_REFRESH
;}
3156 if (pDb
->dbInf
.posOperations
& SQL_POS_UPDATE
)
3157 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_UPD
;}
3158 if (pDb
->dbInf
.posOperations
& SQL_POS_DELETE
)
3159 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_DEL
;}
3160 if (pDb
->dbInf
.posOperations
& SQL_POS_ADD
)
3161 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_ADD
;}
3165 s
+= langDBINF_POS_STMTS
;
3166 if (pDb
->dbInf
.posStmts
& SQL_PS_POSITIONED_DELETE
)
3167 {s
+= langDBINF_POS_DEL
; comma
++;}
3168 if (pDb
->dbInf
.posStmts
& SQL_PS_POSITIONED_UPDATE
)
3169 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_POS_UPD
;}
3170 if (pDb
->dbInf
.posStmts
& SQL_PS_SELECT_FOR_UPDATE
)
3171 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_SELECT_FOR_UPD
;}
3175 s
+= langDBINF_SCROLL_CONCURR
;
3176 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_READ_ONLY
)
3177 {s
+= langDBINF_READ_ONLY
; comma
++;}
3178 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_LOCK
)
3179 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_LOCK
;}
3180 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_OPT_ROWVER
)
3181 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_OPT_ROWVER
;}
3182 if (pDb
->dbInf
.scrollConcurrency
& SQL_SCCO_OPT_VALUES
)
3183 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_OPT_VALUES
;}
3187 s
+= langDBINF_SCROLL_OPTS
;
3188 if (pDb
->dbInf
.scrollOptions
& SQL_SO_FORWARD_ONLY
)
3189 {s
+= langDBINF_FWD_ONLY
; comma
++;}
3190 if (pDb
->dbInf
.scrollOptions
& SQL_SO_STATIC
)
3191 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_STATIC
;}
3192 if (pDb
->dbInf
.scrollOptions
& SQL_SO_KEYSET_DRIVEN
)
3193 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_KEYSET_DRIVEN
;}
3194 if (pDb
->dbInf
.scrollOptions
& SQL_SO_DYNAMIC
)
3195 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_DYNAMIC
;}
3196 if (pDb
->dbInf
.scrollOptions
& SQL_SO_MIXED
)
3197 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_MIXED
;}
3201 s
+= langDBINF_STATIC_SENS
;
3202 if (pDb
->dbInf
.staticSensitivity
& SQL_SS_ADDITIONS
)
3203 {s
+= langDBINF_ADDITIONS
; comma
++;}
3204 if (pDb
->dbInf
.staticSensitivity
& SQL_SS_DELETIONS
)
3205 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_DELETIONS
;}
3206 if (pDb
->dbInf
.staticSensitivity
& SQL_SS_UPDATES
)
3207 {if (comma
++) s
+= wxT(", "); s
+= langDBINF_UPDATES
;}
3210 #pragma message enable incboodep
3214 s
+= langDBINF_TXN_CAPABLE
;
3215 switch(pDb
->dbInf
.txnCapable
)
3217 case SQL_TC_NONE
: s
+= langNO
; break;
3218 case SQL_TC_DML
: s
+= langDBINF_DML_ONLY
; break;
3219 case SQL_TC_DDL_COMMIT
: s
+= langDBINF_DDL_COMMIT
; break;
3220 case SQL_TC_DDL_IGNORE
: s
+= langDBINF_DDL_IGNORE
; break;
3221 case SQL_TC_ALL
: s
+= langDBINF_DDL_AND_DML
; break;
3225 t
.sprintf(wxT("%s%lu\n"), langDBINF_LOGIN_TIMEOUT
, pDb
->dbInf
.loginTimeout
);
3228 // Oracle specific information
3229 if (pDb
->Dbms() == dbmsORACLE
)
3232 s
+= langDBINF_ORACLE_BANNER
;
3235 // Oracle cache hit ratio
3238 pDb
->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'db block gets'"));
3240 if (pDb
->GetData(1, SQL_C_ULONG
, &dbBlockGets
, 0, &cb
))
3242 t
.sprintf(wxT("%s: %lu\n"), langDBINF_DB_BLOCK_GETS
, dbBlockGets
);
3246 ULONG consistentGets
;
3247 pDb
->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'consistent gets'"));
3249 if (pDb
->GetData(1, SQL_C_ULONG
, &consistentGets
, 0, &cb
))
3251 t
.sprintf(wxT("%s: %lu\n"), langDBINF_CONSISTENT_GETS
, consistentGets
);
3256 pDb
->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'physical reads'"));
3258 if (pDb
->GetData(1, SQL_C_ULONG
, &physReads
, 0, &cb
))
3260 t
.sprintf(wxT("%s: %lu\n"), langDBINF_PHYSICAL_READS
, physReads
);
3264 ULONG hitRatio
= (ULONG
)((1.00 - ((float)physReads
/ (float)(dbBlockGets
+ consistentGets
))) * 100.00);
3265 t
.sprintf(wxT("*** %s: %lu%%\n"), langDBINF_CACHE_HIT_RATIO
, hitRatio
);
3268 // Tablespace information
3270 s
+= langDBINF_TABLESPACE_IO
;
3273 char tablespaceName
[256+1];
3274 pDb
->ExecSql(wxT("SELECT NAME,PHYRDS,PHYWRTS FROM V$DATAFILE, V$FILESTAT WHERE V$DATAFILE.FILE# = V$FILESTAT.FILE#"));
3275 while (pDb
->GetNext())
3277 pDb
->GetData(1, SQL_C_WXCHAR
, tablespaceName
, 256, &cb
);
3278 pDb
->GetData(2, SQL_C_ULONG
, &physReads
, 0, &cb
);
3279 pDb
->GetData(3, SQL_C_ULONG
, &physWrites
, 0, &cb
);
3280 t
.sprintf(wxT("%s\n\t%s: %lu\t%s: %lu\n"), tablespaceName
,
3281 langDBINF_PHYSICAL_READS
, physReads
, langDBINF_PHYSICAL_WRITES
, physWrites
);
3288 s
+= wxT("End of Diagnostics\n");
3291 } // DisplayDbDiagnostics()
3295 BEGIN_EVENT_TABLE(DbGridFrame
, wxFrame
)
3296 // EVT_CLOSE(DbGridFrame::OnCloseWindow)
3300 DbGridFrame::DbGridFrame(wxWindow
*parent
)
3301 : wxFrame (parent
, wxID_ANY
, wxT("Database Table"),
3302 wxDefaultPosition
, wxSize(400, 325))
3304 initialized
= false;
3308 void DbGridFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
3314 bool DbGridFrame::Initialize()
3316 wxGrid
*grid
= new wxGrid(this, wxID_ANY
, wxDefaultPosition
);
3318 grid
->RegisterDataType(wxGRID_VALUE_DATETIME
,
3319 new wxGridCellDateTimeRenderer(wxT("%d %b %Y")),
3320 new wxGridCellTextEditor
);
3322 grid
->RegisterDataType(wxGRID_VALUE_CHOICEINT
,
3323 new wxGridCellEnumRenderer
,
3324 new wxGridCellEnumEditor
);
3326 wxString
NativeLangChoice( wxString::Format(wxT("%s:%s,%s,%s,%s,%s"),wxGRID_VALUE_CHOICEINT
,
3334 // Columns must match the sequence specified in SetColDef() calls
3335 wxDbGridColInfo
* cols
=
3336 new wxDbGridColInfo( 0,wxGRID_VALUE_STRING
,wxT("Name"),
3337 new wxDbGridColInfo( 1,wxGRID_VALUE_STRING
,wxT("Address 1"),
3338 new wxDbGridColInfo( 2,wxGRID_VALUE_STRING
,wxT("Address 2"),
3339 new wxDbGridColInfo( 3,wxGRID_VALUE_STRING
,wxT("City"),
3340 new wxDbGridColInfo( 4,wxGRID_VALUE_STRING
,wxT("State"),
3341 new wxDbGridColInfo( 5,wxGRID_VALUE_STRING
,wxT("PostCode"),
3342 new wxDbGridColInfo( 6,wxGRID_VALUE_STRING
,wxT("Country"),
3343 new wxDbGridColInfo( 7,wxGRID_VALUE_DBAUTO
,wxT("Join Date"),
3344 new wxDbGridColInfo( 8,wxGRID_VALUE_BOOL
, wxT("Developer"),
3345 new wxDbGridColInfo( 9,wxGRID_VALUE_NUMBER
,wxT("Contributions"),
3346 new wxDbGridColInfo(10,wxGRID_VALUE_NUMBER
,wxT("Lines Of Code"),
3348 new wxDbGridColInfo(11,NativeLangChoice
, wxT("Native Language"),NULL
))))))))))));
3350 new wxDbGridColInfo(11,wxGRID_VALUE_NUMBER
,wxT("Native Language"),NULL
))))))))))));
3353 Ccontact
*Contact
= new Ccontact();
3354 //wxGetApp().Contact
3358 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"), wxT("Error..."), wxOK
| wxICON_EXCLAMATION
);
3362 if (!Contact
->Open())
3364 if (Contact
->GetDb()->TableExists(CONTACT_TABLE_NAME
, Contact
->GetDb()->GetUsername(),
3365 wxGetApp().DbConnectInf
->GetDefaultDir()))
3368 tStr
.Printf(wxT("Unable to open the table '%s'.\n\n"),CONTACT_TABLE_NAME
.c_str());
3369 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
3370 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
3376 // Execute the following query using the cursor designated
3377 // for full table query
3378 Contact
->SetRowMode(wxDbTable::WX_ROW_MODE_QUERY
);
3380 if (!Contact
->Query())
3383 tStr
= wxT("ODBC error during Query()\n\n");
3384 wxMessageBox(wxDbLogExtendedErrorMsg(tStr
.c_str(),wxGetApp().Contact
->GetDb(),__TFILE__
,__LINE__
),
3385 wxT("ODBC Error..."),wxOK
| wxICON_EXCLAMATION
);
3389 // No data has been read in from the database yet, so
3390 // we need to initialize the data members to valid values
3391 // so Fit() can correctly size the grid
3392 Contact
->Initialize();
3394 wxDbGridTableBase
* db
= new wxDbGridTableBase(Contact
, cols
, wxUSE_QUERY
, true);
3398 grid
->SetTable(db
,true);
3399 grid
->SetMargins(0, 0);
3402 wxSize size
= grid
->GetSize();
3405 SetClientSize(size
);
3408 } // DbGridFrame::Initialize()
3410 #endif // #if wxUSE_GRID
3413 TEST CODE FOR TESTING THE wxDbCreateDataSource() FUNCTION
3416 result = wxDbCreateDataSource(wxT("Microsoft Access Driver (*.mdb)"), wxT("GLT-TEST2"), wxT("GLT-Descrip"), false, wxEmptyString, this);
3419 // check for errors caused by ConfigDSN based functions
3422 wxChar errMsg[500+1];
3423 errMsg[0] = wxT('\0');
3425 SQLInstallerError(1, &retcode, errMsg, 500, &cb);
3427 wxMessageBox(wxT("FAILED creating data source"), wxT("FAILED"));
3430 wxMessageBox(wxT("SUCCEEDED creating data source"), wxT("SUCCESS"));