Removed types that don't exist in iodbc
[wxWidgets.git] / samples / db / dbtest.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: dbtest.cpp
3 // Purpose: wxWidgets database demo app
4 // Author: George Tasker
5 // Modified by:
6 // Created: 1998
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Remstar International, Inc.
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 /*
13 * SYNOPSIS START
14
15 This sample program demonstrates the cross-platform ODBC database classes
16 donated by the development team at Remstar International.
17
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.
20
21 * SYNOPSIS END
22 */
23
24 #ifdef __GNUG__
25 #pragma implementation "dbtest.h"
26 #endif
27
28 #include "wx/wxprec.h"
29
30 #ifdef __BORLANDC__
31 #pragma hdrstop
32 #endif //__BORLANDC__
33
34 #ifndef WX_PRECOMP
35 #include "wx/wx.h"
36 #endif //WX_PRECOMP
37
38 #if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMAC__)
39 #include "db.xpm"
40 #endif
41
42 #include <stdio.h> /* Included strictly for reading the text file with the database parameters */
43
44 //#include "wx/db.h" /* Required in the file which will get the data source connection */
45 //#include "wx/dbtable.h" /* Has the wxDbTable object from which all data objects will inherit their data table functionality */
46
47 //extern wxDbList WXDLLEXPORT *PtrBegDbList; /* from db.cpp, used in getting back error results from db connections */
48
49 #if wxUSE_GRID
50 #include "wx/grid.h"
51 #include "wx/generic/gridctrl.h"
52 #include "wx/dbgrid.h"
53
54 #define CHOICEINT
55 #endif
56
57 #include "dbtest.h" /* Header file for this demonstration program */
58 #include "listdb.h" /* Code to support the "Lookup" button on the editor dialog */
59
60 IMPLEMENT_APP(DatabaseDemoApp)
61
62 extern wxChar ListDB_Selection[]; /* Used to return the first column value for the selected line from the listDB routines */
63 extern wxChar ListDB_Selection2[]; /* Used to return the second column value for the selected line from the listDB routines */
64
65
66 #if !wxUSE_ODBC
67 #error Sample cannot be compiled unless setup.h has wxUSE_ODBC set to 1
68 #endif
69
70
71 bool DataTypeSupported(wxDb *pDb, SWORD datatype, wxString *nativeDataTypeName)
72 {
73 wxDbSqlTypeInfo sqlTypeInfo;
74
75 bool breakpoint = false;
76
77 *nativeDataTypeName = wxEmptyString;
78 if (pDb->GetDataTypeInfo(datatype, sqlTypeInfo))
79 {
80 *nativeDataTypeName = sqlTypeInfo.TypeName;
81 breakpoint = true;
82 }
83
84 return breakpoint;
85
86 } // GetDataTypesSupported();
87
88
89
90 void CheckSupportForAllDataTypes(wxDb *pDb)
91 {
92 wxString nativeDataTypeName;
93
94 wxLogMessage(wxT("\nThe following datatypes are supported by the\ndatabase you are currently connected to:"));
95 #ifdef SQL_C_BINARY
96 if (DataTypeSupported(pDb,SQL_C_BINARY, &nativeDataTypeName))
97 {
98 nativeDataTypeName = wxT("SQL_C_BINARY (") + nativeDataTypeName;
99 nativeDataTypeName += wxT(")\n");
100 wxLogMessage(nativeDataTypeName);
101 }
102 #endif
103 #ifdef SQL_C_BIT
104 if (DataTypeSupported(pDb,SQL_C_BIT, &nativeDataTypeName))
105 {
106 nativeDataTypeName = wxT("SQL_C_BIT (") + nativeDataTypeName;
107 nativeDataTypeName += wxT(")\n");
108 wxLogMessage(nativeDataTypeName);
109 }
110 #endif
111 #ifdef SQL_C_BOOKMARK
112 if (DataTypeSupported(pDb,SQL_C_BOOKMARK, &nativeDataTypeName))
113 {
114 nativeDataTypeName = wxT("SQL_C_BOOKMARK (") + nativeDataTypeName;
115 nativeDataTypeName += wxT(")\n");
116 wxLogMessage(nativeDataTypeName);
117 }
118 #endif
119 #ifdef SQL_C_CHAR
120 if (DataTypeSupported(pDb,SQL_C_CHAR, &nativeDataTypeName))
121 {
122 nativeDataTypeName = wxT("SQL_C_CHAR (") + nativeDataTypeName;
123 nativeDataTypeName += wxT(")\n");
124 wxLogMessage(nativeDataTypeName);
125 }
126 #endif
127 #ifdef SQL_C_DATE
128 if (DataTypeSupported(pDb,SQL_C_DATE, &nativeDataTypeName))
129 {
130 nativeDataTypeName = wxT("SQL_C_DATE (") + nativeDataTypeName;
131 nativeDataTypeName += wxT(")\n");
132 wxLogMessage(nativeDataTypeName);
133 }
134 #endif
135 #ifdef SQL_C_DEFAULT
136 if (DataTypeSupported(pDb,SQL_C_DEFAULT, &nativeDataTypeName))
137 {
138 nativeDataTypeName = wxT("SQL_C_DEFAULT (") + nativeDataTypeName;
139 nativeDataTypeName += wxT(")\n");
140 wxLogMessage(nativeDataTypeName);
141 }
142 #endif
143 #ifdef SQL_C_DOUBLE
144 if (DataTypeSupported(pDb,SQL_C_DOUBLE, &nativeDataTypeName))
145 {
146 nativeDataTypeName = wxT("SQL_C_DOUBLE (") + nativeDataTypeName;
147 nativeDataTypeName += wxT(")\n");
148 wxLogMessage(nativeDataTypeName);
149 }
150 #endif
151 #ifdef SQL_C_FLOAT
152 if (DataTypeSupported(pDb,SQL_C_FLOAT, &nativeDataTypeName))
153 {
154 nativeDataTypeName = wxT("SQL_C_FLOAT (") + nativeDataTypeName;
155 nativeDataTypeName += wxT(")\n");
156 wxLogMessage(nativeDataTypeName);
157 }
158 #endif
159 #ifdef SQL_C_GUID
160 if (DataTypeSupported(pDb,SQL_C_GUID, &nativeDataTypeName))
161 {
162 nativeDataTypeName = wxT("SQL_C_GUID (") + nativeDataTypeName;
163 nativeDataTypeName += wxT(")\n");
164 wxLogMessage(nativeDataTypeName);
165 }
166 #endif
167 #ifdef SQL_C_INTERVAL_DAY
168 if (DataTypeSupported(pDb,SQL_C_INTERVAL_DAY, &nativeDataTypeName))
169 {
170 nativeDataTypeName = wxT("SQL_C_INTERVAL_DAY (") + nativeDataTypeName;
171 nativeDataTypeName += wxT(")\n");
172 wxLogMessage(nativeDataTypeName);
173 }
174 #endif
175 #ifdef SQL_C_INTERVAL_DAY_TO_HOUR
176 if (DataTypeSupported(pDb,SQL_C_INTERVAL_DAY_TO_HOUR, &nativeDataTypeName))
177 {
178 nativeDataTypeName = wxT("SQL_C_INTERVAL_DAY_TO_HOUR (") + nativeDataTypeName;
179 nativeDataTypeName += wxT(")\n");
180 wxLogMessage(nativeDataTypeName);
181 }
182 #endif
183 #ifdef SQL_C_INTERVAL_DAY_TO_MINUTE
184 if (DataTypeSupported(pDb,SQL_C_INTERVAL_DAY_TO_MINUTE, &nativeDataTypeName))
185 {
186 nativeDataTypeName = wxT("SQL_C_INTERVAL_DAY_TO_MINUTE (") + nativeDataTypeName;
187 nativeDataTypeName += wxT(")\n");
188 wxLogMessage(nativeDataTypeName);
189 }
190 #endif
191 #ifdef SQL_C_INTERVAL_DAY_TO_SECOND
192 if (DataTypeSupported(pDb,SQL_C_INTERVAL_DAY_TO_SECOND, &nativeDataTypeName))
193 {
194 nativeDataTypeName = wxT("SQL_C_INTERVAL_DAY_TO_SECOND (") + nativeDataTypeName;
195 nativeDataTypeName += wxT(")\n");
196 wxLogMessage(nativeDataTypeName);
197 }
198 #endif
199 #ifdef SQL_C_INTERVAL_HOUR
200 if (DataTypeSupported(pDb,SQL_C_INTERVAL_HOUR, &nativeDataTypeName))
201 {
202 nativeDataTypeName = wxT("SQL_C_INTERVAL_HOUR (") + nativeDataTypeName;
203 nativeDataTypeName += wxT(")\n");
204 wxLogMessage(nativeDataTypeName);
205 }
206 #endif
207 #ifdef SQL_C_INTERVAL_HOUR_TO_MINUTE
208 if (DataTypeSupported(pDb,SQL_C_INTERVAL_HOUR_TO_MINUTE, &nativeDataTypeName))
209 {
210 nativeDataTypeName = wxT("SQL_C_INTERVAL_HOUR_TO_MINUTE (") + nativeDataTypeName;
211 nativeDataTypeName += wxT(")\n");
212 wxLogMessage(nativeDataTypeName);
213 }
214 #endif
215 #ifdef SQL_C_INTERVAL_HOUR_TO_SECOND
216 if (DataTypeSupported(pDb,SQL_C_INTERVAL_HOUR_TO_SECOND, &nativeDataTypeName))
217 {
218 nativeDataTypeName = wxT("SQL_C_INTERVAL_HOUR_TO_SECOND (") + nativeDataTypeName;
219 nativeDataTypeName += wxT(")\n");
220 wxLogMessage(nativeDataTypeName);
221 }
222 #endif
223 #ifdef SQL_C_INTERVAL_MINUTE
224 if (DataTypeSupported(pDb,SQL_C_INTERVAL_MINUTE, &nativeDataTypeName))
225 {
226 nativeDataTypeName = wxT("SQL_C_INTERVAL_MINUTE (") + nativeDataTypeName;
227 nativeDataTypeName += wxT(")\n");
228 wxLogMessage(nativeDataTypeName);
229 }
230 #endif
231 #ifdef SQL_C_INTERVAL_MINUTE_TO_SECOND
232 if (DataTypeSupported(pDb,SQL_C_INTERVAL_MINUTE_TO_SECOND, &nativeDataTypeName))
233 {
234 nativeDataTypeName = wxT("SQL_C_INTERVAL_MINUTE_TO_SECOND (") + nativeDataTypeName;
235 nativeDataTypeName += wxT(")\n");
236 wxLogMessage(nativeDataTypeName);
237 }
238 #endif
239 #ifdef SQL_C_INTERVAL_MONTH
240 if (DataTypeSupported(pDb,SQL_C_INTERVAL_MONTH, &nativeDataTypeName))
241 {
242 nativeDataTypeName = wxT("SQL_C_INTERVAL_MONTH (") + nativeDataTypeName;
243 nativeDataTypeName += wxT(")\n");
244 wxLogMessage(nativeDataTypeName);
245 }
246 #endif
247 #ifdef SQL_C_INTERVAL_SECOND
248 if (DataTypeSupported(pDb,SQL_C_INTERVAL_SECOND, &nativeDataTypeName))
249 {
250 nativeDataTypeName = wxT("SQL_C_INTERVAL_SECOND (") + nativeDataTypeName;
251 nativeDataTypeName += wxT(")\n");
252 wxLogMessage(nativeDataTypeName);
253 }
254 #endif
255 #ifdef SQL_C_INTERVAL_YEAR
256 if (DataTypeSupported(pDb,SQL_C_INTERVAL_YEAR, &nativeDataTypeName))
257 {
258 nativeDataTypeName = wxT("SQL_C_INTERVAL_YEAR (") + nativeDataTypeName;
259 nativeDataTypeName += wxT(")\n");
260 wxLogMessage(nativeDataTypeName);
261 }
262 #endif
263 #ifdef SQL_C_INTERVAL_YEAR_TO_MONTH
264 if (DataTypeSupported(pDb,SQL_C_INTERVAL_YEAR_TO_MONTH, &nativeDataTypeName))
265 {
266 nativeDataTypeName = wxT("SQL_C_INTERVAL_YEAR_TO_MONTH (") + nativeDataTypeName;
267 nativeDataTypeName += wxT(")\n");
268 wxLogMessage(nativeDataTypeName);
269 }
270 #endif
271 #ifdef SQL_C_LONG
272 if (DataTypeSupported(pDb,SQL_C_LONG, &nativeDataTypeName))
273 {
274 nativeDataTypeName = wxT("SQL_C_LONG (") + nativeDataTypeName;
275 nativeDataTypeName += wxT(")\n");
276 wxLogMessage(nativeDataTypeName);
277 }
278 #endif
279 #ifdef SQL_C_NUMERIC
280 if (DataTypeSupported(pDb,SQL_C_NUMERIC, &nativeDataTypeName))
281 {
282 nativeDataTypeName = wxT("SQL_C_NUMERIC (") + nativeDataTypeName;
283 nativeDataTypeName += wxT(")\n");
284 wxLogMessage(nativeDataTypeName);
285 }
286 #endif
287 #ifdef SQL_C_SBIGINT
288 if (DataTypeSupported(pDb,SQL_C_SBIGINT, &nativeDataTypeName))
289 {
290 nativeDataTypeName = wxT("SQL_C_SBIGINT (") + nativeDataTypeName;
291 nativeDataTypeName += wxT(")\n");
292 wxLogMessage(nativeDataTypeName);
293 }
294 #endif
295 #ifdef SQL_C_SHORT
296 if (DataTypeSupported(pDb,SQL_C_SHORT, &nativeDataTypeName))
297 {
298 nativeDataTypeName = wxT("SQL_C_SHORT (") + nativeDataTypeName;
299 nativeDataTypeName += wxT(")\n");
300 wxLogMessage(nativeDataTypeName);
301 }
302 #endif
303 #ifdef SQL_C_SLONG
304 if (DataTypeSupported(pDb,SQL_C_SLONG, &nativeDataTypeName))
305 {
306 nativeDataTypeName = wxT("SQL_C_SLONG (") + nativeDataTypeName;
307 nativeDataTypeName += wxT(")\n");
308 wxLogMessage(nativeDataTypeName);
309 }
310 #endif
311 #ifdef SQL_C_SSHORT
312 if (DataTypeSupported(pDb,SQL_C_SSHORT, &nativeDataTypeName))
313 {
314 nativeDataTypeName = wxT("SQL_C_SSHORT (") + nativeDataTypeName;
315 nativeDataTypeName += wxT(")\n");
316 wxLogMessage(nativeDataTypeName);
317 }
318 #endif
319 #ifdef SQL_C_STINYINT
320 if (DataTypeSupported(pDb,SQL_C_STINYINT, &nativeDataTypeName))
321 {
322 nativeDataTypeName = wxT("SQL_C_STINYINT (") + nativeDataTypeName;
323 nativeDataTypeName += wxT(")\n");
324 wxLogMessage(nativeDataTypeName);
325 }
326 #endif
327 #ifdef SQL_C_TIME
328 if (DataTypeSupported(pDb,SQL_C_TIME, &nativeDataTypeName))
329 {
330 nativeDataTypeName = wxT("SQL_C_TIME (") + nativeDataTypeName;
331 nativeDataTypeName += wxT(")\n");
332 wxLogMessage(nativeDataTypeName);
333 }
334 #endif
335 #ifdef SQL_C_TIMESTAMP
336 if (DataTypeSupported(pDb,SQL_C_TIMESTAMP, &nativeDataTypeName))
337 {
338 nativeDataTypeName = wxT("SQL_C_TIMESTAMP (") + nativeDataTypeName;
339 nativeDataTypeName += wxT(")\n");
340 wxLogMessage(nativeDataTypeName);
341 }
342 #endif
343 #ifdef SQL_C_TINYINT
344 if (DataTypeSupported(pDb,SQL_C_TINYINT, &nativeDataTypeName))
345 {
346 nativeDataTypeName = wxT("SQL_C_TINYINT (") + nativeDataTypeName;
347 nativeDataTypeName += wxT(")\n");
348 wxLogMessage(nativeDataTypeName);
349 }
350 #endif
351 #ifdef SQL_C_TYPE_DATE
352 if (DataTypeSupported(pDb,SQL_C_TYPE_DATE, &nativeDataTypeName))
353 {
354 nativeDataTypeName = wxT("SQL_C_TYPE_DATE (") + nativeDataTypeName;
355 nativeDataTypeName += wxT(")\n");
356 wxLogMessage(nativeDataTypeName);
357 }
358 #endif
359 #ifdef SQL_C_TYPE_TIME
360 if (DataTypeSupported(pDb,SQL_C_TYPE_TIME, &nativeDataTypeName))
361 {
362 nativeDataTypeName = wxT("SQL_C_TYPE_TIME (") + nativeDataTypeName;
363 nativeDataTypeName += wxT(")\n");
364 wxLogMessage(nativeDataTypeName);
365 }
366 #endif
367 #ifdef SQL_C_TYPE_TIMESTAMP
368 if (DataTypeSupported(pDb,SQL_C_TYPE_TIMESTAMP, &nativeDataTypeName))
369 {
370 nativeDataTypeName = wxT("SQL_C_TYPE_TIMESTAMP (") + nativeDataTypeName;
371 nativeDataTypeName += wxT(")\n");
372 wxLogMessage(nativeDataTypeName);
373 }
374 #endif
375 #ifdef SQL_C_UBIGINT
376 if (DataTypeSupported(pDb,SQL_C_UBIGINT, &nativeDataTypeName))
377 {
378 nativeDataTypeName = wxT("SQL_C_UBIGINT (") + nativeDataTypeName;
379 nativeDataTypeName += wxT(")\n");
380 wxLogMessage(nativeDataTypeName);
381 }
382 #endif
383 #ifdef SQL_C_ULONG
384 if (DataTypeSupported(pDb,SQL_C_ULONG, &nativeDataTypeName))
385 {
386 nativeDataTypeName = wxT("SQL_C_ULONG (") + nativeDataTypeName;
387 nativeDataTypeName += wxT(")\n");
388 wxLogMessage(nativeDataTypeName);
389 }
390 #endif
391 #ifdef SQL_C_USHORT
392 if (DataTypeSupported(pDb,SQL_C_USHORT, &nativeDataTypeName))
393 {
394 nativeDataTypeName = wxT("SQL_C_USHORT (") + nativeDataTypeName;
395 nativeDataTypeName += wxT(")\n");
396 wxLogMessage(nativeDataTypeName);
397 }
398 #endif
399 #ifdef SQL_C_UTINYINT
400 if (DataTypeSupported(pDb,SQL_C_UTINYINT, &nativeDataTypeName))
401 {
402 nativeDataTypeName = wxT("SQL_C_UTINYINT (") + nativeDataTypeName;
403 nativeDataTypeName += wxT(")\n");
404 wxLogMessage(nativeDataTypeName);
405 }
406 #endif
407 #ifdef SQL_C_VARBOOKMARK
408 if (DataTypeSupported(pDb,SQL_C_VARBOOKMARK, &nativeDataTypeName))
409 {
410 nativeDataTypeName = wxT("SQL_C_VARBOOKMARK (") + nativeDataTypeName;
411 nativeDataTypeName += wxT(")\n");
412 wxLogMessage(nativeDataTypeName);
413 }
414 #endif
415
416 // Extended SQL types
417 #ifdef SQL_DATE
418 if (DataTypeSupported(pDb,SQL_DATE, &nativeDataTypeName))
419 {
420 nativeDataTypeName = wxT("SQL_DATE (") + nativeDataTypeName;
421 nativeDataTypeName += wxT(")\n");
422 wxLogMessage(nativeDataTypeName);
423 }
424 #endif
425 #ifdef SQL_INTERVAL
426 if (DataTypeSupported(pDb,SQL_INTERVAL, &nativeDataTypeName))
427 {
428 nativeDataTypeName = wxT("SQL_INTERVAL (") + nativeDataTypeName;
429 nativeDataTypeName += wxT(")\n");
430 wxLogMessage(nativeDataTypeName);
431 }
432 #endif
433 #ifdef SQL_TIME
434 if (DataTypeSupported(pDb,SQL_TIME, &nativeDataTypeName))
435 {
436 nativeDataTypeName = wxT("SQL_TIME (") + nativeDataTypeName;
437 nativeDataTypeName += wxT(")\n");
438 wxLogMessage(nativeDataTypeName);
439 }
440 #endif
441 #ifdef SQL_TIMESTAMP
442 if (DataTypeSupported(pDb,SQL_TIMESTAMP, &nativeDataTypeName))
443 {
444 nativeDataTypeName = wxT("SQL_TIMESTAMP (") + nativeDataTypeName;
445 nativeDataTypeName += wxT(")\n");
446 wxLogMessage(nativeDataTypeName);
447 }
448 #endif
449 #ifdef SQL_LONGVARCHAR
450 if (DataTypeSupported(pDb,SQL_LONGVARCHAR, &nativeDataTypeName))
451 {
452 nativeDataTypeName = wxT("SQL_LONGVARCHAR (") + nativeDataTypeName;
453 nativeDataTypeName += wxT(")\n");
454 wxLogMessage(nativeDataTypeName);
455 }
456 #endif
457 #ifdef SQL_BINARY
458 if (DataTypeSupported(pDb,SQL_BINARY, &nativeDataTypeName))
459 {
460 nativeDataTypeName = wxT("SQL_BINARY (") + nativeDataTypeName;
461 nativeDataTypeName += wxT(")\n");
462 wxLogMessage(nativeDataTypeName);
463 }
464 #endif
465 #ifdef SQL_VARBINARY
466 if (DataTypeSupported(pDb,SQL_VARBINARY, &nativeDataTypeName))
467 {
468 nativeDataTypeName = wxT("SQL_VARBINARY (") + nativeDataTypeName;
469 nativeDataTypeName += wxT(")\n");
470 wxLogMessage(nativeDataTypeName);
471 }
472 #endif
473 #ifdef SQL_LONGVARBINARY
474 if (DataTypeSupported(pDb,SQL_LONGVARBINARY, &nativeDataTypeName))
475 {
476 nativeDataTypeName = wxT("SQL_LOGVARBINARY (") + nativeDataTypeName;
477 nativeDataTypeName += wxT(")\n");
478 wxLogMessage(nativeDataTypeName);
479 }
480 #endif
481 #ifdef SQL_BIGINT
482 if (DataTypeSupported(pDb,SQL_BIGINT, &nativeDataTypeName))
483 {
484 nativeDataTypeName = wxT("SQL_BIGINT (") + nativeDataTypeName;
485 nativeDataTypeName += wxT(")\n");
486 wxLogMessage(nativeDataTypeName);
487 }
488 #endif
489 #ifdef SQL_TINYINT
490 if (DataTypeSupported(pDb,SQL_TINYINT, &nativeDataTypeName))
491 {
492 nativeDataTypeName = wxT("SQL_TINYINT (") + nativeDataTypeName;
493 nativeDataTypeName += wxT(")\n");
494 wxLogMessage(nativeDataTypeName);
495 }
496 #endif
497 #ifdef SQL_BIT
498 if (DataTypeSupported(pDb,SQL_BIT, &nativeDataTypeName))
499 {
500 nativeDataTypeName = wxT("SQL_BIT (") + nativeDataTypeName;
501 nativeDataTypeName += wxT(")\n");
502 wxLogMessage(nativeDataTypeName);
503 }
504 #endif
505 #ifdef SQL_GUID
506 if (DataTypeSupported(pDb,SQL_GUID, &nativeDataTypeName))
507 {
508 nativeDataTypeName = wxT("SQL_GUID (") + nativeDataTypeName;
509 nativeDataTypeName += wxT(")\n");
510 wxLogMessage(nativeDataTypeName);
511 }
512 #endif
513
514 #ifdef SQL_CHAR
515 if (DataTypeSupported(pDb,SQL_CHAR, &nativeDataTypeName))
516 {
517 nativeDataTypeName = wxT("SQL_CHAR (") + nativeDataTypeName;
518 nativeDataTypeName += wxT(")\n");
519 wxLogMessage(nativeDataTypeName);
520 }
521 #endif
522 #ifdef SQL_INTEGER
523 if (DataTypeSupported(pDb,SQL_INTEGER, &nativeDataTypeName))
524 {
525 nativeDataTypeName = wxT("SQL_INTEGER (") + nativeDataTypeName;
526 nativeDataTypeName += wxT(")\n");
527 wxLogMessage(nativeDataTypeName);
528 }
529 #endif
530 #ifdef SQL_SMALLINT
531 if (DataTypeSupported(pDb,SQL_SMALLINT, &nativeDataTypeName))
532 {
533 nativeDataTypeName = wxT("SQL_SAMLLINT (") + nativeDataTypeName;
534 nativeDataTypeName += wxT(")\n");
535 wxLogMessage(nativeDataTypeName);
536 }
537 #endif
538 #ifdef SQL_REAL
539 if (DataTypeSupported(pDb,SQL_REAL, &nativeDataTypeName))
540 {
541 nativeDataTypeName = wxT("SQL_REAL (") + nativeDataTypeName;
542 nativeDataTypeName += wxT(")\n");
543 wxLogMessage(nativeDataTypeName);
544 }
545 #endif
546 #ifdef SQL_DOUBLE
547 if (DataTypeSupported(pDb,SQL_DOUBLE, &nativeDataTypeName))
548 {
549 nativeDataTypeName = wxT("SQL_DOUBLE (") + nativeDataTypeName;
550 nativeDataTypeName += wxT(")\n");
551 wxLogMessage(nativeDataTypeName);
552 }
553 #endif
554 #ifdef SQL_NUMERIC
555 if (DataTypeSupported(pDb,SQL_NUMERIC, &nativeDataTypeName))
556 {
557 nativeDataTypeName = wxT("SQL_NUMERIC (") + nativeDataTypeName;
558 nativeDataTypeName += wxT(")\n");
559 wxLogMessage(nativeDataTypeName);
560 }
561 #endif
562 #ifdef SQL_DATE
563 if (DataTypeSupported(pDb,SQL_DATE, &nativeDataTypeName))
564 {
565 nativeDataTypeName = wxT("SQL_DATE (") + nativeDataTypeName;
566 nativeDataTypeName += wxT(")\n");
567 wxLogMessage(nativeDataTypeName);
568 }
569 #endif
570 #ifdef SQL_TIME
571 if (DataTypeSupported(pDb,SQL_TIME, &nativeDataTypeName))
572 {
573 nativeDataTypeName = wxT("SQL_TIME (") + nativeDataTypeName;
574 nativeDataTypeName += wxT(")\n");
575 wxLogMessage(nativeDataTypeName);
576 }
577 #endif
578 #ifdef SQL_TIMESTAMP
579 if (DataTypeSupported(pDb,SQL_TIMESTAMP, &nativeDataTypeName))
580 {
581 nativeDataTypeName = wxT("SQL_TIMESTAMP (") + nativeDataTypeName;
582 nativeDataTypeName += wxT(")\n");
583 wxLogMessage(nativeDataTypeName);
584 }
585 #endif
586 #ifdef SQL_VARCHAR
587 if (DataTypeSupported(pDb,SQL_VARCHAR, &nativeDataTypeName))
588 {
589 nativeDataTypeName = wxT("SQL_VARCHAR (") + nativeDataTypeName;
590 nativeDataTypeName += wxT(")\n");
591 wxLogMessage(nativeDataTypeName);
592 }
593 #endif
594
595 // UNICODE
596 #ifdef SQL_C_TCHAR
597 if (DataTypeSupported(pDb,SQL_C_TCHAR, &nativeDataTypeName))
598 {
599 nativeDataTypeName = wxT("SQL_C_TCHAR (") + nativeDataTypeName;
600 nativeDataTypeName += wxT(")\n");
601 wxLogMessage(nativeDataTypeName);
602 }
603 #endif
604
605 wxLogMessage(wxT("Done\n"));
606 } // CheckSupportForAllDataTypes()
607
608
609 bool DatabaseDemoApp::OnInit()
610 {
611 DbConnectInf = NULL;
612 Contact = NULL;
613
614 // Create the main frame window
615 DemoFrame = new DatabaseDemoFrame(NULL, wxT("wxWidgets Database Demo"), wxPoint(50, 50), wxSize(537, 480));
616
617 // Give it an icon
618 DemoFrame->SetIcon(wxICON(db));
619
620 // Make a menubar
621 wxMenu *file_menu = new wxMenu;
622 file_menu->Append(FILE_CREATE_ID, wxT("&Create CONTACT table"));
623 file_menu->Append(FILE_RECREATE_TABLE, wxT("&Recreate CONTACT table"));
624 file_menu->Append(FILE_RECREATE_INDEXES, wxT("&Recreate CONTACT indexes"));
625 #if wxUSE_GRID
626 file_menu->Append(FILE_DBGRID_TABLE, wxT("&Open DB Grid example"));
627 #endif
628 file_menu->Append(FILE_EXIT, wxT("E&xit"));
629
630 wxMenu *edit_menu = new wxMenu;
631 edit_menu->Append(EDIT_PARAMETERS, wxT("&Parameters..."));
632
633 wxMenu *help_menu = new wxMenu;
634 help_menu->Append(HELP_ABOUT, wxT("&About"));
635
636 wxMenuBar *menu_bar = new wxMenuBar;
637 menu_bar->Append(file_menu, wxT("&File"));
638 menu_bar->Append(edit_menu, wxT("&Edit"));
639 menu_bar->Append(help_menu, wxT("&Help"));
640 DemoFrame->SetMenuBar(menu_bar);
641
642 params.ODBCSource[0] = 0;
643 params.UserName[0] = 0;
644 params.Password[0] = 0;
645 params.DirPath[0] = 0;
646
647 // Show the frame
648 DemoFrame->Show(true);
649
650 // Passing NULL for the SQL environment handle causes
651 // the wxDbConnectInf constructor to obtain a handle
652 // for you.
653 //
654 // WARNING: Be certain that you do not free this handle
655 // directly with SQLFreeEnv(). Use either the
656 // method ::FreeHenv() or delete the DbConnectInf.
657 DbConnectInf = new wxDbConnectInf(NULL, params.ODBCSource, params.UserName,
658 params.Password, params.DirPath);
659
660 if (!DbConnectInf || !DbConnectInf->GetHenv())
661 {
662 wxMessageBox(wxT("Unable to define data source connection info."), wxT("DB CONNECTION ERROR..."),wxOK | wxICON_EXCLAMATION);
663 wxDELETE(DbConnectInf);
664 }
665
666 if (!ReadParamFile(params))
667 DemoFrame->BuildParameterDialog(NULL);
668
669 if (!wxStrlen(params.ODBCSource))
670 {
671 wxDELETE(DbConnectInf);
672 return(false);
673 }
674
675 DbConnectInf->SetDsn(params.ODBCSource);
676 DbConnectInf->SetUserID(params.UserName);
677 DbConnectInf->SetPassword(params.Password);
678 DbConnectInf->SetDefaultDir(params.DirPath);
679
680 READONLY_DB = wxDbGetConnection(DbConnectInf);
681 if (READONLY_DB == 0)
682 {
683 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);
684 DemoFrame->BuildParameterDialog(NULL);
685 wxDELETE(DbConnectInf);
686 wxMessageBox(wxT("Now exiting program.\n\nRestart program to try any new settings."),wxT("Notice..."),wxOK | wxICON_INFORMATION);
687 return(false);
688 }
689
690 DemoFrame->BuildEditorDialog();
691
692 // Show the frame
693 DemoFrame->Refresh();
694
695 return true;
696 } // DatabaseDemoApp::OnInit()
697
698
699 /*
700 * Remove CR or CR/LF from a character string.
701 */
702 wxChar* wxRemoveLineTerminator(wxChar* aString)
703 {
704 int len = wxStrlen(aString);
705 while (len > 0 && (aString[len-1] == wxT('\r') || aString[len-1] == wxT('\n'))) {
706 aString[len-1] = wxT('\0');
707 len--;
708 }
709 return aString;
710 }
711
712
713 bool DatabaseDemoApp::ReadParamFile(Cparameters &params)
714 {
715 FILE *paramFile;
716 if ((paramFile = wxFopen(PARAM_FILENAME, wxT("r"))) == NULL)
717 {
718 wxString tStr;
719 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);
720 wxMessageBox(tStr,wxT("File I/O Error..."),wxOK | wxICON_EXCLAMATION);
721
722 return false;
723 }
724
725 wxChar buffer[1000+1];
726 wxFgets(buffer, sizeof(params.ODBCSource), paramFile);
727 wxRemoveLineTerminator(buffer);
728 wxStrcpy(params.ODBCSource,buffer);
729
730 wxFgets(buffer, sizeof(params.UserName), paramFile);
731 wxRemoveLineTerminator(buffer);
732 wxStrcpy(params.UserName,buffer);
733
734 wxFgets(buffer, sizeof(params.Password), paramFile);
735 wxRemoveLineTerminator(buffer);
736 wxStrcpy(params.Password,buffer);
737
738 wxFgets(buffer, sizeof(params.DirPath), paramFile);
739 wxRemoveLineTerminator(buffer);
740 wxStrcpy(params.DirPath,buffer);
741
742 fclose(paramFile);
743
744 return true;
745 } // DatabaseDemoApp::ReadParamFile()
746
747
748 bool DatabaseDemoApp::WriteParamFile(Cparameters &WXUNUSED(params))
749 {
750 FILE *paramFile;
751 if ((paramFile = wxFopen(PARAM_FILENAME, wxT("wt"))) == NULL)
752 {
753 wxString tStr;
754 tStr.Printf(wxT("Unable to write/overwrite '%s'."),PARAM_FILENAME);
755 wxMessageBox(tStr,wxT("File I/O Error..."),wxOK | wxICON_EXCLAMATION);
756 return false;
757 }
758
759 wxFputs(wxGetApp().params.ODBCSource, paramFile);
760 wxFputc(wxT('\n'), paramFile);
761 wxFputs(wxGetApp().params.UserName, paramFile);
762 wxFputc(wxT('\n'), paramFile);
763 wxFputs(wxGetApp().params.Password, paramFile);
764 wxFputc(wxT('\n'), paramFile);
765 wxFputs(wxGetApp().params.DirPath, paramFile);
766 wxFputc(wxT('\n'), paramFile);
767 fclose(paramFile);
768
769 return true;
770 } // DatabaseDemoApp::WriteParamFile()
771
772
773 void DatabaseDemoApp::CreateDataTable(bool recreate)
774 {
775 bool Ok = true;
776 if (recreate)
777 Ok = (wxMessageBox(wxT("Any data currently residing in the table will be erased.\n\nAre you sure?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
778
779 if (!Ok)
780 return;
781
782 wxBeginBusyCursor();
783
784 bool success = true;
785
786 Contact->GetDb()->RollbackTrans(); // Make sure the current cursor is in a known/stable state
787
788 if (!Contact->CreateTable(recreate))
789 {
790 wxEndBusyCursor();
791 wxString tStr;
792 tStr = wxT("Error creating CONTACTS table.\nTable was not created.\n\n");
793 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),Contact->GetDb(),__TFILE__,__LINE__),
794 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
795
796 success = false;
797 }
798 else
799 {
800 if (!Contact->CreateIndexes(recreate))
801 {
802 wxEndBusyCursor();
803 wxString tStr;
804 tStr = wxT("Error creating CONTACTS indexes.\nIndexes will be unavailable.\n\n");
805 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),Contact->GetDb(),__TFILE__,__LINE__),
806 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
807
808 success = false;
809 }
810 }
811 while (wxIsBusy())
812 wxEndBusyCursor();
813
814 if (success)
815 wxMessageBox(wxT("Table and index(es) were successfully created."),wxT("Notice..."),wxOK | wxICON_INFORMATION);
816 } // DatabaseDemoApp::CreateDataTable()
817
818
819 BEGIN_EVENT_TABLE(DatabaseDemoFrame, wxFrame)
820 EVT_MENU(FILE_CREATE_ID, DatabaseDemoFrame::OnCreate)
821 EVT_MENU(FILE_RECREATE_TABLE, DatabaseDemoFrame::OnRecreateTable)
822 EVT_MENU(FILE_RECREATE_INDEXES, DatabaseDemoFrame::OnRecreateIndexes)
823 #if wxUSE_GRID
824 EVT_MENU(FILE_DBGRID_TABLE, DatabaseDemoFrame::OnDbGridTable)
825 #endif
826 EVT_MENU(FILE_EXIT, DatabaseDemoFrame::OnExit)
827 EVT_MENU(EDIT_PARAMETERS, DatabaseDemoFrame::OnEditParameters)
828 EVT_MENU(HELP_ABOUT, DatabaseDemoFrame::OnAbout)
829 EVT_CLOSE(DatabaseDemoFrame::OnCloseWindow)
830 END_EVENT_TABLE()
831
832
833 // DatabaseDemoFrame constructor
834 DatabaseDemoFrame::DatabaseDemoFrame(wxFrame *frame, const wxString& title,
835 const wxPoint& pos, const wxSize& size):
836 wxFrame(frame, wxID_ANY, title, pos, size)
837 {
838 // Put any code in necessary for initializing the main frame here
839 pEditorDlg = NULL;
840 pParamDlg = NULL;
841
842 #if wxUSE_LOG
843 delete wxLog::SetActiveTarget(new wxLogStderr);
844 #endif // wxUSE_LOG
845
846 } // DatabaseDemoFrame constructor
847
848 DatabaseDemoFrame::~DatabaseDemoFrame()
849 {
850 #if wxUSE_LOG
851 delete wxLog::SetActiveTarget(NULL);
852 #endif // wxUSE_LOG
853 } // DatabaseDemoFrame destructor
854
855
856 void DatabaseDemoFrame::OnCreate(wxCommandEvent& WXUNUSED(event))
857 {
858 wxGetApp().CreateDataTable(false);
859 } // DatabaseDemoFrame::OnCreate()
860
861
862 void DatabaseDemoFrame::OnRecreateTable(wxCommandEvent& WXUNUSED(event))
863 {
864 wxGetApp().CreateDataTable(true);
865 } // DatabaseDemoFrame::OnRecreate()
866
867
868 void DatabaseDemoFrame::OnRecreateIndexes(wxCommandEvent& WXUNUSED(event))
869 {
870 wxGetApp().Contact->GetDb()->RollbackTrans(); // Make sure the current cursor is in a known/stable state
871
872 if (!wxGetApp().Contact->CreateIndexes(true))
873 {
874 while (wxIsBusy())
875 wxEndBusyCursor();
876 wxString tStr;
877 tStr = wxT("Error creating CONTACTS indexes.\nNew indexes will be unavailable.\n\n");
878 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
879 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
880
881 }
882 else
883 wxMessageBox(wxT("Index(es) were successfully recreated."),wxT("Notice..."),wxOK | wxICON_INFORMATION);
884
885 } // DatabaseDemoFrame::OnRecreateIndexes()
886
887
888 #if wxUSE_GRID
889 void DatabaseDemoFrame::OnDbGridTable(wxCommandEvent& WXUNUSED(event))
890 {
891 DbGridFrame *frame = new DbGridFrame(this);
892 if (frame->Initialize())
893 {
894 frame->Show();
895 }
896 }
897 #endif
898
899 void DatabaseDemoFrame::OnExit(wxCommandEvent& WXUNUSED(event))
900 {
901 Close();
902 } // DatabaseDemoFrame::OnExit()
903
904
905 void DatabaseDemoFrame::OnEditParameters(wxCommandEvent& WXUNUSED(event))
906 {
907 if ((pEditorDlg->mode != mCreate) && (pEditorDlg->mode != mEdit))
908 BuildParameterDialog(this);
909 else
910 wxMessageBox(wxT("Cannot change database parameters while creating or editing a record"),wxT("Notice..."),wxOK | wxICON_INFORMATION);
911 } // DatabaseDemoFrame::OnEditParameters()
912
913
914 void DatabaseDemoFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
915 {
916 wxMessageBox(wxT("wxWidgets sample program for database classes\n\nContributed on 27 July 1998"),wxT("About..."),wxOK | wxICON_INFORMATION);
917 } // DatabaseDemoFrame::OnAbout()
918
919
920 // Put any additional checking necessary to make certain it is alright
921 // to close the program here that is not done elsewhere
922 void DatabaseDemoFrame::OnCloseWindow(wxCloseEvent& event)
923 {
924 // Clean up time
925 if (pEditorDlg && pEditorDlg->Close())
926 pEditorDlg = NULL;
927 else
928 {
929 if (pEditorDlg)
930 {
931 event.Veto();
932 return;
933 }
934 }
935
936 wxDELETE(wxGetApp().Contact);
937
938 // This function will close all the connections to the database that have been
939 // previously cached.
940 wxDbCloseConnections();
941
942 // Deletion of the wxDbConnectInf instance must be the LAST thing done that
943 // has anything to do with the database. Deleting this before disconnecting,
944 // freeing/closing connections, etc will result in a crash!
945 wxDELETE(wxGetApp().DbConnectInf);
946
947 this->Destroy();
948
949 } // DatabaseDemoFrame::OnCloseWindow()
950
951
952 void DatabaseDemoFrame::BuildEditorDialog()
953 {
954 pEditorDlg = NULL;
955 pEditorDlg = new CeditorDlg(this);
956 if (pEditorDlg)
957 {
958 pEditorDlg->Initialize();
959 if (!pEditorDlg->initialized)
960 {
961 pEditorDlg->Close();
962 pEditorDlg = NULL;
963 wxMessageBox(wxT("Unable to initialize the editor dialog for some reason"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
964 Close();
965 }
966 }
967 else
968 {
969 wxMessageBox(wxT("Unable to create the editor dialog for some reason"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
970 Close();
971 }
972 } // DatabaseDemoFrame::BuildEditorDialog()
973
974
975 void DatabaseDemoFrame::BuildParameterDialog(wxWindow *parent)
976 {
977 pParamDlg = new CparameterDlg(parent);
978
979 if (!pParamDlg)
980 wxMessageBox(wxT("Unable to create the parameter dialog for some reason"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
981 } // DatabaseDemoFrame::BuildParameterDialog()
982
983
984 /*
985 * Constructor note: If no wxDb object is passed in, a new connection to the database
986 * is created for this instance of Ccontact. This can be a slow process depending
987 * on the database engine being used, and some database engines have a limit on the
988 * number of connections (either hard limits, or license restricted) so care should
989 * be used to use as few connections as is necessary.
990 *
991 * IMPORTANT: Objects which share a wxDb pointer are ALL acted upon whenever a member
992 * function of pDb is called (i.e. CommitTrans() or RollbackTrans(), so if modifying
993 * or creating a table objects which use the same pDb, know that all the objects
994 * will be committed or rolled back when any of the objects has this function call made.
995 */
996 Ccontact::Ccontact (wxDb *pwxDb) : wxDbTable(pwxDb ? pwxDb : wxDbGetConnection(wxGetApp().DbConnectInf),
997 CONTACT_TABLE_NAME, CONTACT_NO_COLS, wxEmptyString,
998 !wxDB_QUERY_ONLY, wxGetApp().DbConnectInf->GetDefaultDir())
999 {
1000 // This is used to represent whether the database connection should be released
1001 // when this instance of the object is deleted. If using the same connection
1002 // for multiple instance of database objects, then the connection should only be
1003 // released when the last database instance using the connection is deleted
1004 freeDbConn = !pwxDb;
1005
1006 if (GetDb())
1007 GetDb()->SetSqlLogging(sqlLogON);
1008
1009 SetupColumns();
1010
1011 } // Ccontact Constructor
1012
1013
1014 void Ccontact::Initialize()
1015 {
1016 Name[0] = 0;
1017 Addr1[0] = 0;
1018 Addr2[0] = 0;
1019 City[0] = 0;
1020 State[0] = 0;
1021 PostalCode[0] = 0;
1022 Country[0] = 0;
1023 JoinDate.year = 1980;
1024 JoinDate.month = 1;
1025 JoinDate.day = 1;
1026 JoinDate.hour = 0;
1027 JoinDate.minute = 0;
1028 JoinDate.second = 0;
1029 JoinDate.fraction = 0;
1030 NativeLanguage = langENGLISH;
1031 IsDeveloper = false;
1032 Contributions = 0;
1033 LinesOfCode = 0L;
1034 Picture[0] = 0;
1035 } // Ccontact::Initialize
1036
1037
1038 Ccontact::~Ccontact()
1039 {
1040 if (freeDbConn)
1041 {
1042 if (!wxDbFreeConnection(GetDb()))
1043 {
1044 wxString tStr;
1045 tStr = wxT("Unable to Free the Ccontact data table handle\n\n");
1046
1047 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
1048 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
1049 }
1050 }
1051 } // Ccontract destructor
1052
1053
1054 /*
1055 * Handles setting up all the connections for the interface from the wxDbTable
1056 * functions to interface to the data structure used to store records in
1057 * memory, and for all the column definitions that define the table structure
1058 */
1059 void Ccontact::SetupColumns()
1060 {
1061 // NOTE: Columns now are 8 character names, as that is all dBase can support. Longer
1062 // names can be used for other database engines
1063 SetColDefs ( 0,wxT("NAME"), DB_DATA_TYPE_VARCHAR, Name, SQL_C_CHAR, sizeof(Name), true, true); // Primary index
1064 SetColDefs ( 1,wxT("ADDRESS1"), DB_DATA_TYPE_VARCHAR, Addr1, SQL_C_CHAR, sizeof(Addr1), false,true);
1065 SetColDefs ( 2,wxT("ADDRESS2"), DB_DATA_TYPE_VARCHAR, Addr2, SQL_C_CHAR, sizeof(Addr2), false,true);
1066 SetColDefs ( 3,wxT("CITY"), DB_DATA_TYPE_VARCHAR, City, SQL_C_CHAR, sizeof(City), false,true);
1067 SetColDefs ( 4,wxT("STATE"), DB_DATA_TYPE_VARCHAR, State, SQL_C_CHAR, sizeof(State), false,true);
1068 SetColDefs ( 5,wxT("POSTCODE"), DB_DATA_TYPE_VARCHAR, PostalCode, SQL_C_CHAR, sizeof(PostalCode), false,true);
1069 SetColDefs ( 6,wxT("COUNTRY"), DB_DATA_TYPE_VARCHAR, Country, SQL_C_CHAR, sizeof(Country), false,true);
1070 SetColDefs ( 7,wxT("JOINDATE"), DB_DATA_TYPE_DATE, &JoinDate, SQL_C_TIMESTAMP, sizeof(JoinDate), false,true);
1071 SetColDefs ( 8,wxT("IS_DEV"), DB_DATA_TYPE_INTEGER, &IsDeveloper, SQL_C_BOOLEAN(IsDeveloper), sizeof(IsDeveloper), false,true);
1072 SetColDefs ( 9,wxT("CONTRIBS"), DB_DATA_TYPE_INTEGER, &Contributions, SQL_C_UTINYINT, sizeof(Contributions), false,true);
1073 SetColDefs (10,wxT("LINE_CNT"), DB_DATA_TYPE_INTEGER, &LinesOfCode, SQL_C_ULONG, sizeof(LinesOfCode), false,true);
1074 SetColDefs (11,wxT("LANGUAGE"), DB_DATA_TYPE_INTEGER, &NativeLanguage, SQL_C_ENUM, sizeof(NativeLanguage), false,true);
1075 #ifdef wxODBC_BLOB_SUPPORT
1076 SetColDefs (12,wxT("PICTURE"), DB_DATA_TYPE_BLOB, Picture, SQL_C_BINARY, sizeof(Picture), false,true);
1077 #endif
1078 } // Ccontact::SetupColumns
1079
1080
1081 bool Ccontact::CreateIndexes(bool recreate)
1082 {
1083 // This index could easily be accomplished with an "orderBy" clause,
1084 // but is done to show how to construct a non-primary index.
1085 wxString indexName;
1086 wxDbIdxDef idxDef[2];
1087
1088 wxStrcpy(idxDef[0].ColName, wxT("IS_DEV"));
1089 idxDef[0].Ascending = true;
1090
1091 wxStrcpy(idxDef[1].ColName, wxT("NAME"));
1092 idxDef[1].Ascending = true;
1093
1094 indexName = GetTableName();
1095 indexName += wxT("_IDX1");
1096
1097 return CreateIndex(indexName.c_str(), true, 2, idxDef, recreate);
1098
1099 } // Ccontact::CreateIndexes()
1100
1101
1102 /*
1103 * Having a function to do a query on the primary key (and possibly others) is
1104 * very efficient and tighter coding so that it is available where ever the object
1105 * is. Great for use with multiple tables when not using views or outer joins
1106 */
1107 bool Ccontact::FetchByName(const wxString &name)
1108 {
1109 whereStr.Printf(wxT("NAME = '%s'"),name.c_str());
1110 SetWhereClause(whereStr.c_str());
1111 SetOrderByClause(wxT(""));
1112
1113 if (!Query())
1114 return(false);
1115
1116 // Fetch the record
1117 return(GetNext());
1118
1119 } // Ccontact::FetchByName()
1120
1121
1122 /*
1123 *
1124 * ************* DIALOGS ***************
1125 *
1126 */
1127
1128
1129 /* CeditorDlg constructor
1130 *
1131 * Creates the dialog used for creating/editing/deleting/copying a Ccontact object.
1132 * This dialog actually is drawn in the main frame of the program
1133 *
1134 * An instance of Ccontact is created - "Contact" - which is used to hold the Ccontact
1135 * object that is currently being worked with.
1136 */
1137
1138 BEGIN_EVENT_TABLE(CeditorDlg, wxPanel)
1139 EVT_BUTTON(wxID_ANY, CeditorDlg::OnButton)
1140 EVT_CLOSE(CeditorDlg::OnCloseWindow)
1141 END_EVENT_TABLE()
1142
1143 CeditorDlg::CeditorDlg(wxWindow *parent) : wxPanel (parent, 0, 0, 537, 480)
1144 {
1145 // Since the ::OnCommand() function is overridden, this prevents the widget
1146 // detection in ::OnCommand() until all widgets have been initialized to prevent
1147 // uninitialized pointers from crashing the program
1148 widgetPtrsSet = false;
1149
1150 initialized = false;
1151
1152 SetMode(mView);
1153
1154 Show(false);
1155 } // CeditorDlg constructor
1156
1157
1158 void CeditorDlg::OnCloseWindow(wxCloseEvent& event)
1159 {
1160 // Clean up time
1161 if ((mode != mCreate) && (mode != mEdit))
1162 {
1163 this->Destroy();
1164 }
1165 else
1166 {
1167 wxMessageBox(wxT("Must finish processing the current record being created/modified before exiting"),wxT("Notice..."),wxOK | wxICON_INFORMATION);
1168 event.Veto();
1169 }
1170 } // CeditorDlg::OnCloseWindow()
1171
1172
1173 void CeditorDlg::OnButton(wxCommandEvent &event)
1174 {
1175 wxWindow *win = (wxWindow*) event.GetEventObject();
1176 OnCommand( *win, event );
1177 } // CeditorDlg::OnButton()
1178
1179
1180 void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& WXUNUSED(event))
1181 {
1182 wxString widgetName;
1183
1184 widgetName = win.GetName();
1185
1186 if (!widgetPtrsSet)
1187 return;
1188
1189 if (widgetName == pCreateBtn->GetName())
1190 {
1191 wxGetApp().Contact->Initialize();
1192 PutData();
1193 SetMode( mCreate );
1194 pNameTxt->SetValue(wxT(""));
1195 pNameTxt->SetFocus();
1196 return;
1197 }
1198
1199 if (widgetName == pEditBtn->GetName())
1200 {
1201 saveName = wxGetApp().Contact->Name;
1202 SetMode( mEdit );
1203 pNameTxt->SetFocus();
1204 return;
1205 }
1206
1207 if (widgetName == pCopyBtn->GetName())
1208 {
1209 SetMode(mCreate);
1210 pNameTxt->SetValue(wxT(""));
1211 pNameTxt->SetFocus();
1212 return;
1213 }
1214
1215 if (widgetName == pDeleteBtn->GetName())
1216 {
1217 bool Ok = (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
1218
1219 if (!Ok)
1220 return;
1221
1222 if (Ok && wxGetApp().Contact->Delete())
1223 {
1224 // NOTE: Deletions are not finalized until a CommitTrans() is performed.
1225 // If the commit were not performed, the program will continue to
1226 // show the table contents as if they were deleted until this instance
1227 // of Ccontact is deleted. If the Commit wasn't performed, the
1228 // database will automatically Rollback the changes when the database
1229 // connection is terminated
1230 wxGetApp().Contact->GetDb()->CommitTrans();
1231
1232 // Try to get the row that followed the just deleted row in the orderBy sequence
1233 if (!GetNextRec())
1234 {
1235 // There was now row (in sequence) after the just deleted row, so get the
1236 // row which preceded the just deleted row
1237 if (!GetPrevRec())
1238 {
1239 // There are now no rows remaining, so clear the dialog widgets
1240 wxGetApp().Contact->Initialize();
1241 PutData();
1242 }
1243 }
1244 SetMode(mode); // force reset of button enable/disable
1245 }
1246 else
1247 // Delete failed
1248 wxGetApp().Contact->GetDb()->RollbackTrans();
1249
1250 SetMode(mView);
1251 return;
1252 }
1253
1254 if (widgetName == pSaveBtn->GetName())
1255 {
1256 Save();
1257 return;
1258 }
1259
1260 if (widgetName == pCancelBtn->GetName())
1261 {
1262 bool Ok = (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
1263
1264 if (!Ok)
1265 return;
1266
1267 if (saveName.IsEmpty())
1268 {
1269 wxGetApp().Contact->Initialize();
1270 PutData();
1271 SetMode(mView);
1272 return;
1273 }
1274 else
1275 {
1276 // Requery previous record
1277 if (wxGetApp().Contact->FetchByName(saveName))
1278 {
1279 PutData();
1280 SetMode(mView);
1281 return;
1282 }
1283 }
1284
1285 // Previous record not available, retrieve first record in table
1286 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1287 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
1288 {
1289 wxGetApp().Contact->whereStr = wxT("NAME = (SELECT MIN(NAME) FROM ");
1290 wxGetApp().Contact->whereStr += wxGetApp().Contact->GetTableName();
1291 wxGetApp().Contact->whereStr += wxT(")");
1292 wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr.c_str());
1293 }
1294 else
1295 wxGetApp().Contact->SetWhereClause(wxT(""));
1296
1297 if (!wxGetApp().Contact->Query())
1298 {
1299 wxString tStr;
1300 tStr = wxT("ODBC error during Query()\n\n");
1301 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
1302 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
1303
1304 SetMode(mView);
1305 return;
1306 }
1307 if (wxGetApp().Contact->GetNext()) // Successfully read first record
1308 {
1309 PutData();
1310 SetMode(mView);
1311 return;
1312 }
1313 // No contacts are available, clear dialog
1314 wxGetApp().Contact->Initialize();
1315 PutData();
1316 SetMode(mView);
1317 return;
1318 } // Cancel Button
1319
1320 if (widgetName == pPrevBtn->GetName())
1321 {
1322 if (!GetPrevRec())
1323 wxBell();
1324 return;
1325 } // Prev Button
1326
1327 if (widgetName == pNextBtn->GetName())
1328 {
1329 if (!GetNextRec())
1330 wxBell();
1331 return;
1332 } // Next Button
1333
1334 if (widgetName == pQueryBtn->GetName())
1335 {
1336 // Display the query dialog box
1337 wxChar qryWhere[DB_MAX_WHERE_CLAUSE_LEN+1];
1338 wxStrcpy(qryWhere, (const wxChar*) wxGetApp().Contact->qryWhereStr);
1339 wxChar *tblName[] = {(wxChar *)CONTACT_TABLE_NAME, 0};
1340 new CqueryDlg(GetParent(), wxGetApp().Contact->GetDb(), tblName, qryWhere);
1341
1342 // Query the first record in the new record set and
1343 // display it, if the query string has changed.
1344 if (wxStrcmp(qryWhere, (const wxChar*) wxGetApp().Contact->qryWhereStr))
1345 {
1346 wxGetApp().Contact->whereStr.Empty();
1347 wxGetApp().Contact->SetOrderByClause(wxT("NAME"));
1348
1349 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1350 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
1351 {
1352 wxGetApp().Contact->whereStr = wxT("NAME = (SELECT MIN(NAME) FROM ");
1353 wxGetApp().Contact->whereStr += CONTACT_TABLE_NAME;
1354 }
1355
1356 // Append the query where string (if there is one)
1357 wxGetApp().Contact->qryWhereStr = qryWhere;
1358 if (wxStrlen(qryWhere))
1359 {
1360 wxGetApp().Contact->whereStr += wxT(" WHERE ");
1361 wxGetApp().Contact->whereStr += wxGetApp().Contact->qryWhereStr;
1362 }
1363 // Close the expression with a right paren
1364 wxGetApp().Contact->whereStr += wxT(")");
1365 // Requery the table
1366 wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr.c_str());
1367 if (!wxGetApp().Contact->Query())
1368 {
1369 wxString tStr;
1370 tStr = wxT("ODBC error during Query()\n\n");
1371 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
1372 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
1373
1374 return;
1375 }
1376 // Display the first record from the query set
1377 if (!wxGetApp().Contact->GetNext())
1378 wxGetApp().Contact->Initialize();
1379 PutData();
1380 }
1381
1382 // Enable/Disable the reset button
1383 pResetBtn->Enable(!wxGetApp().Contact->qryWhereStr.IsEmpty());
1384
1385 return;
1386 } // Query button
1387
1388
1389 if (widgetName == pResetBtn->GetName())
1390 {
1391 // Clear the additional where criteria established by the query feature
1392 wxGetApp().Contact->qryWhereStr = wxT("");
1393 wxGetApp().Contact->SetOrderByClause(wxT("NAME"));
1394
1395 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1396 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
1397 {
1398 wxGetApp().Contact->whereStr = wxT("NAME = (SELECT MIN(NAME) FROM ");
1399 wxGetApp().Contact->whereStr += CONTACT_TABLE_NAME;
1400 wxGetApp().Contact->whereStr += wxT(")");
1401 }
1402
1403 wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr.c_str());
1404 if (!wxGetApp().Contact->Query())
1405 {
1406 wxString tStr;
1407 tStr = wxT("ODBC error during Query()\n\n");
1408 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
1409 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
1410 return;
1411 }
1412 if (!wxGetApp().Contact->GetNext())
1413 wxGetApp().Contact->Initialize();
1414 PutData();
1415 pResetBtn->Enable(false);
1416
1417 return;
1418 } // Reset button
1419
1420
1421 if (widgetName == pNameListBtn->GetName())
1422 {
1423 new ClookUpDlg(/* wxWindow *parent */ this,
1424 /* wxChar *windowTitle */ wxT("Select contact name"),
1425 /* wxChar *tableName */ (wxChar *) CONTACT_TABLE_NAME,
1426 /* wxChar *dispCol1 */ wxT("NAME"),
1427 /* wxChar *dispCol2 */ wxT("JOINDATE"),
1428 /* wxChar *where */ wxT(""),
1429 /* wxChar *orderBy */ wxT("NAME"),
1430 /* wxDb *pDb */ wxGetApp().READONLY_DB,
1431 /* const wxString &defDir */ wxGetApp().DbConnectInf->GetDefaultDir(),
1432 /* bool distinctValues */ true);
1433
1434 if (ListDB_Selection && wxStrlen(ListDB_Selection))
1435 {
1436 wxString w = wxT("NAME = '");
1437 w += ListDB_Selection;
1438 w += wxT("'");
1439 GetRec(w);
1440 }
1441
1442 return;
1443 }
1444
1445 if (widgetName == pDataTypesBtn->GetName())
1446 {
1447 CheckSupportForAllDataTypes(wxGetApp().READONLY_DB);
1448 wxMessageBox(wxT("Support datatypes was dumped to stdout."));
1449 return;
1450 } // Data types Button
1451
1452 if (widgetName == pDbDiagsBtn->GetName())
1453 {
1454 DisplayDbDiagnostics(wxGetApp().READONLY_DB);
1455 wxMessageBox(wxT("Diagnostics info was dumped to stdout."));
1456 return;
1457 }
1458
1459 if (widgetName == pCatalogBtn->GetName())
1460 {
1461 if (wxGetApp().Contact->GetDb()->Catalog(wxT(""),wxT("catalog.txt")))
1462 wxMessageBox(wxT("The file 'catalog.txt' was created."));
1463 else
1464 wxMessageBox(wxT("Creation of the file 'catalog.txt' was failed."));
1465 return;
1466 }
1467
1468 } // CeditorDlg::OnCommand()
1469
1470
1471 bool CeditorDlg::Initialize()
1472 {
1473 // Create the data structure and a new database connection.
1474 // (As there is not a pDb being passed in the constructor, a new database
1475 // connection is created)
1476 wxGetApp().Contact = new Ccontact();
1477
1478 if (!wxGetApp().Contact)
1479 {
1480 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
1481 return false;
1482 }
1483
1484 // Check if the table exists or not. If it doesn't, ask the user if they want to
1485 // create the table. Continue trying to create the table until it exists, or user aborts
1486 while (!wxGetApp().Contact->GetDb()->TableExists((wxChar *)CONTACT_TABLE_NAME,
1487 wxGetApp().DbConnectInf->GetUserID(),
1488 wxGetApp().DbConnectInf->GetDefaultDir()))
1489 {
1490 wxString tStr;
1491 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);
1492 bool createTable = (wxMessageBox(tStr.c_str(),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
1493
1494 if (!createTable)
1495 {
1496 // Close();
1497 return false;
1498 }
1499 else
1500 wxGetApp().CreateDataTable(false);
1501 }
1502
1503 // Tables must be "opened" before anything other than creating/deleting table can be done
1504 if (!wxGetApp().Contact->Open())
1505 {
1506 // Table does exist, or there was some problem opening it. Currently this should
1507 // never fail, except in the case of the table not exisiting or the current
1508 // user has insufficent privileges to access the table
1509 #if 1
1510 // This code is experimenting with a new function that will hopefully be available
1511 // in the 2.4 release. This check will determine whether the open failing was due
1512 // to the table not existing, or the users privileges being insufficient to
1513 // open the table.
1514 if (!wxGetApp().Contact->GetDb()->TablePrivileges(CONTACT_TABLE_NAME, wxT("SELECT"),
1515 wxGetApp().Contact->GetDb()->GetUsername(),
1516 wxGetApp().Contact->GetDb()->GetUsername(),
1517 wxGetApp().DbConnectInf->GetDefaultDir()))
1518 {
1519 wxString tStr;
1520 tStr.Printf(wxT("Unable to open the table '%s' (likely due to\ninsufficient privileges of the logged in user).\n\n"),CONTACT_TABLE_NAME);
1521
1522 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
1523 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
1524 }
1525 else
1526 #endif
1527 if (!wxGetApp().Contact->GetDb()->TableExists(CONTACT_TABLE_NAME,
1528 wxGetApp().Contact->GetDb()->GetUsername(),
1529 wxGetApp().DbConnectInf->GetDefaultDir()))
1530 {
1531 wxString tStr;
1532 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);
1533 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
1534 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
1535 }
1536
1537 return false;
1538 }
1539
1540 // Build the dialog
1541
1542 (void)new wxStaticBox(this, EDITOR_DIALOG_FN_GROUP, wxT(""), wxPoint(15, 1), wxSize(497, 69), 0, wxT("FunctionGrp"));
1543 (void)new wxStaticBox(this, EDITOR_DIALOG_SEARCH_GROUP, wxT(""), wxPoint(417, 1), wxSize(95, 242), 0, wxT("SearchGrp"));
1544
1545 pCreateBtn = new wxButton(this, EDITOR_DIALOG_CREATE, wxT("&Create"), wxPoint( 25, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("CreateBtn"));
1546 pEditBtn = new wxButton(this, EDITOR_DIALOG_EDIT, wxT("&Edit"), wxPoint(102, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("EditBtn"));
1547 pDeleteBtn = new wxButton(this, EDITOR_DIALOG_DELETE, wxT("&Delete"), wxPoint(179, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("DeleteBtn"));
1548 pCopyBtn = new wxButton(this, EDITOR_DIALOG_COPY, wxT("Cop&y"), wxPoint(256, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("CopyBtn"));
1549 pSaveBtn = new wxButton(this, EDITOR_DIALOG_SAVE, wxT("&Save"), wxPoint(333, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("SaveBtn"));
1550 pCancelBtn = new wxButton(this, EDITOR_DIALOG_CANCEL, wxT("C&ancel"), wxPoint(430, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("CancelBtn"));
1551 pPrevBtn = new wxButton(this, EDITOR_DIALOG_PREV, wxT("<< &Prev"), wxPoint(430, 81), wxSize( 70, 35), 0, wxDefaultValidator, wxT("PrevBtn"));
1552 pNextBtn = new wxButton(this, EDITOR_DIALOG_NEXT, wxT("&Next >>"), wxPoint(430, 121), wxSize( 70, 35), 0, wxDefaultValidator, wxT("NextBtn"));
1553 pQueryBtn = new wxButton(this, EDITOR_DIALOG_QUERY, wxT("&Query"), wxPoint(430, 161), wxSize( 70, 35), 0, wxDefaultValidator, wxT("QueryBtn"));
1554 pResetBtn = new wxButton(this, EDITOR_DIALOG_RESET, wxT("&Reset"), wxPoint(430, 200), wxSize( 70, 35), 0, wxDefaultValidator, wxT("ResetBtn"));
1555 pNameMsg = new wxStaticText(this, EDITOR_DIALOG_NAME_MSG, wxT("Name:"), wxPoint( 17, 80), wxDefaultSize, 0, wxT("NameMsg"));
1556 pNameTxt = new wxTextCtrl(this, EDITOR_DIALOG_NAME_TEXT, wxT(""), wxPoint( 17, 97), wxSize(308, 25), 0, wxDefaultValidator, wxT("NameTxt"));
1557 pNameListBtn = new wxButton(this, EDITOR_DIALOG_LOOKUP, wxT("&Lookup"), wxPoint(333, 97), wxSize( 70, 24), 0, wxDefaultValidator, wxT("LookupBtn"));
1558 pAddress1Msg = new wxStaticText(this, EDITOR_DIALOG_ADDRESS1_MSG, wxT("Address:"), wxPoint( 17, 130), wxDefaultSize, 0, wxT("Address1Msg"));
1559 pAddress1Txt = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT, wxT(""), wxPoint( 17, 147), wxSize(308, 25), 0, wxDefaultValidator, wxT("Address1Txt"));
1560 pAddress2Msg = new wxStaticText(this, EDITOR_DIALOG_ADDRESS2_MSG, wxT("Address:"), wxPoint( 17, 180), wxDefaultSize, 0, wxT("Address2Msg"));
1561 pAddress2Txt = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT, wxT(""), wxPoint( 17, 197), wxSize(308, 25), 0, wxDefaultValidator, wxT("Address2Txt"));
1562 pCityMsg = new wxStaticText(this, EDITOR_DIALOG_CITY_MSG, wxT("City:"), wxPoint( 17, 230), wxDefaultSize, 0, wxT("CityMsg"));
1563 pCityTxt = new wxTextCtrl(this, EDITOR_DIALOG_CITY_TEXT, wxT(""), wxPoint( 17, 247), wxSize(225, 25), 0, wxDefaultValidator, wxT("CityTxt"));
1564 pStateMsg = new wxStaticText(this, EDITOR_DIALOG_STATE_MSG, wxT("State:"), wxPoint(250, 230), wxDefaultSize, 0, wxT("StateMsg"));
1565 pStateTxt = new wxTextCtrl(this, EDITOR_DIALOG_STATE_TEXT, wxT(""), wxPoint(250, 247), wxSize(153, 25), 0, wxDefaultValidator, wxT("StateTxt"));
1566 pCountryMsg = new wxStaticText(this, EDITOR_DIALOG_COUNTRY_MSG, wxT("Country:"), wxPoint( 17, 280), wxDefaultSize, 0, wxT("CountryMsg"));
1567 pCountryTxt = new wxTextCtrl(this, EDITOR_DIALOG_COUNTRY_TEXT, wxT(""), wxPoint( 17, 297), wxSize(225, 25), 0, wxDefaultValidator, wxT("CountryTxt"));
1568 pPostalCodeMsg = new wxStaticText(this, EDITOR_DIALOG_POSTAL_MSG, wxT("Postal Code:"),wxPoint(250, 280), wxDefaultSize, 0, wxT("PostalCodeMsg"));
1569 pPostalCodeTxt = new wxTextCtrl(this, EDITOR_DIALOG_POSTAL_TEXT, wxT(""), wxPoint(250, 297), wxSize(153, 25), 0, wxDefaultValidator, wxT("PostalCodeTxt"));
1570
1571 wxString choice_strings[5];
1572 choice_strings[0] = wxT("English");
1573 choice_strings[1] = wxT("French");
1574 choice_strings[2] = wxT("German");
1575 choice_strings[3] = wxT("Spanish");
1576 choice_strings[4] = wxT("Other");
1577
1578 pNativeLangChoice = new wxChoice(this, EDITOR_DIALOG_LANG_CHOICE, wxPoint( 17, 346), wxSize(277, wxDefaultCoord), 5, choice_strings);
1579 pNativeLangMsg = new wxStaticText(this, EDITOR_DIALOG_LANG_MSG, wxT("Native language:"), wxPoint( 17, 330), wxDefaultSize, 0, wxT("NativeLangMsg"));
1580
1581 wxString radio_strings[2];
1582 radio_strings[0] = wxT("No");
1583 radio_strings[1] = wxT("Yes");
1584 pDeveloperRadio = new wxRadioBox(this,EDITOR_DIALOG_DEVELOPER, wxT("Developer:"), wxPoint(303, 330), wxDefaultSize, 2, radio_strings, 2, wxHORIZONTAL);
1585 pJoinDateMsg = new wxStaticText(this, EDITOR_DIALOG_JOIN_MSG, wxT("Date joined:"), wxPoint( 17, 380), wxDefaultSize, 0, wxT("JoinDateMsg"));
1586 pJoinDateTxt = new wxTextCtrl(this, EDITOR_DIALOG_JOIN_TEXT, wxT(""), wxPoint( 17, 397), wxSize(150, 25), 0, wxDefaultValidator, wxT("JoinDateTxt"));
1587 pContribMsg = new wxStaticText(this, EDITOR_DIALOG_CONTRIB_MSG,wxT("Contributions:"), wxPoint(175, 380), wxDefaultSize, 0, wxT("ContribMsg"));
1588 pContribTxt = new wxTextCtrl(this, EDITOR_DIALOG_CONTRIB_TEXT, wxT(""), wxPoint(175, 397), wxSize(120, 25), 0, wxDefaultValidator, wxT("ContribTxt"));
1589 pLinesMsg = new wxStaticText(this, EDITOR_DIALOG_LINES_MSG, wxT("Lines of code:"), wxPoint(303, 380), wxDefaultSize, 0, wxT("LinesMsg"));
1590 pLinesTxt = new wxTextCtrl(this, EDITOR_DIALOG_LINES_TEXT, wxT(""), wxPoint(303, 397), wxSize(100, 25), 0, wxDefaultValidator, wxT("LinesTxt"));
1591
1592 pCatalogBtn = new wxButton(this, EDITOR_DIALOG_CATALOG, wxT("Catalo&g"), wxPoint(430, 287), wxSize( 70, 35), 0, wxDefaultValidator, wxT("CatalogBtn"));
1593 pDataTypesBtn = new wxButton(this, EDITOR_DIALOG_DATATYPES, wxT("Data&types"), wxPoint(430, 337), wxSize( 70, 35), 0, wxDefaultValidator, wxT("DataTypesBtn"));
1594 pDbDiagsBtn = new wxButton(this, EDITOR_DIALOG_DB_DIAGS, wxT("DB Dia&gs"), wxPoint(430, 387), wxSize( 70, 35), 0, wxDefaultValidator, wxT("DbDiagsBtn"));
1595
1596 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
1597 // handle all widget processing
1598 widgetPtrsSet = true;
1599
1600 // Setup the orderBy and where clauses to return back a single record as the result set,
1601 // as there will only be one record being shown on the dialog at a time, this optimizes
1602 // network traffic by only returning a one row result
1603
1604 wxGetApp().Contact->SetOrderByClause(wxT("NAME")); // field name to sort by
1605
1606 // The wxString "whereStr" is not a member of the wxDbTable object, it is a member variable
1607 // specifically in the Ccontact class. It is used here for simpler construction of a varying
1608 // length string, and then after the string is built, the wxDbTable member variable "where" is
1609 // assigned the pointer to the constructed string.
1610 //
1611 // The constructed where clause below has a sub-query within it "SELECT MIN(NAME) FROM %s"
1612 // to achieve a single row (in this case the first name in alphabetical order).
1613
1614 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1615 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
1616 {
1617 wxGetApp().Contact->whereStr.Printf(wxT("NAME = (SELECT MIN(NAME) FROM %s)"),
1618 wxGetApp().Contact->GetTableName().c_str());
1619 // NOTE: (const wxChar*) returns a pointer which may not be valid later, so this is short term use only
1620 wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr);
1621 }
1622 else
1623 wxGetApp().Contact->SetWhereClause(wxT(""));
1624
1625 // Perform the Query to get the result set.
1626 // NOTE: If there are no rows returned, that is a valid result, so Query() would return true.
1627 // Only if there is a database error will Query() come back as false
1628 if (!wxGetApp().Contact->Query())
1629 {
1630 wxString tStr;
1631 tStr = wxT("ODBC error during Query()\n\n");
1632 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
1633 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
1634 return false;
1635 }
1636
1637 // Since Query succeeded, now get the row that was returned
1638 if (!wxGetApp().Contact->GetNext())
1639 // If the GetNext() failed at this point, then there are no rows to retrieve,
1640 // so clear the values in the members of "Contact" so that PutData() blanks the
1641 // widgets on the dialog
1642 wxGetApp().Contact->Initialize();
1643 /*
1644 wxGetApp().Contact->GetDb()->RollbackTrans();
1645 */
1646 SetMode(mView);
1647 PutData();
1648
1649 Show(true);
1650
1651 initialized = true;
1652 return true;
1653 } // CeditorDlg::Initialize()
1654
1655
1656 void CeditorDlg::FieldsEditable()
1657 {
1658 if (!widgetPtrsSet)
1659 return;
1660
1661 pNameTxt->Enable((mode == mCreate) || (mode == mEdit));
1662 pAddress1Txt->Enable((mode == mCreate) || (mode == mEdit));
1663 pAddress2Txt->Enable((mode == mCreate) || (mode == mEdit));
1664 pCityTxt->Enable((mode == mCreate) || (mode == mEdit));
1665 pStateTxt->Enable((mode == mCreate) || (mode == mEdit));
1666 pPostalCodeTxt->Enable((mode == mCreate) || (mode == mEdit));
1667 pCountryTxt->Enable((mode == mCreate) || (mode == mEdit));
1668
1669 pJoinDateTxt->Enable((mode == mCreate) || (mode == mEdit));
1670 pContribTxt->Enable((mode == mCreate) || (mode == mEdit));
1671 pLinesTxt->Enable((mode == mCreate) || (mode == mEdit));
1672 pNativeLangChoice->Enable((mode == mCreate) || (mode == mEdit));
1673 pDeveloperRadio->Enable((mode == mCreate) || (mode == mEdit));
1674
1675 } // CeditorDlg::FieldsEditable()
1676
1677
1678 void CeditorDlg::SetMode(enum DialogModes m)
1679 {
1680 bool edit = false;
1681
1682 mode = m;
1683 switch (mode)
1684 {
1685 case mCreate:
1686 case mEdit:
1687 edit = true;
1688 break;
1689 case mView:
1690 case mSearch:
1691 edit = false;
1692 break;
1693 default:
1694 break;
1695 };
1696
1697 if (widgetPtrsSet)
1698 {
1699 pCreateBtn->Enable( !edit );
1700 pEditBtn->Enable( !edit && (wxStrcmp(wxGetApp().Contact->Name,wxT(""))!=0) );
1701 pDeleteBtn->Enable( !edit && (wxStrcmp(wxGetApp().Contact->Name,wxT(""))!=0) );
1702 pCopyBtn->Enable( !edit && (wxStrcmp(wxGetApp().Contact->Name,wxT(""))!=0) );
1703 pSaveBtn->Enable( edit );
1704 pCancelBtn->Enable( edit );
1705 pPrevBtn->Enable( !edit );
1706 pNextBtn->Enable( !edit );
1707 pQueryBtn->Enable( !edit );
1708 pResetBtn->Enable( !edit && !wxGetApp().Contact->qryWhereStr.IsEmpty() );
1709 pNameListBtn->Enable( !edit );
1710 }
1711
1712 FieldsEditable();
1713 } // CeditorDlg::SetMode()
1714
1715
1716 bool CeditorDlg::PutData()
1717 {
1718 wxString tStr;
1719
1720 pNameTxt->SetValue(wxGetApp().Contact->Name);
1721 pAddress1Txt->SetValue(wxGetApp().Contact->Addr1);
1722 pAddress2Txt->SetValue(wxGetApp().Contact->Addr2);
1723 pCityTxt->SetValue(wxGetApp().Contact->City);
1724 pStateTxt->SetValue(wxGetApp().Contact->State);
1725 pCountryTxt->SetValue(wxGetApp().Contact->Country);
1726 pPostalCodeTxt->SetValue(wxGetApp().Contact->PostalCode);
1727
1728 tStr.Printf(wxT("%d/%d/%d"),wxGetApp().Contact->JoinDate.month,wxGetApp().Contact->JoinDate.day,wxGetApp().Contact->JoinDate.year);
1729 pJoinDateTxt->SetValue(tStr);
1730
1731 tStr.Printf(wxT("%d"),wxGetApp().Contact->Contributions);
1732 pContribTxt->SetValue(tStr);
1733
1734 tStr.Printf(wxT("%lu"),wxGetApp().Contact->LinesOfCode);
1735 pLinesTxt->SetValue(tStr);
1736
1737 pNativeLangChoice->SetSelection(wxGetApp().Contact->NativeLanguage);
1738
1739 pDeveloperRadio->SetSelection(wxGetApp().Contact->IsDeveloper);
1740
1741 return true;
1742 } // Ceditor::PutData()
1743
1744
1745 /*
1746 * Reads the data out of all the widgets on the dialog. Some data evaluation is done
1747 * to ensure that there is a name entered and that the date field is valid.
1748 *
1749 * A return value of true means that valid data was retrieved from the dialog, otherwise
1750 * invalid data was found (and a message was displayed telling the user what to fix), and
1751 * the data was not placed into the appropraite fields of Ccontact
1752 */
1753 bool CeditorDlg::GetData()
1754 {
1755 // Validate that the data currently entered into the widgets is valid data
1756
1757 wxString tStr;
1758 tStr = pNameTxt->GetValue();
1759 if (!wxStrcmp((const wxChar*) tStr,wxT("")))
1760 {
1761 wxMessageBox(wxT("A name is required for entry into the contact table"),wxT("Notice..."),wxOK | wxICON_INFORMATION);
1762 return false;
1763 }
1764
1765 bool invalid = false;
1766 int mm = 1,dd = 1,yyyy = 2001;
1767 int first, second;
1768
1769 tStr = pJoinDateTxt->GetValue();
1770 if (tStr.Freq(wxT('/')) != 2)
1771 invalid = true;
1772
1773 // Find the month, day, and year tokens
1774 if (!invalid)
1775 {
1776 first = tStr.First(wxT('/'));
1777 second = tStr.Last(wxT('/'));
1778
1779 mm = wxAtoi(tStr.SubString(0,first));
1780 dd = wxAtoi(tStr.SubString(first+1,second));
1781 yyyy = wxAtoi(tStr.SubString(second+1,tStr.Length()-1));
1782
1783 invalid = !(mm && dd && yyyy);
1784 }
1785
1786 // Force Year 2000 compliance
1787 if (!invalid && (yyyy < 1000))
1788 invalid = true;
1789
1790 // Check the token ranges for validity
1791 if (!invalid)
1792 {
1793 if (yyyy > 9999)
1794 invalid = true;
1795 else if ((mm < 1) || (mm > 12))
1796 invalid = true;
1797 else
1798 {
1799 if (dd < 1)
1800 invalid = true;
1801 else
1802 {
1803 int days[12] = {31,28,31,30,31,30,
1804 31,31,30,31,30,31};
1805 if (dd > days[mm-1])
1806 {
1807 invalid = true;
1808 if ((dd == 29) && (mm == 2))
1809 {
1810 if (((yyyy % 4) == 0) && (((yyyy % 100) != 0) || ((yyyy % 400) == 0)))
1811 invalid = false;
1812 }
1813 }
1814 }
1815 }
1816 }
1817
1818 if (!invalid)
1819 {
1820 wxGetApp().Contact->JoinDate.month = (unsigned short) mm;
1821 wxGetApp().Contact->JoinDate.day = (unsigned short) dd;
1822 wxGetApp().Contact->JoinDate.year = (short) yyyy;
1823 }
1824 else
1825 {
1826 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);
1827 return false;
1828 }
1829
1830 tStr = pNameTxt->GetValue();
1831 wxStrcpy(wxGetApp().Contact->Name,(const wxChar*) tStr);
1832 wxStrcpy(wxGetApp().Contact->Addr1,pAddress1Txt->GetValue());
1833 wxStrcpy(wxGetApp().Contact->Addr2,pAddress2Txt->GetValue());
1834 wxStrcpy(wxGetApp().Contact->City,pCityTxt->GetValue());
1835 wxStrcpy(wxGetApp().Contact->State,pStateTxt->GetValue());
1836 wxStrcpy(wxGetApp().Contact->Country,pCountryTxt->GetValue());
1837 wxStrcpy(wxGetApp().Contact->PostalCode,pPostalCodeTxt->GetValue());
1838
1839 wxGetApp().Contact->Contributions = (UCHAR)wxAtoi(pContribTxt->GetValue());
1840 wxGetApp().Contact->LinesOfCode = wxAtol(pLinesTxt->GetValue());
1841
1842 wxGetApp().Contact->NativeLanguage = (enum Language) pNativeLangChoice->GetSelection();
1843 wxGetApp().Contact->IsDeveloper = pDeveloperRadio->GetSelection() > 0;
1844
1845 return true;
1846 } // CeditorDlg::GetData()
1847
1848
1849 /*
1850 * Retrieve data from the dialog, verify the validity of the data, and if it is valid,
1851 * try to insert/update the data to the table based on the current 'mode' the dialog
1852 * is set to.
1853 *
1854 * A return value of true means the insert/update was completed successfully, a return
1855 * value of false means that Save() failed. If returning false, then this function
1856 * has displayed a detailed error message for the user.
1857 */
1858 bool CeditorDlg::Save()
1859 {
1860 bool failed = false;
1861
1862 // Read the data in the widgets of the dialog to get the user's data
1863 if (!GetData())
1864 failed = true;
1865
1866 // Perform any other required validations necessary before saving
1867 if (!failed)
1868 {
1869 wxBeginBusyCursor();
1870
1871 if (mode == mCreate)
1872 {
1873 RETCODE result = (RETCODE)wxGetApp().Contact->Insert();
1874
1875 failed = (result != DB_SUCCESS);
1876 if (failed)
1877 {
1878 // Some errors may be expected, like a duplicate key, so handle those instances with
1879 // specific error messages.
1880 if (result == DB_ERR_INTEGRITY_CONSTRAINT_VIOL)
1881 {
1882 wxString tStr;
1883 tStr = wxT("A duplicate key value already exists in the table.\nUnable to save record\n\n");
1884 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
1885 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
1886 }
1887 else
1888 {
1889 // Some other unexpected error occurred
1890 wxString tStr;
1891 tStr = wxT("Database insert failed\n\n");
1892 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
1893 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
1894 }
1895 }
1896 }
1897 else // mode == mEdit
1898 {
1899 wxGetApp().Contact->GetDb()->RollbackTrans();
1900 wxGetApp().Contact->whereStr.Printf(wxT("NAME = '%s'"),saveName.c_str());
1901 if (!wxGetApp().Contact->UpdateWhere(wxGetApp().Contact->whereStr))
1902 {
1903 wxString tStr;
1904 tStr = wxT("Database update failed\n\n");
1905 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
1906 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
1907 failed = true;
1908 }
1909 }
1910
1911 if (!failed)
1912 {
1913 wxGetApp().Contact->GetDb()->CommitTrans();
1914 SetMode(mView); // Sets the dialog mode back to viewing after save is successful
1915 }
1916 else
1917 wxGetApp().Contact->GetDb()->RollbackTrans();
1918
1919 wxEndBusyCursor();
1920 }
1921
1922 return !failed;
1923 } // CeditorDlg::Save()
1924
1925
1926 /*
1927 * Where this program is only showing a single row at a time in the dialog,
1928 * a special where clause must be built to find just the single row which,
1929 * in sequence, would follow the currently displayed row.
1930 */
1931 bool CeditorDlg::GetNextRec()
1932 {
1933 wxString w;
1934
1935 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1936 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
1937 {
1938 w = wxT("NAME = (SELECT MIN(NAME) FROM ");
1939 w += wxGetApp().Contact->GetTableName();
1940 w += wxT(" WHERE NAME > '");
1941 }
1942 else
1943 w = wxT("(NAME > '");
1944
1945 w += wxGetApp().Contact->Name;
1946 w += wxT("'");
1947
1948 // If a query where string is currently set, append that criteria
1949 if (!wxGetApp().Contact->qryWhereStr.IsEmpty())
1950 {
1951 w += wxT(" AND (");
1952 w += wxGetApp().Contact->qryWhereStr;
1953 w += wxT(")");
1954 }
1955
1956 w += wxT(")");
1957 return(GetRec(w));
1958
1959 } // CeditorDlg::GetNextRec()
1960
1961
1962 /*
1963 * Where this program is only showing a single row at a time in the dialog,
1964 * a special where clause must be built to find just the single row which,
1965 * in sequence, would precede the currently displayed row.
1966 */
1967 bool CeditorDlg::GetPrevRec()
1968 {
1969 wxString w;
1970
1971 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1972 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
1973 {
1974 w = wxT("NAME = (SELECT MAX(NAME) FROM ");
1975 w += wxGetApp().Contact->GetTableName();
1976 w += wxT(" WHERE NAME < '");
1977 }
1978 else
1979 w = wxT("(NAME < '");
1980
1981 w += wxGetApp().Contact->Name;
1982 w += wxT("'");
1983
1984 // If a query where string is currently set, append that criteria
1985 if (!wxGetApp().Contact->qryWhereStr.IsEmpty())
1986 {
1987 w += wxT(" AND (");
1988 w += wxGetApp().Contact->qryWhereStr;
1989 w += wxT(")");
1990 }
1991
1992 w += wxT(")");
1993
1994 return(GetRec(w));
1995
1996 } // CeditorDlg::GetPrevRec()
1997
1998
1999 /*
2000 * This function is here to avoid duplicating this same code in both the
2001 * GetPrevRec() and GetNextRec() functions
2002 */
2003 bool CeditorDlg::GetRec(const wxString &whereStr)
2004 {
2005 wxGetApp().Contact->SetWhereClause(whereStr);
2006 wxGetApp().Contact->SetOrderByClause(wxT("NAME"));
2007
2008 if (!wxGetApp().Contact->Query())
2009 {
2010 wxString tStr;
2011 tStr = wxT("ODBC error during Query()\n\n");
2012 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
2013 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
2014
2015 return(false);
2016 }
2017
2018 if (wxGetApp().Contact->GetNext())
2019 {
2020 PutData();
2021 return(true);
2022 }
2023 else
2024 return(false);
2025 } // CeditorDlg::GetRec()
2026
2027
2028
2029 /*
2030 * CparameterDlg constructor
2031 */
2032
2033 BEGIN_EVENT_TABLE(CparameterDlg, wxDialog)
2034 EVT_BUTTON(PARAMETER_DIALOG_SAVE, CparameterDlg::OnButton)
2035 EVT_BUTTON(PARAMETER_DIALOG_CANCEL, CparameterDlg::OnButton)
2036 EVT_CLOSE(CparameterDlg::OnCloseWindow)
2037 END_EVENT_TABLE()
2038
2039 CparameterDlg::CparameterDlg(wxWindow *parent) : wxDialog (parent, PARAMETER_DIALOG, wxT("ODBC parameter settings"), wxDefaultPosition, wxSize(400, 325))
2040 {
2041 // Since the ::OnCommand() function is overridden, this prevents the widget
2042 // detection in ::OnCommand() until all widgets have been initialized to prevent
2043 // uninitialized pointers from crashing the program
2044 widgetPtrsSet = false;
2045
2046 pParamODBCSourceMsg = new wxStaticText(this, PARAMETER_DIALOG_SOURCE_MSG, wxT("ODBC data sources:"), wxPoint( 10, 10), wxDefaultSize, 0, wxT("ParamODBCSourceMsg"));
2047 pParamODBCSourceList = new wxListBox(this, PARAMETER_DIALOG_SOURCE_LISTBOX, wxPoint( 10, 29), wxSize(285, 150), 0, 0, wxLB_SINGLE|wxLB_ALWAYS_SB, wxDefaultValidator, wxT("ParamODBCSourceList"));
2048 pParamUserNameMsg = new wxStaticText(this, PARAMETER_DIALOG_NAME_MSG, wxT("Database user name:"), wxPoint( 10, 193), wxDefaultSize, 0, wxT("ParamUserNameMsg"));
2049 pParamUserNameTxt = new wxTextCtrl(this, PARAMETER_DIALOG_NAME_TEXT, wxT(""), wxPoint(10, 209), wxSize( 140, 25), 0, wxDefaultValidator, wxT("ParamUserNameTxt"));
2050 pParamPasswordMsg = new wxStaticText(this, PARAMETER_DIALOG_PASSWORD_MSG, wxT("Password:"), wxPoint(156, 193), wxDefaultSize, 0, wxT("ParamPasswordMsg"));
2051 pParamPasswordTxt = new wxTextCtrl(this, PARAMETER_DIALOG_PASSWORD_TEXT, wxT(""), wxPoint(156, 209), wxSize( 140, 25), 0, wxDefaultValidator, wxT("ParamPasswordTxt"));
2052 pParamDirPathMsg = new wxStaticText(this, PARAMETER_DIALOG_DIRPATH_MSG, wxT("Directory:"), wxPoint( 10, 243), wxDefaultSize, 0, wxT("ParamDirPathMsg"));
2053 pParamDirPathTxt = new wxTextCtrl(this, PARAMETER_DIALOG_DIRPATH_TEXT, wxT(""), wxPoint( 10, 259), wxSize(140, 25), 0, wxDefaultValidator, wxT("ParamDirPathTxt"));
2054 pParamSaveBtn = new wxButton(this, PARAMETER_DIALOG_SAVE, wxT("&Save"), wxPoint(310, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("ParamSaveBtn"));
2055 pParamCancelBtn = new wxButton(this, PARAMETER_DIALOG_CANCEL, wxT("C&ancel"), wxPoint(310, 66), wxSize( 70, 35), 0, wxDefaultValidator, wxT("ParamCancelBtn"));
2056
2057 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
2058 // handle all widget processing
2059 widgetPtrsSet = true;
2060
2061 saved = false;
2062 savedParamSettings = wxGetApp().params;
2063
2064 Centre(wxBOTH);
2065 PutData();
2066 ShowModal();
2067 } // CparameterDlg constructor
2068
2069
2070 void CparameterDlg::OnCloseWindow(wxCloseEvent& event)
2071 {
2072 // Put any additional checking necessary to make certain it is alright
2073 // to close the program here that is not done elsewhere
2074 if (!saved)
2075 {
2076 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);
2077
2078 if (!Ok)
2079 {
2080 event.Veto();
2081 return;
2082 }
2083
2084 wxGetApp().params = savedParamSettings;
2085 }
2086
2087 if (GetParent() != NULL)
2088 GetParent()->SetFocus();
2089
2090 while (wxIsBusy())
2091 wxEndBusyCursor();
2092
2093 Show(false);
2094 SetReturnCode(0); // added so BoundsChecker would not report use of uninitialized variable
2095
2096 this->Destroy();
2097 } // CparameterDlg::OnCloseWindow()
2098
2099
2100 void CparameterDlg::OnButton( wxCommandEvent &event )
2101 {
2102 wxWindow *win = (wxWindow*) event.GetEventObject();
2103 OnCommand( *win, event );
2104 }
2105
2106
2107 void CparameterDlg::OnCommand(wxWindow& win, wxCommandEvent& WXUNUSED(event))
2108 {
2109 wxString widgetName;
2110
2111 widgetName = win.GetName();
2112
2113 if (!widgetPtrsSet)
2114 return;
2115
2116 if (widgetName == pParamSaveBtn->GetName())
2117 {
2118 if (Save())
2119 {
2120 wxString tStr;
2121 tStr = wxT("Database parameters have been saved.");
2122 if (GetParent() != NULL) // The parameter dialog was not called during startup due to a missing cfg file
2123 tStr += wxT("\nNew parameters will take effect the next time the program is started.");
2124 wxMessageBox(tStr,wxT("Notice..."),wxOK | wxICON_INFORMATION);
2125 saved = true;
2126 Close();
2127 }
2128 return;
2129 }
2130
2131 if (widgetName == pParamCancelBtn->GetName())
2132 {
2133 Close();
2134 return;
2135 }
2136 } // CparameterDlg::OnCommand()
2137
2138
2139 bool CparameterDlg::PutData()
2140 {
2141 // Fill the data source list box
2142 FillDataSourceList();
2143
2144 // Fill in the fields from the params object
2145 if (wxGetApp().params.ODBCSource && wxStrlen(wxGetApp().params.ODBCSource))
2146 {
2147 int index = pParamODBCSourceList->FindString(wxGetApp().params.ODBCSource);
2148 if (index != wxNOT_FOUND)
2149 pParamODBCSourceList->SetSelection(index);
2150 }
2151 pParamUserNameTxt->SetValue(wxGetApp().params.UserName);
2152 pParamPasswordTxt->SetValue(wxGetApp().params.Password);
2153 pParamDirPathTxt->SetValue(wxGetApp().params.DirPath);
2154 return true;
2155 } // CparameterDlg::PutData()
2156
2157
2158 bool CparameterDlg::GetData()
2159 {
2160 wxString tStr;
2161 if (pParamODBCSourceList->GetStringSelection() != wxT(""))
2162 {
2163 tStr = pParamODBCSourceList->GetStringSelection();
2164 if (tStr.Length() > (sizeof(wxGetApp().params.ODBCSource)-1))
2165 {
2166 wxString errmsg;
2167 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());
2168 wxMessageBox(errmsg,wxT("Internal program error..."),wxOK | wxICON_EXCLAMATION);
2169 return false;
2170 }
2171 wxStrcpy(wxGetApp().params.ODBCSource, tStr);
2172 }
2173 else
2174 return false;
2175
2176 tStr = pParamUserNameTxt->GetValue();
2177 if (tStr.Length() > (sizeof(wxGetApp().params.UserName)-1))
2178 {
2179 wxString errmsg;
2180 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());
2181 wxMessageBox(errmsg,wxT("Internal program error..."),wxOK | wxICON_EXCLAMATION);
2182 return false;
2183 }
2184 wxStrcpy(wxGetApp().params.UserName, tStr);
2185
2186 tStr = pParamPasswordTxt->GetValue();
2187 if (tStr.Length() > (sizeof(wxGetApp().params.Password)-1))
2188 {
2189 wxString errmsg;
2190 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());
2191 wxMessageBox(errmsg,wxT("Internal program error..."),wxOK | wxICON_EXCLAMATION);
2192 return false;
2193 }
2194 wxStrcpy(wxGetApp().params.Password,tStr);
2195
2196 tStr = pParamDirPathTxt->GetValue();
2197 tStr.Replace(wxT("\\"),wxT("/"));
2198 if (tStr.Length() > (sizeof(wxGetApp().params.DirPath)-1))
2199 {
2200 wxString errmsg;
2201 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());
2202 wxMessageBox(errmsg,wxT("Internal program error..."),wxOK | wxICON_EXCLAMATION);
2203 return false;
2204 }
2205 wxStrcpy(wxGetApp().params.DirPath,tStr);
2206 return true;
2207 } // CparameterDlg::GetData()
2208
2209
2210 bool CparameterDlg::Save()
2211 {
2212 // Copy the current params in case user cancels changing
2213 // the params, so that we can reset them.
2214 if (!GetData())
2215 {
2216 wxGetApp().params = savedParamSettings;
2217 return false;
2218 }
2219
2220 wxGetApp().WriteParamFile(wxGetApp().params);
2221
2222 return true;
2223 } // CparameterDlg::Save()
2224
2225
2226 void CparameterDlg::FillDataSourceList()
2227 {
2228 wxChar Dsn[SQL_MAX_DSN_LENGTH + 1];
2229 wxChar DsDesc[255];
2230 wxSortedArrayString strArr;
2231
2232 while (wxDbGetDataSource(wxGetApp().DbConnectInf->GetHenv(), Dsn,
2233 SQL_MAX_DSN_LENGTH+1, DsDesc, 255))
2234 {
2235 strArr.Add(Dsn);
2236 }
2237
2238 for (size_t i=0; i < strArr.GetCount(); i++ )
2239 {
2240 pParamODBCSourceList->Append(strArr[i].c_str());
2241 }
2242
2243 } // CparameterDlg::FillDataSourceList()
2244
2245
2246 BEGIN_EVENT_TABLE(CqueryDlg, wxDialog)
2247 EVT_BUTTON(wxID_ANY, CqueryDlg::OnButton)
2248 EVT_CLOSE(CqueryDlg::OnCloseWindow)
2249 END_EVENT_TABLE()
2250
2251
2252 // CqueryDlg() constructor
2253 CqueryDlg::CqueryDlg(wxWindow *parent, wxDb *pDb, wxChar *tblName[],
2254 const wxString &pWhereArg) :
2255 wxDialog (parent, QUERY_DIALOG, wxT("Query"), wxDefaultPosition, wxSize(480, 360))
2256 {
2257 wxBeginBusyCursor();
2258
2259 colInf = 0;
2260 dbTable = 0;
2261 masterTableName = tblName[0];
2262 widgetPtrsSet = false;
2263 pDB = pDb;
2264
2265 // Initialize the WHERE clause from the string passed in
2266 pWhere = pWhereArg; // Save a pointer to the output buffer
2267 if (pWhere.Length() > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN) // Check the length of the buffer passed in
2268 {
2269 wxString s;
2270 s.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN+1);
2271 wxMessageBox(s,wxT("Error..."),wxOK | wxICON_EXCLAMATION);
2272 Close();
2273 return;
2274 }
2275
2276 pQueryCol1Msg = new wxStaticText(this, QUERY_DIALOG_COL_MSG, wxT("Column 1:"), wxPoint( 10, 10), wxSize( 69, 16), 0, wxT("QueryCol1Msg"));
2277 pQueryCol1Choice = new wxChoice(this, QUERY_DIALOG_COL_CHOICE, wxPoint( 10, 27), wxSize(250, 27), 0, 0, 0, wxDefaultValidator, wxT("QueryCol1Choice"));
2278 pQueryNotMsg = new wxStaticText(this, QUERY_DIALOG_NOT_MSG, wxT("NOT"), wxPoint(268, 10), wxDefaultSize, 0, wxT("QueryNotMsg"));
2279 pQueryNotCheck = new wxCheckBox(this, QUERY_DIALOG_NOT_CHECKBOX, wxT(""), wxPoint(275, 37), wxSize( 20, 20), 0, wxDefaultValidator, wxT("QueryNotCheck"));
2280
2281 wxString choice_strings[9];
2282 choice_strings[0] = wxT("=");
2283 choice_strings[1] = wxT("<");
2284 choice_strings[2] = wxT(">");
2285 choice_strings[3] = wxT("<=");
2286 choice_strings[4] = wxT(">=");
2287 choice_strings[5] = wxT("Begins");
2288 choice_strings[6] = wxT("Contains");
2289 choice_strings[7] = wxT("Like");
2290 choice_strings[8] = wxT("Between");
2291
2292 pQueryOperatorMsg = new wxStaticText(this, QUERY_DIALOG_OP_MSG, wxT("Operator:"), wxPoint(305, 10), wxDefaultSize, 0, wxT("QueryOperatorMsg"));
2293 pQueryOperatorChoice = new wxChoice(this, QUERY_DIALOG_OP_CHOICE, wxPoint(305, 27), wxSize( 80, 27), 9, choice_strings, 0, wxDefaultValidator, wxT("QueryOperatorChoice"));
2294 pQueryCol2Msg = new wxStaticText(this, QUERY_DIALOG_COL2_MSG, wxT("Column 2:"), wxPoint( 10, 65), wxSize( 69, 16), 0, wxT("QueryCol2Msg"));
2295 pQueryCol2Choice = new wxChoice(this, QUERY_DIALOG_COL2_CHOICE, wxPoint( 10, 82), wxSize(250, 27), 0, 0, 0, wxDefaultValidator, wxT("QueryCol2Choice"));
2296 pQuerySqlWhereMsg = new wxStaticText(this, QUERY_DIALOG_WHERE_MSG, wxT("SQL where clause:"), wxPoint( 10, 141), wxDefaultSize, 0, wxT("QuerySqlWhereMsg"));
2297 pQuerySqlWhereMtxt = new wxTextCtrl(this, QUERY_DIALOG_WHERE_TEXT, wxT(""), wxPoint( 10, 159), wxSize(377, 134), wxTE_MULTILINE, wxDefaultValidator, wxT("QuerySqlWhereMtxt"));
2298 pQueryAddBtn = new wxButton(this, QUERY_DIALOG_ADD, wxT("&Add"), wxPoint(406, 24), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryAddBtn"));
2299 pQueryAndBtn = new wxButton(this, QUERY_DIALOG_AND, wxT("A&nd"), wxPoint(406, 58), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryAndBtn"));
2300 pQueryOrBtn = new wxButton(this, QUERY_DIALOG_OR, wxT("&Or"), wxPoint(406, 92), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryOrBtn"));
2301 pQueryLParenBtn = new wxButton(this, QUERY_DIALOG_LPAREN, wxT("("), wxPoint(406, 126), wxSize( 26, 26), 0, wxDefaultValidator, wxT("QueryLParenBtn"));
2302 pQueryRParenBtn = new wxButton(this, QUERY_DIALOG_RPAREN, wxT(")"), wxPoint(436, 126), wxSize( 26, 26), 0, wxDefaultValidator, wxT("QueryRParenBtn"));
2303 pQueryDoneBtn = new wxButton(this, QUERY_DIALOG_DONE, wxT("&Done"), wxPoint(406, 185), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryDoneBtn"));
2304 pQueryClearBtn = new wxButton(this, QUERY_DIALOG_CLEAR, wxT("C&lear"), wxPoint(406, 218), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryClearBtn"));
2305 pQueryCountBtn = new wxButton(this, QUERY_DIALOG_COUNT, wxT("&Count"), wxPoint(406, 252), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryCountBtn"));
2306 pQueryValue1Msg = new wxStaticText(this, QUERY_DIALOG_VALUE1_MSG, wxT("Value:"), wxPoint(277, 66), wxDefaultSize, 0, wxT("QueryValue1Msg"));
2307 pQueryValue1Txt = new wxTextCtrl(this, QUERY_DIALOG_VALUE1_TEXT, wxT(""), wxPoint(277, 83), wxSize(108, 25), 0, wxDefaultValidator, wxT("QueryValue1Txt"));
2308 pQueryValue2Msg = new wxStaticText(this, QUERY_DIALOG_VALUE2_MSG, wxT("AND"), wxPoint(238, 126), wxDefaultSize, 0, wxT("QueryValue2Msg"));
2309 pQueryValue2Txt = new wxTextCtrl(this, QUERY_DIALOG_VALUE2_TEXT, wxT(""), wxPoint(277, 120), wxSize(108, 25), 0, wxDefaultValidator, wxT("QueryValue2Txt"));
2310 pQueryHintGrp = new wxStaticBox(this, QUERY_DIALOG_HINT_GROUP, wxT(""), wxPoint( 10, 291), wxSize(377, 40), 0, wxT("QueryHintGrp"));
2311 pQueryHintMsg = new wxStaticText(this, QUERY_DIALOG_HINT_MSG, wxT(""), wxPoint( 16, 306), wxDefaultSize, 0, wxT("QueryHintMsg"));
2312
2313 widgetPtrsSet = true;
2314 // Initialize the dialog
2315 wxString qualName;
2316 pQueryCol2Choice->Append(wxT("VALUE -->"));
2317 colInf = pDB->GetColumns(tblName);
2318
2319 if (!colInf)
2320 {
2321 wxEndBusyCursor();
2322 wxString tStr;
2323 tStr = wxT("ODBC error during GetColumns()\n\n");
2324 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
2325 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
2326 return;
2327 }
2328
2329 int i;
2330 for (i = 0; colInf[i].colName && wxStrlen(colInf[i].colName); i++)
2331 {
2332 // If there is more than one table being queried, qualify
2333 // the column names with the table name prefix.
2334 if (tblName[1] && wxStrlen(tblName[1]))
2335 {
2336 qualName.Printf(wxT("%s.%s"), colInf[i].tableName, colInf[i].colName);
2337 pQueryCol1Choice->Append(qualName);
2338 pQueryCol2Choice->Append(qualName);
2339 }
2340 else // Single table query, append just the column names
2341 {
2342 pQueryCol1Choice->Append(colInf[i].colName);
2343 pQueryCol2Choice->Append(colInf[i].colName);
2344 }
2345 }
2346
2347 pQueryCol1Choice->SetSelection(0);
2348 pQueryCol2Choice->SetSelection(0);
2349 pQueryOperatorChoice->SetSelection(0);
2350
2351 pQueryValue2Msg->Show(false);
2352 pQueryValue2Txt->Show(false);
2353
2354 pQueryHintMsg->SetLabel(langQRY_EQ);
2355
2356 pQuerySqlWhereMtxt->SetValue(pWhere.c_str());
2357
2358 wxEndBusyCursor();
2359
2360 // Display the dialog window
2361 Centre(wxBOTH);
2362 ShowModal();
2363 } // CqueryDlg() constructor
2364
2365
2366 void CqueryDlg::OnButton(wxCommandEvent &event)
2367 {
2368 wxWindow *win = (wxWindow*) event.GetEventObject();
2369 OnCommand( *win, event );
2370 } // CqueryDlg::OnButton()
2371
2372
2373 void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& WXUNUSED(event))
2374 {
2375 // Widget pointers won't be set when the dialog is constructed.
2376 // Control is passed through this function once for each widget on
2377 // a dialog as the dialog is constructed.
2378 if (!widgetPtrsSet)
2379 return;
2380
2381 wxString widgetName = win.GetName();
2382
2383 // Operator choice box
2384 if (widgetName == pQueryOperatorChoice->GetName())
2385 {
2386 // Set the help text
2387 switch((qryOp) pQueryOperatorChoice->GetSelection())
2388 {
2389 case qryOpEQ:
2390 pQueryHintMsg->SetLabel(langQRY_EQ);
2391 break;
2392 case qryOpLT:
2393 pQueryHintMsg->SetLabel(langQRY_LT);
2394 break;
2395 case qryOpGT:
2396 pQueryHintMsg->SetLabel(langQRY_GT);
2397 break;
2398 case qryOpLE:
2399 pQueryHintMsg->SetLabel(langQRY_LE);
2400 break;
2401 case qryOpGE:
2402 pQueryHintMsg->SetLabel(langQRY_GE);
2403 break;
2404 case qryOpBEGINS:
2405 pQueryHintMsg->SetLabel(langQRY_BEGINS);
2406 break;
2407 case qryOpCONTAINS:
2408 pQueryHintMsg->SetLabel(langQRY_CONTAINS);
2409 break;
2410 case qryOpLIKE:
2411 pQueryHintMsg->SetLabel(langQRY_LIKE);
2412 break;
2413 case qryOpBETWEEN:
2414 pQueryHintMsg->SetLabel(langQRY_BETWEEN);
2415 break;
2416 }
2417
2418 // Hide the value2 widget
2419 pQueryValue2Msg->Show(false); // BETWEEN will show this widget
2420 pQueryValue2Txt->Show(false); // BETWEEN will show this widget
2421
2422 // Disable the NOT operator for <, <=, >, >=
2423 switch((qryOp) pQueryOperatorChoice->GetSelection())
2424 {
2425 case qryOpLT:
2426 case qryOpGT:
2427 case qryOpLE:
2428 case qryOpGE:
2429 pQueryNotCheck->SetValue(0);
2430 pQueryNotCheck->Enable(false);
2431 break;
2432 default:
2433 pQueryNotCheck->Enable(true);
2434 break;
2435 }
2436
2437 // Manipulate the dialog to handle the selected operator
2438 switch((qryOp) pQueryOperatorChoice->GetSelection())
2439 {
2440 case qryOpEQ:
2441 case qryOpLT:
2442 case qryOpGT:
2443 case qryOpLE:
2444 case qryOpGE:
2445 pQueryCol2Choice->Enable(true);
2446 if (pQueryCol2Choice->GetSelection()) // Column name is highlighted
2447 {
2448 pQueryValue1Msg->Show(false);
2449 pQueryValue1Txt->Show(false);
2450 }
2451 else // "Value" is highlighted
2452 {
2453 pQueryValue1Msg->Show(true);
2454 pQueryValue1Txt->Show(true);
2455 pQueryValue1Txt->SetFocus();
2456 }
2457 break;
2458 case qryOpBEGINS:
2459 case qryOpCONTAINS:
2460 case qryOpLIKE:
2461 pQueryCol2Choice->SetSelection(0);
2462 pQueryCol2Choice->Enable(false);
2463 pQueryValue1Msg->Show(true);
2464 pQueryValue1Txt->Show(true);
2465 pQueryValue1Txt->SetFocus();
2466 break;
2467 case qryOpBETWEEN:
2468 pQueryCol2Choice->SetSelection(0);
2469 pQueryCol2Choice->Enable(false);
2470 pQueryValue2Msg->Show(true);
2471 pQueryValue2Txt->Show(true);
2472 pQueryValue1Msg->Show(true);
2473 pQueryValue1Txt->Show(true);
2474 pQueryValue1Txt->SetFocus();
2475 break;
2476 }
2477
2478 return;
2479
2480 } // Operator choice box
2481
2482 // Column 2 choice
2483 if (widgetName == pQueryCol2Choice->GetName())
2484 {
2485 if (pQueryCol2Choice->GetSelection()) // Column name is highlighted
2486 {
2487 pQueryValue1Msg->Show(false);
2488 pQueryValue1Txt->Show(false);
2489 }
2490 else // "Value" is highlighted
2491 {
2492 pQueryValue1Msg->Show(true);
2493 pQueryValue1Txt->Show(true);
2494 pQueryValue1Txt->SetFocus();
2495 }
2496 return;
2497 } // Column 2 choice
2498
2499 // Add button
2500 if (widgetName == pQueryAddBtn->GetName())
2501 {
2502 ProcessAddBtn();
2503 return;
2504 } // Add button
2505
2506 // And button
2507 if (widgetName == pQueryAndBtn->GetName())
2508 {
2509 AppendToWhere(wxT(" AND\n"));
2510 return;
2511 } // And button
2512
2513 // Or button
2514 if (widgetName == pQueryOrBtn->GetName())
2515 {
2516 AppendToWhere(wxT(" OR\n"));
2517 return;
2518 } // Or button
2519
2520 // Left Paren button
2521 if (widgetName == pQueryLParenBtn->GetName())
2522 {
2523 AppendToWhere(wxT("("));
2524 return;
2525 } // Left Paren button
2526
2527 // Right paren button
2528 if (widgetName == pQueryRParenBtn->GetName())
2529 {
2530 AppendToWhere(wxT(")"));
2531 return;
2532 } // Right Paren button
2533
2534 // Done button
2535 if (widgetName == pQueryDoneBtn->GetName())
2536 {
2537 // Be sure the where clause will not overflow the output buffer
2538 if (wxStrlen(pQuerySqlWhereMtxt->GetValue()) > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN)
2539 {
2540 wxString s;
2541 s.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN+1);
2542 wxMessageBox(s,wxT("Error..."),wxOK | wxICON_EXCLAMATION);
2543 return;
2544 }
2545 // Validate the where clause for things such as matching parens
2546 if (!ValidateWhereClause())
2547 return;
2548 // Copy the where clause to the output buffer and exit
2549 pWhere = pQuerySqlWhereMtxt->GetValue();
2550 Close();
2551 return;
2552 } // Done button
2553
2554 // Clear button
2555 if (widgetName == pQueryClearBtn->GetName())
2556 {
2557 bool Ok = (wxMessageBox(wxT("Are you sure you wish to clear the Query?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
2558
2559 if (Ok)
2560 pQuerySqlWhereMtxt->SetValue(wxT(""));
2561 return;
2562 } // Clear button
2563
2564 // Count button
2565 if (widgetName == pQueryCountBtn->GetName())
2566 {
2567 wxBeginBusyCursor();
2568 ProcessCountBtn();
2569 wxEndBusyCursor();
2570 return;
2571 } // Count button
2572
2573 } // CqueryDlg::OnCommand
2574
2575
2576 void CqueryDlg::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
2577 {
2578 // Clean up
2579 wxDELETEA(colInf);
2580
2581 wxDELETE(dbTable);
2582
2583 GetParent()->SetFocus();
2584 while (wxIsBusy())
2585 wxEndBusyCursor();
2586
2587 Show(false);
2588 SetReturnCode(1); // added so BoundsChecker would not report use of uninitialized variable
2589
2590 this->Destroy();
2591 } // CqueryDlg::OnCloseWindow()
2592
2593
2594 void CqueryDlg::AppendToWhere(wxChar *s)
2595 {
2596 wxString whereStr = pQuerySqlWhereMtxt->GetValue();
2597 whereStr += s;
2598 pQuerySqlWhereMtxt->SetValue(whereStr);
2599 } // CqueryDlg::AppendToWhere()
2600
2601
2602 void CqueryDlg::ProcessAddBtn()
2603 {
2604 qryOp oper = (qryOp) pQueryOperatorChoice->GetSelection();
2605
2606 // Verify that eveything is filled in correctly
2607 if (pQueryCol2Choice->GetSelection() == 0) // "Value" is selected
2608 {
2609 // Verify that value 1 is filled in
2610 if (wxStrlen(pQueryValue1Txt->GetValue()) == 0)
2611 {
2612 wxBell();
2613 pQueryValue1Txt->SetFocus();
2614 return;
2615 }
2616 // For the BETWEEN operator, value 2 must be filled in as well
2617 if (oper == qryOpBETWEEN &&
2618 wxStrlen(pQueryValue2Txt->GetValue()) == 0)
2619 {
2620 wxBell();
2621 pQueryValue2Txt->SetFocus();
2622 return;
2623 }
2624 }
2625
2626 // Build the expression and append it to the where clause window
2627 wxString s = pQueryCol1Choice->GetStringSelection();
2628
2629 if (pQueryNotCheck->GetValue() && (oper != qryOpEQ))
2630 s += wxT(" NOT");
2631
2632 switch(oper)
2633 {
2634 case qryOpEQ:
2635 if (pQueryNotCheck->GetValue()) // NOT box is checked
2636 s += wxT(" <>");
2637 else
2638 s += wxT(" =");
2639 break;
2640 case qryOpLT:
2641 s += wxT(" <");
2642 break;
2643 case qryOpGT:
2644 s += wxT(" >");
2645 break;
2646 case qryOpLE:
2647 s += wxT(" <=");
2648 break;
2649 case qryOpGE:
2650 s += wxT(" >=");
2651 break;
2652 case qryOpBEGINS:
2653 case qryOpCONTAINS:
2654 case qryOpLIKE:
2655 s += wxT(" LIKE");
2656 break;
2657 case qryOpBETWEEN:
2658 s += wxT(" BETWEEN");
2659 break;
2660 }
2661
2662 s += wxT(" ");
2663
2664 int col1Idx = pQueryCol1Choice->GetSelection();
2665
2666 bool quote = false;
2667 if (colInf[col1Idx].sqlDataType == SQL_VARCHAR ||
2668 oper == qryOpBEGINS ||
2669 oper == qryOpCONTAINS ||
2670 oper == qryOpLIKE)
2671 quote = true;
2672
2673 if (pQueryCol2Choice->GetSelection()) // Column name
2674 s += pQueryCol2Choice->GetStringSelection();
2675 else // Column 2 is a "value"
2676 {
2677 if (quote)
2678 s += wxT("'");
2679 if (oper == qryOpCONTAINS)
2680 s += wxT("%");
2681 s += pQueryValue1Txt->GetValue();
2682 if (oper == qryOpCONTAINS || oper == qryOpBEGINS)
2683 s += wxT("%");
2684 if (quote)
2685 s += wxT("'");
2686 }
2687
2688 if (oper == qryOpBETWEEN)
2689 {
2690 s += wxT(" AND ");
2691 if (quote)
2692 s += wxT("'");
2693 s += pQueryValue2Txt->GetValue();
2694 if (quote)
2695 s += wxT("'");
2696 }
2697
2698 AppendToWhere((wxChar*) (const wxChar*) s);
2699
2700 } // CqueryDlg::ProcessAddBtn()
2701
2702
2703 void CqueryDlg::ProcessCountBtn()
2704 {
2705 if (!ValidateWhereClause())
2706 return;
2707
2708 if (!dbTable) // wxDbTable object needs to be created and opened
2709 {
2710 dbTable = new wxDbTable(pDB, masterTableName, 0, wxEmptyString,
2711 !wxDB_QUERY_ONLY,
2712 wxGetApp().DbConnectInf->GetDefaultDir());
2713 if (!dbTable)
2714 {
2715 wxMessageBox(wxT("Memory allocation failed creating a wxDbTable object."),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
2716 return;
2717 }
2718 if (!dbTable->Open())
2719 {
2720 wxString tStr;
2721 tStr = wxT("ODBC error during Open()\n\n");
2722 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
2723 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
2724 return;
2725 }
2726 }
2727
2728 // Count() with WHERE clause
2729 wxString whereStr;
2730
2731 whereStr = pQuerySqlWhereMtxt->GetValue();
2732 dbTable->SetWhereClause(whereStr.c_str());
2733
2734 ULONG whereCnt = dbTable->Count();
2735
2736 // Count() of all records in the table
2737 dbTable->SetWhereClause(wxT(""));
2738 ULONG totalCnt = dbTable->Count();
2739
2740 if (whereCnt > 0 || totalCnt == 0)
2741 {
2742 wxString tStr;
2743 tStr.Printf(wxT("%lu of %lu records match the query criteria."),whereCnt,totalCnt);
2744 wxMessageBox(tStr,wxT("Notice..."),wxOK | wxICON_INFORMATION);
2745 }
2746 else
2747 {
2748 wxString tStr;
2749 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);
2750 wxMessageBox(tStr,wxT("Notice..."),wxOK | wxICON_INFORMATION);
2751 }
2752
2753 // After a wxMessageBox, the focus does not necessarily return to the
2754 // window which was the focus when the message box popped up, so return
2755 // focus to the Query dialog for certain
2756 SetFocus();
2757
2758 } // CqueryDlg::ProcessCountBtn()
2759
2760
2761 bool CqueryDlg::ValidateWhereClause()
2762 {
2763 wxString where = pQuerySqlWhereMtxt->GetValue();
2764
2765 if (where.Freq(wxT('(')) != where.Freq(wxT(')')))
2766 {
2767 wxMessageBox(wxT("There are mismatched parenthesis in the constructed where clause"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
2768 return(false);
2769 }
2770 // After a wxMessageBox, the focus does not necessarily return to the
2771 // window which was the focus when the message box popped up, so return
2772 // focus to the Query dialog for certain
2773 SetFocus();
2774
2775 return(true);
2776
2777 } // CqueryDlg::ValidateWhereClause()
2778
2779
2780
2781 void DisplayDbDiagnostics(wxDb *pDb)
2782 {
2783 wxString s, t;
2784 bool comma;
2785
2786 s = wxT("Diagnostics Output\n");
2787 s += langDBINF_DB_NAME;
2788 s += pDb->dbInf.dbmsName;
2789 s += wxT("\n");
2790
2791 s += langDBINF_DB_VER;
2792 s += pDb->dbInf.dbmsVer;
2793 s += wxT("\n");
2794
2795 s += langDBINF_DRIVER_NAME;
2796 s += pDb->dbInf.driverName;
2797 s += wxT("\n");
2798
2799 s += langDBINF_DRIVER_ODBC_VER;
2800 s += pDb->dbInf.odbcVer;
2801 s += wxT("\n");
2802
2803 s += langDBINF_DRIVER_MGR_ODBC_VER;
2804 s += pDb->dbInf.drvMgrOdbcVer;
2805 s += wxT("\n");
2806
2807 s += langDBINF_DRIVER_VER;
2808 s += pDb->dbInf.driverVer;
2809 s += wxT("\n");
2810
2811 s += langDBINF_SERVER_NAME;
2812 s += pDb->dbInf.serverName;
2813 s += wxT("\n");
2814
2815 s += langDBINF_FILENAME;
2816 s += pDb->dbInf.databaseName;
2817 s += wxT("\n");
2818
2819 s += langDBINF_OUTER_JOINS;
2820 s += pDb->dbInf.outerJoins;
2821 s += wxT("\n");
2822
2823 s += langDBINF_STORED_PROC;
2824 s += pDb->dbInf.procedureSupport;
2825 s += wxT("\n");
2826
2827 if (pDb->dbInf.maxConnections)
2828 t.sprintf(wxT("%s%d\n"), langDBINF_MAX_HDBC, pDb->dbInf.maxConnections);
2829 else
2830 t.sprintf(wxT("%s%s\n"), langDBINF_MAX_HDBC, langDBINF_UNLIMITED);
2831 s += t;
2832
2833 if (pDb->dbInf.maxStmts)
2834 t.sprintf(wxT("%s%d\n"), langDBINF_MAX_HSTMT, pDb->dbInf.maxStmts);
2835 else
2836 t.sprintf(wxT("%s%s\n"), langDBINF_MAX_HSTMT, langDBINF_UNLIMITED);
2837 s += t;
2838
2839 s += langDBINF_API_LVL;
2840 switch(pDb->dbInf.apiConfLvl)
2841 {
2842 case SQL_OAC_NONE: s += langDBINF_NONE; break;
2843 case SQL_OAC_LEVEL1: s += langDBINF_LEVEL1; break;
2844 case SQL_OAC_LEVEL2: s += langDBINF_LEVEL2; break;
2845 }
2846 s += wxT("\n");
2847
2848 s += langDBINF_CLI_LVL;
2849 switch(pDb->dbInf.cliConfLvl)
2850 {
2851 case SQL_OSCC_NOT_COMPLIANT: s += langDBINF_NOT_COMPLIANT; break;
2852 case SQL_OSCC_COMPLIANT: s += langDBINF_COMPLIANT; break;
2853 }
2854 s += wxT("\n");
2855
2856 s += langDBINF_SQL_LVL;
2857 switch(pDb->dbInf.sqlConfLvl)
2858 {
2859 case SQL_OSC_MINIMUM: s += langDBINF_MIN_GRAMMAR; break;
2860 case SQL_OSC_CORE: s += langDBINF_CORE_GRAMMAR; break;
2861 case SQL_OSC_EXTENDED: s += langDBINF_EXT_GRAMMAR; break;
2862 }
2863 s += wxT("\n");
2864
2865 s += langDBINF_COMMIT_BEHAVIOR;
2866 switch(pDb->dbInf.cursorCommitBehavior)
2867 {
2868 case SQL_CB_DELETE: s += langDBINF_DELETE_CURSORS; break;
2869 case SQL_CB_CLOSE: s += langDBINF_CLOSE_CURSORS; break;
2870 case SQL_CB_PRESERVE: s += langDBINF_PRESERVE_CURSORS; break;
2871 }
2872 s += wxT("\n");
2873
2874 s += langDBINF_ROLLBACK_BEHAVIOR;
2875 switch(pDb->dbInf.cursorRollbackBehavior)
2876 {
2877 case SQL_CB_DELETE: s += langDBINF_DELETE_CURSORS; break;
2878 case SQL_CB_CLOSE: s += langDBINF_CLOSE_CURSORS; break;
2879 case SQL_CB_PRESERVE: s += langDBINF_PRESERVE_CURSORS; break;
2880 }
2881 s += wxT("\n");
2882
2883 s += langDBINF_SUPP_NOT_NULL;
2884 switch(pDb->dbInf.supportNotNullClause)
2885 {
2886 case SQL_NNC_NULL: s += langNO; break;
2887 case SQL_NNC_NON_NULL: s += langYES; break;
2888 }
2889 s += wxT("\n");
2890
2891 s += langDBINF_SUPP_IEF;
2892 s += pDb->dbInf.supportIEF;
2893 s += wxT("\n");
2894
2895 // DEFAULT setting for "Transaction Isolation Level"
2896 s += langDBINF_TXN_ISOLATION;
2897 switch(pDb->dbInf.txnIsolation)
2898 {
2899 case SQL_TXN_READ_UNCOMMITTED: s += langDBINF_READ_UNCOMMITTED; break;
2900 case SQL_TXN_READ_COMMITTED: s += langDBINF_READ_COMMITTED; break;
2901 case SQL_TXN_REPEATABLE_READ: s += langDBINF_REPEATABLE_READ; break;
2902 case SQL_TXN_SERIALIZABLE: s += langDBINF_SERIALIZABLE; break;
2903 #ifdef ODBC_V20
2904 case SQL_TXN_VERSIONING: s += langDBINF_VERSIONING; break;
2905 #endif
2906 }
2907 s += wxT("\n");
2908
2909 // CURRENT setting for "Transaction Isolation Level"
2910 long txnIsoLvl;
2911 s += langDBINF_TXN_ISOLATION_CURR;
2912 if (SQLGetConnectOption(pDb->GetHDBC(),SQL_TXN_ISOLATION,&txnIsoLvl) == SQL_SUCCESS)
2913 {
2914 switch(txnIsoLvl)
2915 {
2916 case SQL_TXN_READ_UNCOMMITTED: s += langDBINF_READ_UNCOMMITTED; break;
2917 case SQL_TXN_READ_COMMITTED: s += langDBINF_READ_COMMITTED; break;
2918 case SQL_TXN_REPEATABLE_READ: s += langDBINF_REPEATABLE_READ; break;
2919 case SQL_TXN_SERIALIZABLE: s += langDBINF_SERIALIZABLE; break;
2920 #ifdef ODBC_V20
2921 case SQL_TXN_VERSIONING: s += langDBINF_VERSIONING; break;
2922 #endif
2923 }
2924 }
2925 s += wxT("\n");
2926
2927 #ifdef __VMS__
2928 #pragma message disable incboodep
2929 #endif
2930 comma = false;
2931 s += langDBINF_TXN_ISOLATION_OPTS;
2932 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_READ_UNCOMMITTED)
2933 {s += langDBINF_READ_UNCOMMITTED; comma++;}
2934 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_READ_COMMITTED)
2935 {if (comma++) s += wxT(", "); s += langDBINF_READ_COMMITTED;}
2936 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_REPEATABLE_READ)
2937 {if (comma++) s += wxT(", "); s += langDBINF_REPEATABLE_READ;}
2938 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_SERIALIZABLE)
2939 {if (comma++) s += wxT(", "); s += langDBINF_SERIALIZABLE;}
2940 #ifdef ODBC_V20
2941 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_VERSIONING)
2942 {if (comma++) s += wxT(", "); s += langDBINF_VERSIONING;}
2943 #endif
2944 s += wxT("\n");
2945
2946 comma = false;
2947 s += langDBINF_FETCH_DIRS;
2948 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_NEXT)
2949 {s += langDBINF_NEXT; comma++;}
2950 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_PRIOR)
2951 {if (comma++) s += wxT(", "); s += langDBINF_PREV;}
2952 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_FIRST)
2953 {if (comma++) s += wxT(", "); s += langDBINF_FIRST;}
2954 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_LAST)
2955 {if (comma++) s += wxT(", "); s += langDBINF_LAST;}
2956 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_ABSOLUTE)
2957 {if (comma++) s += wxT(", "); s += langDBINF_ABSOLUTE;}
2958 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_RELATIVE)
2959 {if (comma++) s += wxT(", "); s += langDBINF_RELATIVE;}
2960 #ifdef ODBC_V20
2961 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_RESUME)
2962 {if (comma++) s += wxT(", "); s += langDBINF_RESUME;}
2963 #endif
2964 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_BOOKMARK)
2965 {if (comma++) s += wxT(", "); s += langDBINF_BOOKMARK;}
2966 s += wxT("\n");
2967
2968 comma = false;
2969 s += langDBINF_LOCK_TYPES;
2970 if (pDb->dbInf.lockTypes & SQL_LCK_NO_CHANGE)
2971 {s += langDBINF_NO_CHANGE; comma++;}
2972 if (pDb->dbInf.lockTypes & SQL_LCK_EXCLUSIVE)
2973 {if (comma++) s += wxT(", "); s += langDBINF_EXCLUSIVE;}
2974 if (pDb->dbInf.lockTypes & SQL_LCK_UNLOCK)
2975 {if (comma++) s += wxT(", "); s += langDBINF_UNLOCK;}
2976 s += wxT("\n");
2977
2978 comma = false;
2979 s += langDBINF_POS_OPERS;
2980 if (pDb->dbInf.posOperations & SQL_POS_POSITION)
2981 {s += langDBINF_POSITION; comma++;}
2982 if (pDb->dbInf.posOperations & SQL_POS_REFRESH)
2983 {if (comma++) s += wxT(", "); s += langDBINF_REFRESH;}
2984 if (pDb->dbInf.posOperations & SQL_POS_UPDATE)
2985 {if (comma++) s += wxT(", "); s += langDBINF_UPD;}
2986 if (pDb->dbInf.posOperations & SQL_POS_DELETE)
2987 {if (comma++) s += wxT(", "); s += langDBINF_DEL;}
2988 if (pDb->dbInf.posOperations & SQL_POS_ADD)
2989 {if (comma++) s += wxT(", "); s += langDBINF_ADD;}
2990 s += wxT("\n");
2991
2992 comma = false;
2993 s += langDBINF_POS_STMTS;
2994 if (pDb->dbInf.posStmts & SQL_PS_POSITIONED_DELETE)
2995 {s += langDBINF_POS_DEL; comma++;}
2996 if (pDb->dbInf.posStmts & SQL_PS_POSITIONED_UPDATE)
2997 {if (comma++) s += wxT(", "); s += langDBINF_POS_UPD;}
2998 if (pDb->dbInf.posStmts & SQL_PS_SELECT_FOR_UPDATE)
2999 {if (comma++) s += wxT(", "); s += langDBINF_SELECT_FOR_UPD;}
3000 s += wxT("\n");
3001
3002 comma = false;
3003 s += langDBINF_SCROLL_CONCURR;
3004 if (pDb->dbInf.scrollConcurrency & SQL_SCCO_READ_ONLY)
3005 {s += langDBINF_READ_ONLY; comma++;}
3006 if (pDb->dbInf.scrollConcurrency & SQL_SCCO_LOCK)
3007 {if (comma++) s += wxT(", "); s += langDBINF_LOCK;}
3008 if (pDb->dbInf.scrollConcurrency & SQL_SCCO_OPT_ROWVER)
3009 {if (comma++) s += wxT(", "); s += langDBINF_OPT_ROWVER;}
3010 if (pDb->dbInf.scrollConcurrency & SQL_SCCO_OPT_VALUES)
3011 {if (comma++) s += wxT(", "); s += langDBINF_OPT_VALUES;}
3012 s += wxT("\n");
3013
3014 comma = false;
3015 s += langDBINF_SCROLL_OPTS;
3016 if (pDb->dbInf.scrollOptions & SQL_SO_FORWARD_ONLY)
3017 {s += langDBINF_FWD_ONLY; comma++;}
3018 if (pDb->dbInf.scrollOptions & SQL_SO_STATIC)
3019 {if (comma++) s += wxT(", "); s += langDBINF_STATIC;}
3020 if (pDb->dbInf.scrollOptions & SQL_SO_KEYSET_DRIVEN)
3021 {if (comma++) s += wxT(", "); s += langDBINF_KEYSET_DRIVEN;}
3022 if (pDb->dbInf.scrollOptions & SQL_SO_DYNAMIC)
3023 {if (comma++) s += wxT(", "); s += langDBINF_DYNAMIC;}
3024 if (pDb->dbInf.scrollOptions & SQL_SO_MIXED)
3025 {if (comma++) s += wxT(", "); s += langDBINF_MIXED;}
3026 s += wxT("\n");
3027
3028 comma = false;
3029 s += langDBINF_STATIC_SENS;
3030 if (pDb->dbInf.staticSensitivity & SQL_SS_ADDITIONS)
3031 {s += langDBINF_ADDITIONS; comma++;}
3032 if (pDb->dbInf.staticSensitivity & SQL_SS_DELETIONS)
3033 {if (comma++) s += wxT(", "); s += langDBINF_DELETIONS;}
3034 if (pDb->dbInf.staticSensitivity & SQL_SS_UPDATES)
3035 {if (comma++) s += wxT(", "); s += langDBINF_UPDATES;}
3036 s += wxT("\n");
3037 #ifdef __VMS__
3038 #pragma message enable incboodep
3039 #endif
3040
3041
3042 s += langDBINF_TXN_CAPABLE;
3043 switch(pDb->dbInf.txnCapable)
3044 {
3045 case SQL_TC_NONE: s += langNO; break;
3046 case SQL_TC_DML: s += langDBINF_DML_ONLY; break;
3047 case SQL_TC_DDL_COMMIT: s += langDBINF_DDL_COMMIT; break;
3048 case SQL_TC_DDL_IGNORE: s += langDBINF_DDL_IGNORE; break;
3049 case SQL_TC_ALL: s += langDBINF_DDL_AND_DML; break;
3050 }
3051 s += wxT("\n");
3052
3053 t.sprintf(wxT("%s%lu\n"), langDBINF_LOGIN_TIMEOUT, pDb->dbInf.loginTimeout);
3054 s += t;
3055
3056 // Oracle specific information
3057 if (pDb->Dbms() == dbmsORACLE)
3058 {
3059 s += wxT("\n");
3060 s += langDBINF_ORACLE_BANNER;
3061 s += wxT("\n");
3062
3063 // Oracle cache hit ratio
3064 SDWORD cb;
3065 ULONG dbBlockGets;
3066 pDb->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'db block gets'"));
3067 pDb->GetNext();
3068 if (pDb->GetData(1, SQL_C_ULONG, &dbBlockGets, 0, &cb))
3069 {
3070 t.sprintf(wxT("%s: %lu\n"), langDBINF_DB_BLOCK_GETS, dbBlockGets);
3071 s += t;
3072 }
3073
3074 ULONG consistentGets;
3075 pDb->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'consistent gets'"));
3076 pDb->GetNext();
3077 if (pDb->GetData(1, SQL_C_ULONG, &consistentGets, 0, &cb))
3078 {
3079 t.sprintf(wxT("%s: %lu\n"), langDBINF_CONSISTENT_GETS, consistentGets);
3080 s += t;
3081 }
3082
3083 ULONG physReads;
3084 pDb->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'physical reads'"));
3085 pDb->GetNext();
3086 if (pDb->GetData(1, SQL_C_ULONG, &physReads, 0, &cb))
3087 {
3088 t.sprintf(wxT("%s: %lu\n"), langDBINF_PHYSICAL_READS, physReads);
3089 s += t;
3090 }
3091
3092 ULONG hitRatio = (ULONG)((1.00 - ((float)physReads / (float)(dbBlockGets + consistentGets))) * 100.00);
3093 t.sprintf(wxT("*** %s: %lu%%\n"), langDBINF_CACHE_HIT_RATIO, hitRatio);
3094 s += t;
3095
3096 // Tablespace information
3097 s += wxT("\n");
3098 s += langDBINF_TABLESPACE_IO;
3099 s += wxT("\n");
3100 ULONG physWrites;
3101 char tablespaceName[257];
3102 pDb->ExecSql(wxT("SELECT NAME,PHYRDS,PHYWRTS FROM V$DATAFILE, V$FILESTAT WHERE V$DATAFILE.FILE# = V$FILESTAT.FILE#"));
3103 while (pDb->GetNext())
3104 {
3105 pDb->GetData(1, SQL_C_CHAR, tablespaceName, 257, &cb);
3106 pDb->GetData(2, SQL_C_ULONG, &physReads, 0, &cb);
3107 pDb->GetData(3, SQL_C_ULONG, &physWrites, 0, &cb);
3108 t.sprintf(wxT("%s\n\t%s: %lu\t%s: %lu\n"), tablespaceName,
3109 langDBINF_PHYSICAL_READS, physReads, langDBINF_PHYSICAL_WRITES, physWrites);
3110 s += t;
3111 }
3112
3113 s += wxT("\n");
3114 }
3115
3116 s += wxT("End of Diagnostics\n");
3117 wxLogMessage(s);
3118
3119 } // DisplayDbDiagnostics()
3120
3121 #if wxUSE_GRID
3122
3123 BEGIN_EVENT_TABLE(DbGridFrame, wxFrame)
3124 // EVT_CLOSE(DbGridFrame::OnCloseWindow)
3125 END_EVENT_TABLE()
3126
3127
3128 DbGridFrame::DbGridFrame(wxWindow *parent)
3129 : wxFrame (parent, wxID_ANY, wxT("Database Table"),
3130 wxDefaultPosition, wxSize(400, 325))
3131 {
3132 initialized = false;
3133 }
3134
3135
3136 void DbGridFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
3137 {
3138 this->Destroy();
3139 }
3140
3141
3142 bool DbGridFrame::Initialize()
3143 {
3144 wxGrid *grid = new wxGrid(this, wxID_ANY, wxDefaultPosition);
3145
3146 grid->RegisterDataType(wxGRID_VALUE_DATETIME,
3147 new wxGridCellDateTimeRenderer(wxT("%d %b %Y")),
3148 new wxGridCellTextEditor);
3149 #ifdef CHOICEINT
3150 grid->RegisterDataType(wxGRID_VALUE_CHOICEINT,
3151 new wxGridCellEnumRenderer,
3152 new wxGridCellEnumEditor);
3153
3154 wxString NativeLangChoice( wxString::Format(wxT("%s:%s,%s,%s,%s,%s"),wxGRID_VALUE_CHOICEINT,
3155 wxT("English"),
3156 wxT("French"),
3157 wxT("German"),
3158 wxT("Spanish"),
3159 wxT("Other") ));
3160 #endif
3161
3162 // Columns must match the sequence specified in SetColDef() calls
3163 wxDbGridColInfo* cols =
3164 new wxDbGridColInfo( 0,wxGRID_VALUE_STRING,wxT("Name"),
3165 new wxDbGridColInfo( 1,wxGRID_VALUE_STRING,wxT("Address 1"),
3166 new wxDbGridColInfo( 2,wxGRID_VALUE_STRING,wxT("Address 2"),
3167 new wxDbGridColInfo( 3,wxGRID_VALUE_STRING,wxT("City"),
3168 new wxDbGridColInfo( 4,wxGRID_VALUE_STRING,wxT("State"),
3169 new wxDbGridColInfo( 5,wxGRID_VALUE_STRING,wxT("PostCode"),
3170 new wxDbGridColInfo( 6,wxGRID_VALUE_STRING,wxT("Country"),
3171 new wxDbGridColInfo( 7,wxGRID_VALUE_DBAUTO,wxT("Join Date"),
3172 new wxDbGridColInfo( 8,wxGRID_VALUE_BOOL, wxT("Developer"),
3173 new wxDbGridColInfo( 9,wxGRID_VALUE_NUMBER,wxT("Contributions"),
3174 new wxDbGridColInfo(10,wxGRID_VALUE_NUMBER,wxT("Lines Of Code"),
3175 #ifdef CHOICEINT
3176 new wxDbGridColInfo(11,NativeLangChoice, wxT("Native Language"),NULL))))))))))));
3177 #else
3178 new wxDbGridColInfo(11,wxGRID_VALUE_NUMBER,wxT("Native Language"),NULL))))))))))));
3179 #endif
3180
3181 Ccontact *Contact = new Ccontact();
3182 //wxGetApp().Contact
3183
3184 if (!Contact)
3185 {
3186 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"), wxT("Error..."), wxOK | wxICON_EXCLAMATION);
3187 return false;
3188 }
3189
3190 if (!Contact->Open())
3191 {
3192 if (Contact->GetDb()->TableExists(CONTACT_TABLE_NAME, Contact->GetDb()->GetUsername(),
3193 wxGetApp().DbConnectInf->GetDefaultDir()))
3194 {
3195 wxString tStr;
3196 tStr.Printf(wxT("Unable to open the table '%s'.\n\n"),CONTACT_TABLE_NAME);
3197 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
3198 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
3199 }
3200
3201 return false;
3202 }
3203
3204 // Execute the following query using the cursor designated
3205 // for full table query
3206 Contact->SetRowMode(wxDbTable::WX_ROW_MODE_QUERY);
3207
3208 if (!Contact->Query())
3209 {
3210 wxString tStr;
3211 tStr = wxT("ODBC error during Query()\n\n");
3212 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
3213 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
3214 return false;
3215 }
3216
3217 // No data has been read in from the database yet, so
3218 // we need to initialize the data members to valid values
3219 // so Fit() can correctly size the grid
3220 Contact->Initialize();
3221
3222 wxDbGridTableBase* db = new wxDbGridTableBase(Contact, cols, wxUSE_QUERY, true);
3223
3224 delete cols;
3225
3226 grid->SetTable(db,true);
3227 grid->SetMargins(0, 0);
3228
3229 grid->Fit();
3230 wxSize size = grid->GetSize();
3231 size.x += 10;
3232 size.y += 10;
3233 SetClientSize(size);
3234 initialized = true;
3235 return true;
3236 } // DbGridFrame::Initialize()
3237
3238 #endif // #if wxUSE_GRID
3239
3240 /*
3241 TEST CODE FOR TESTING THE wxDbCreateDataSource() FUNCTION
3242
3243 int result = 0;
3244 result = wxDbCreateDataSource(wxT("Microsoft Access Driver (*.mdb)"),wxT("GLT-TEST2"),wxT("GLT-Descrip"),false,wxT(""),this);
3245 if (!result)
3246 {
3247 // check for errors caused by ConfigDSN based functions
3248 DWORD retcode = 0;
3249 WORD cb;
3250 wxChar errMsg[500+1];
3251 errMsg[0] = wxT('\0');
3252
3253 SQLInstallerError(1,&retcode,errMsg,500,&cb);
3254
3255 wxMessageBox(wxT("FAILED creating data source"),wxT("FAILED"));
3256 }
3257 else
3258 wxMessageBox(wxT("SUCCEEDED creating data source"),wxT("SUCCESS"));
3259 */
3260
3261