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