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