]> git.saurik.com Git - wxWidgets.git/blame - samples/db/dbtest.cpp
OGL typemap and OOR fixes
[wxWidgets.git] / samples / db / dbtest.cpp
CommitLineData
108106cf
JS
1///////////////////////////////////////////////////////////////////////////////
2// Name: dbtest.cpp
3// Purpose: wxWindows database demo app
4// Author: George Tasker
5// Modified by:
6// Created: 1998
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Remstar International, Inc.
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12/*
e70e8f4c 13 * SYNOPSIS START
108106cf 14
e70e8f4c
GT
15 This sample program demonstrates the cross-platform ODBC database classes
16 donated by the development team at Remstar International.
108106cf 17
e70e8f4c 18 The table this sample is based on is developer contact table, and shows
f6bcfd97 19 some of the simple uses of the database classes wxDb and wxDbTable.
108106cf 20
e70e8f4c 21 * SYNOPSIS END
108106cf
JS
22 */
23
24#ifdef __GNUG__
25#pragma implementation "dbtest.h"
26#endif
27
28#include "wx/wxprec.h"
29
30#ifdef __BORLANDC__
31#pragma hdrstop
32#endif //__BORLANDC__
33
34#ifndef WX_PRECOMP
fb86524f 35#include "wx/wx.h"
108106cf
JS
36#endif //WX_PRECOMP
37
52ad8c7d 38#if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMAC__)
7e616b10
RR
39#include "db.xpm"
40#endif
41
5b077d48 42#include <stdio.h> /* Included strictly for reading the text file with the database parameters */
108106cf 43
fb86524f
GD
44//#include "wx/db.h" /* Required in the file which will get the data source connection */
45//#include "wx/dbtable.h" /* Has the wxDbTable object from which all data objects will inherit their data table functionality */
108106cf 46
3fe813a9 47//extern wxDbList WXDLLEXPORT *PtrBegDbList; /* from db.cpp, used in getting back error results from db connections */
108106cf 48
f21b2fd8 49#if wxUSE_NEW_GRID
fb86524f
GD
50#include "wx/grid.h"
51#include "wx/generic/gridctrl.h"
52#include "wx/dbgrid.h"
f21b2fd8
GT
53
54#define CHOICEINT
55#endif
56
5b077d48
RR
57#include "dbtest.h" /* Header file for this demonstration program */
58#include "listdb.h" /* Code to support the "Lookup" button on the editor dialog */
1fc5dd6f
JS
59
60IMPLEMENT_APP(DatabaseDemoApp)
61
049977d0
GT
62extern wxChar ListDB_Selection[]; /* Used to return the first column value for the selected line from the listDB routines */
63extern wxChar ListDB_Selection2[]; /* Used to return the second column value for the selected line from the listDB routines */
108106cf 64
5d59e67a
GT
65
66#if !wxUSE_ODBC
67 #error Sample cannot be compiled unless setup.h has wxUSE_ODBC set to 1
68#endif
69
70
aaf0836c 71bool DataTypeSupported(wxDb *pDb, SWORD datatype, wxString *nativeDataTypeName)
3fe813a9
GT
72{
73 wxDbSqlTypeInfo sqlTypeInfo;
74
a4054ad1 75 bool breakpoint = FALSE;
3fe813a9 76
aaf0836c 77 *nativeDataTypeName = wxEmptyString;
3fe813a9 78 if (pDb->GetDataTypeInfo(datatype, sqlTypeInfo))
aaf0836c
GT
79 {
80 *nativeDataTypeName = sqlTypeInfo.TypeName;
a4054ad1 81 breakpoint = TRUE;
aaf0836c 82 }
3fe813a9
GT
83
84 return breakpoint;
85
86} // GetDataTypesSupported();
87
88
89
90void CheckSupportForAllDataTypes(wxDb *pDb)
91{
aaf0836c
GT
92 wxString nativeDataTypeName;
93
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
JS
98 nativeDataTypeName = wxT("SQL_C_BINARY (") + nativeDataTypeName;
99 nativeDataTypeName += wxT(")");
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
JS
106 nativeDataTypeName = wxT("SQL_C_BIT (") + nativeDataTypeName;
107 nativeDataTypeName += wxT(")");
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
JS
114 nativeDataTypeName = wxT("SQL_C_BOOKMARK (") + nativeDataTypeName;
115 nativeDataTypeName += wxT(")");
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
JS
122 nativeDataTypeName = wxT("SQL_C_CHAR (") + nativeDataTypeName;
123 nativeDataTypeName += wxT(")");
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
JS
130 nativeDataTypeName = wxT("SQL_C_DATE (") + nativeDataTypeName;
131 nativeDataTypeName += wxT(")");
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
JS
138 nativeDataTypeName = wxT("SQL_C_DEFAULT (") + nativeDataTypeName;
139 nativeDataTypeName += wxT(")");
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
JS
146 nativeDataTypeName = wxT("SQL_C_DOUBLE (") + nativeDataTypeName;
147 nativeDataTypeName += wxT(")");
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
JS
154 nativeDataTypeName = wxT("SQL_C_FLOAT (") + nativeDataTypeName;
155 nativeDataTypeName += wxT(")");
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
JS
162 nativeDataTypeName = wxT("SQL_C_GUID (") + nativeDataTypeName;
163 nativeDataTypeName += wxT(")");
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
JS
170 nativeDataTypeName = wxT("SQL_C_INTERVAL_DAY (") + nativeDataTypeName;
171 nativeDataTypeName += wxT(")");
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
JS
178 nativeDataTypeName = wxT("SQL_C_INTERVAL_DAY_TO_HOUR (") + nativeDataTypeName;
179 nativeDataTypeName += wxT(")");
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
JS
186 nativeDataTypeName = wxT("SQL_C_INTERVAL_DAY_TO_MINUTE (") + nativeDataTypeName;
187 nativeDataTypeName += wxT(")");
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
JS
194 nativeDataTypeName = wxT("SQL_C_INTERVAL_DAY_TO_SECOND (") + nativeDataTypeName;
195 nativeDataTypeName += wxT(")");
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
JS
202 nativeDataTypeName = wxT("SQL_C_INTERVAL_HOUR (") + nativeDataTypeName;
203 nativeDataTypeName += wxT(")");
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
JS
210 nativeDataTypeName = wxT("SQL_C_INTERVAL_HOUR_TO_MINUTE (") + nativeDataTypeName;
211 nativeDataTypeName += wxT(")");
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
JS
218 nativeDataTypeName = wxT("SQL_C_INTERVAL_HOUR_TO_SECOND (") + nativeDataTypeName;
219 nativeDataTypeName += wxT(")");
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
JS
226 nativeDataTypeName = wxT("SQL_C_INTERVAL_MINUTE (") + nativeDataTypeName;
227 nativeDataTypeName += wxT(")");
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
JS
234 nativeDataTypeName = wxT("SQL_C_INTERVAL_MINUTE_TO_SECOND (") + nativeDataTypeName;
235 nativeDataTypeName += wxT(")");
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
JS
242 nativeDataTypeName = wxT("SQL_C_INTERVAL_MONTH (") + nativeDataTypeName;
243 nativeDataTypeName += wxT(")");
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
JS
250 nativeDataTypeName = wxT("SQL_C_INTERVAL_SECOND (") + nativeDataTypeName;
251 nativeDataTypeName += wxT(")");
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
JS
258 nativeDataTypeName = wxT("SQL_C_INTERVAL_YEAR (") + nativeDataTypeName;
259 nativeDataTypeName += wxT(")");
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
JS
266 nativeDataTypeName = wxT("SQL_C_INTERVAL_YEAR_TO_MONTH (") + nativeDataTypeName;
267 nativeDataTypeName += wxT(")");
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
JS
274 nativeDataTypeName = wxT("SQL_C_LONG (") + nativeDataTypeName;
275 nativeDataTypeName += wxT(")");
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
JS
282 nativeDataTypeName = wxT("SQL_C_NUMERIC (") + nativeDataTypeName;
283 nativeDataTypeName += wxT(")");
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
JS
290 nativeDataTypeName = wxT("SQL_C_SBIGINT (") + nativeDataTypeName;
291 nativeDataTypeName += wxT(")");
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
JS
298 nativeDataTypeName = wxT("SQL_C_SHORT (") + nativeDataTypeName;
299 nativeDataTypeName += wxT(")");
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
JS
306 nativeDataTypeName = wxT("SQL_C_SLONG (") + nativeDataTypeName;
307 nativeDataTypeName += wxT(")");
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
JS
314 nativeDataTypeName = wxT("SQL_C_SSHORT (") + nativeDataTypeName;
315 nativeDataTypeName += wxT(")");
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
JS
322 nativeDataTypeName = wxT("SQL_C_STINYINT (") + nativeDataTypeName;
323 nativeDataTypeName += wxT(")");
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
JS
330 nativeDataTypeName = wxT("SQL_C_TIME (") + nativeDataTypeName;
331 nativeDataTypeName += wxT(")");
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
JS
338 nativeDataTypeName = wxT("SQL_C_TIMESTAMP (") + nativeDataTypeName;
339 nativeDataTypeName += wxT(")");
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
JS
346 nativeDataTypeName = wxT("SQL_C_TINYINT (") + nativeDataTypeName;
347 nativeDataTypeName += wxT(")");
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
JS
354 nativeDataTypeName = wxT("SQL_C_TYPE_DATE (") + nativeDataTypeName;
355 nativeDataTypeName += wxT(")");
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
JS
362 nativeDataTypeName = wxT("SQL_C_TYPE_TIME (") + nativeDataTypeName;
363 nativeDataTypeName += wxT(")");
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
JS
370 nativeDataTypeName = wxT("SQL_C_TYPE_TIMESTAMP (") + nativeDataTypeName;
371 nativeDataTypeName += wxT(")");
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
JS
378 nativeDataTypeName = wxT("SQL_C_UBIGINT (") + nativeDataTypeName;
379 nativeDataTypeName += wxT(")");
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
JS
386 nativeDataTypeName = wxT("SQL_C_ULONG (") + nativeDataTypeName;
387 nativeDataTypeName += wxT(")");
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
JS
394 nativeDataTypeName = wxT("SQL_C_USHORT (") + nativeDataTypeName;
395 nativeDataTypeName += wxT(")");
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
JS
402 nativeDataTypeName = wxT("SQL_C_UTINYINT (") + nativeDataTypeName;
403 nativeDataTypeName += wxT(")");
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
JS
410 nativeDataTypeName = wxT("SQL_C_VARBOOKMARK (") + nativeDataTypeName;
411 nativeDataTypeName += wxT(")");
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
JS
420 nativeDataTypeName = wxT("SQL_DATE (") + nativeDataTypeName;
421 nativeDataTypeName += wxT(")");
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
JS
428 nativeDataTypeName = wxT("SQL_INTERVAL (") + nativeDataTypeName;
429 nativeDataTypeName += wxT(")");
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
JS
436 nativeDataTypeName = wxT("SQL_TIME (") + nativeDataTypeName;
437 nativeDataTypeName += wxT(")");
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
JS
444 nativeDataTypeName = wxT("SQL_TIMESTAMP (") + nativeDataTypeName;
445 nativeDataTypeName += wxT(")");
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
JS
452 nativeDataTypeName = wxT("SQL_LONGVARCHAR (") + nativeDataTypeName;
453 nativeDataTypeName += wxT(")");
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
JS
460 nativeDataTypeName = wxT("SQL_BINARY (") + nativeDataTypeName;
461 nativeDataTypeName += wxT(")");
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
JS
468 nativeDataTypeName = wxT("SQL_VARBINARY (") + nativeDataTypeName;
469 nativeDataTypeName += wxT(")");
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
JS
476 nativeDataTypeName = wxT("SQL_LOGVARBINARY (") + nativeDataTypeName;
477 nativeDataTypeName += wxT(")");
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
JS
484 nativeDataTypeName = wxT("SQL_BIGINT (") + nativeDataTypeName;
485 nativeDataTypeName += wxT(")");
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
JS
492 nativeDataTypeName = wxT("SQL_TINYINT (") + nativeDataTypeName;
493 nativeDataTypeName += wxT(")");
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
JS
500 nativeDataTypeName = wxT("SQL_BIT (") + nativeDataTypeName;
501 nativeDataTypeName += wxT(")");
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
JS
508 nativeDataTypeName = wxT("SQL_GUID (") + nativeDataTypeName;
509 nativeDataTypeName += wxT(")");
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
JS
517 nativeDataTypeName = wxT("SQL_CHAR (") + nativeDataTypeName;
518 nativeDataTypeName += wxT(")");
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
JS
525 nativeDataTypeName = wxT("SQL_INTEGER (") + nativeDataTypeName;
526 nativeDataTypeName += wxT(")");
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
JS
533 nativeDataTypeName = wxT("SQL_SAMLLINT (") + nativeDataTypeName;
534 nativeDataTypeName += wxT(")");
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
JS
541 nativeDataTypeName = wxT("SQL_REAL (") + nativeDataTypeName;
542 nativeDataTypeName += wxT(")");
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
JS
549 nativeDataTypeName = wxT("SQL_DOUBLE (") + nativeDataTypeName;
550 nativeDataTypeName += wxT(")");
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
JS
557 nativeDataTypeName = wxT("SQL_NUMERIC (") + nativeDataTypeName;
558 nativeDataTypeName += wxT(")");
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
JS
565 nativeDataTypeName = wxT("SQL_DATE (") + nativeDataTypeName;
566 nativeDataTypeName += wxT(")");
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
JS
573 nativeDataTypeName = wxT("SQL_TIME (") + nativeDataTypeName;
574 nativeDataTypeName += wxT(")");
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
JS
581 nativeDataTypeName = wxT("SQL_TIMESTAMP (") + nativeDataTypeName;
582 nativeDataTypeName += wxT(")");
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
JS
589 nativeDataTypeName = wxT("SQL_VARCHAR (") + nativeDataTypeName;
590 nativeDataTypeName += wxT(")");
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
JS
599 nativeDataTypeName = wxT("SQL_C_TCHAR (") + nativeDataTypeName;
600 nativeDataTypeName += wxT(")");
aaf0836c
GT
601 wxLogMessage(nativeDataTypeName);
602 }
3fe813a9 603#endif
3f030b48 604
74de91cc 605 wxLogMessage(wxT("\n"));
3fe813a9
GT
606} // CheckSupportForAllDataTypes()
607
608
1fc5dd6f 609bool DatabaseDemoApp::OnInit()
108106cf 610{
ea24eeb2
GT
611 DbConnectInf = NULL;
612 Contact = NULL;
049977d0 613
e70e8f4c 614 // Create the main frame window
94613352 615 DemoFrame = new DatabaseDemoFrame(NULL, wxT("wxWindows Database Demo"), wxPoint(50, 50), wxSize(537, 480));
e70e8f4c
GT
616
617 // Give it an icon
618 DemoFrame->SetIcon(wxICON(db));
619
620 // Make a menubar
621 wxMenu *file_menu = new wxMenu;
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"));
f21b2fd8
GT
625#if wxUSE_NEW_GRID
626 file_menu->Append(FILE_DBGRID_TABLE, wxT("&Open DB Grid example"));
627#endif
94613352 628 file_menu->Append(FILE_EXIT, wxT("E&xit"));
e70e8f4c
GT
629
630 wxMenu *edit_menu = new wxMenu;
94613352 631 edit_menu->Append(EDIT_PARAMETERS, wxT("&Parameters..."));
e70e8f4c 632
ea24eeb2
GT
633 wxMenu *help_menu = new wxMenu;
634 help_menu->Append(HELP_ABOUT, wxT("&About"));
e70e8f4c
GT
635
636 wxMenuBar *menu_bar = new wxMenuBar;
94613352
GT
637 menu_bar->Append(file_menu, wxT("&File"));
638 menu_bar->Append(edit_menu, wxT("&Edit"));
ea24eeb2 639 menu_bar->Append(help_menu, wxT("&Help"));
e70e8f4c
GT
640 DemoFrame->SetMenuBar(menu_bar);
641
e70e8f4c
GT
642 params.ODBCSource[0] = 0;
643 params.UserName[0] = 0;
644 params.Password[0] = 0;
645 params.DirPath[0] = 0;
646
3ca6a5f0 647 // Show the frame
a4054ad1 648 DemoFrame->Show(TRUE);
3ca6a5f0 649
049977d0
GT
650 // Passing NULL for the SQL environment handle causes
651 // the wxDbConnectInf constructor to obtain a handle
652 // for you.
653 //
654 // WARNING: Be certain that you do not free this handle
655 // directly with SQLFreeEnv(). Use either the
656 // method ::FreeHenv() or delete the DbConnectInf.
657 DbConnectInf = new wxDbConnectInf(NULL, params.ODBCSource, params.UserName,
658 params.Password, params.DirPath);
659
660 if (!DbConnectInf || !DbConnectInf->GetHenv())
661 {
662 wxMessageBox(wxT("Unable to define data source connection info."), wxT("DB CONNECTION ERROR..."),wxOK | wxICON_EXCLAMATION);
ea24eeb2 663 wxDELETE(DbConnectInf);
049977d0
GT
664 }
665
3fe813a9
GT
666 if (!ReadParamFile(params))
667 DemoFrame->BuildParameterDialog(NULL);
668
669 if (!wxStrlen(params.ODBCSource))
670 {
ea24eeb2 671 wxDELETE(DbConnectInf);
a4054ad1 672 return(FALSE);
3fe813a9
GT
673 }
674
675 DbConnectInf->SetDsn(params.ODBCSource);
676 DbConnectInf->SetUserID(params.UserName);
677 DbConnectInf->SetPassword(params.Password);
678 DbConnectInf->SetDefaultDir(params.DirPath);
679
049977d0
GT
680 READONLY_DB = wxDbGetConnection(DbConnectInf);
681 if (READONLY_DB == 0)
682 {
683 wxMessageBox(wxT("Unable to connect to the data source.\n\nCheck the name of your data source to verify it has been correctly entered/spelled.\n\nWith some databases, the user name and password must\nbe created with full rights to the CONTACT table prior to making a connection\n(using tools provided by the database manufacturer)"), wxT("DB CONNECTION ERROR..."),wxOK | wxICON_EXCLAMATION);
684 DemoFrame->BuildParameterDialog(NULL);
ea24eeb2 685 wxDELETE(DbConnectInf);
049977d0 686 wxMessageBox(wxT("Now exiting program.\n\nRestart program to try any new settings."),wxT("Notice..."),wxOK | wxICON_INFORMATION);
a4054ad1 687 return(FALSE);
049977d0
GT
688 }
689
690 DemoFrame->BuildEditorDialog();
691
692 // Show the frame
693 DemoFrame->Refresh();
694
a4054ad1 695 return TRUE;
049977d0
GT
696} // DatabaseDemoApp::OnInit()
697
698
f369dd4f
GT
699/*
700* Remove CR or CR/LF from a character string.
701*/
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
a4054ad1 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
a4054ad1 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);
a4054ad1 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
a4054ad1 769 return TRUE;
049977d0
GT
770} // DatabaseDemoApp::WriteParamFile()
771
772
773void DatabaseDemoApp::CreateDataTable(bool recreate)
774{
a4054ad1 775 bool Ok = TRUE;
049977d0
GT
776 if (recreate)
777 Ok = (wxMessageBox(wxT("Any data currently residing in the table will be erased.\n\nAre you sure?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
778
779 if (!Ok)
780 return;
781
782 wxBeginBusyCursor();
783
a4054ad1 784 bool success = TRUE;
049977d0 785
ea24eeb2 786 Contact->GetDb()->RollbackTrans(); // Make sure the current cursor is in a known/stable state
049977d0
GT
787
788 if (!Contact->CreateTable(recreate))
789 {
790 wxEndBusyCursor();
791 wxString tStr;
f21b2fd8 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
a4054ad1 796 success = FALSE;
049977d0
GT
797 }
798 else
799 {
69a2b59d 800 if (!Contact->CreateIndexes(recreate))
049977d0
GT
801 {
802 wxEndBusyCursor();
803 wxString tStr;
f21b2fd8 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
a4054ad1 808 success = FALSE;
049977d0
GT
809 }
810 }
811 while (wxIsBusy())
812 wxEndBusyCursor();
813
049977d0
GT
814 if (success)
815 wxMessageBox(wxT("Table and index(es) were successfully created."),wxT("Notice..."),wxOK | wxICON_INFORMATION);
816} // DatabaseDemoApp::CreateDataTable()
108106cf 817
3ca6a5f0 818
1fc5dd6f 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)
f21b2fd8
GT
823#if wxUSE_NEW_GRID
824 EVT_MENU(FILE_DBGRID_TABLE, DatabaseDemoFrame::OnDbGridTable)
825#endif
1fc5dd6f
JS
826 EVT_MENU(FILE_EXIT, DatabaseDemoFrame::OnExit)
827 EVT_MENU(EDIT_PARAMETERS, DatabaseDemoFrame::OnEditParameters)
ea24eeb2 828 EVT_MENU(HELP_ABOUT, DatabaseDemoFrame::OnAbout)
1fc5dd6f
JS
829 EVT_CLOSE(DatabaseDemoFrame::OnCloseWindow)
830END_EVENT_TABLE()
108106cf 831
3ca6a5f0 832
108106cf 833// DatabaseDemoFrame constructor
1fc5dd6f 834DatabaseDemoFrame::DatabaseDemoFrame(wxFrame *frame, const wxString& title,
3ca6a5f0
BP
835 const wxPoint& pos, const wxSize& size):
836 wxFrame(frame, -1, title, pos, size)
108106cf 837{
3ca6a5f0
BP
838 // Put any code in necessary for initializing the main frame here
839 pEditorDlg = NULL;
840 pParamDlg = NULL;
3f030b48
GT
841
842 delete wxLog::SetActiveTarget(new wxLogStderr);
843
3ca6a5f0
BP
844} // DatabaseDemoFrame constructor
845
3f030b48
GT
846DatabaseDemoFrame::~DatabaseDemoFrame()
847{
848 delete wxLog::SetActiveTarget(NULL);
849} // DatabaseDemoFrame destructor
850
108106cf 851
74de91cc 852void DatabaseDemoFrame::OnCreate(wxCommandEvent& WXUNUSED(event))
1fc5dd6f 853{
a4054ad1 854 wxGetApp().CreateDataTable(FALSE);
3ca6a5f0
BP
855} // DatabaseDemoFrame::OnCreate()
856
857
74de91cc 858void DatabaseDemoFrame::OnRecreateTable(wxCommandEvent& WXUNUSED(event))
3ca6a5f0 859{
a4054ad1 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
a4054ad1 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
f21b2fd8 884#if wxUSE_NEW_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{
94613352 912 wxMessageBox(wxT("wxWindows sample program for database classes\n\nContributed on 27 July 1998"),wxT("About..."),wxOK | wxICON_INFORMATION);
3ca6a5f0
BP
913} // DatabaseDemoFrame::OnAbout()
914
108106cf 915
049977d0
GT
916// Put any additional checking necessary to make certain it is alright
917// to close the program here that is not done elsewhere
1fc5dd6f 918void DatabaseDemoFrame::OnCloseWindow(wxCloseEvent& event)
108106cf 919{
3f755e2d 920 // Clean up time
3ca6a5f0 921 if (pEditorDlg && pEditorDlg->Close())
3f755e2d
GT
922 pEditorDlg = NULL;
923 else
f6bcfd97 924 {
3ca6a5f0
BP
925 if (pEditorDlg)
926 {
927 event.Veto();
928 return;
929 }
f6bcfd97
BP
930 }
931
ea24eeb2
GT
932 wxDELETE(wxGetApp().Contact);
933
3ca6a5f0
BP
934 // This function will close all the connections to the database that have been
935 // previously cached.
936 wxDbCloseConnections();
937
049977d0
GT
938 // Deletion of the wxDbConnectInf instance must be the LAST thing done that
939 // has anything to do with the database. Deleting this before disconnecting,
940 // freeing/closing connections, etc will result in a crash!
ea24eeb2 941 wxDELETE(wxGetApp().DbConnectInf);
3f755e2d 942
1fc5dd6f 943 this->Destroy();
3f755e2d 944
e3065973 945} // DatabaseDemoFrame::OnCloseWindow()
108106cf
JS
946
947
108106cf
JS
948void DatabaseDemoFrame::BuildEditorDialog()
949{
3ca6a5f0 950 pEditorDlg = NULL;
e70e8f4c 951 pEditorDlg = new CeditorDlg(this);
3ca6a5f0
BP
952 if (pEditorDlg)
953 {
954 pEditorDlg->Initialize();
955 if (!pEditorDlg->initialized)
956 {
957 pEditorDlg->Close();
973f2539 958 pEditorDlg = NULL;
94613352 959 wxMessageBox(wxT("Unable to initialize the editor dialog for some reason"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
049977d0 960 Close();
3ca6a5f0
BP
961 }
962 }
963 else
964 {
94613352 965 wxMessageBox(wxT("Unable to create the editor dialog for some reason"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
049977d0 966 Close();
3ca6a5f0 967 }
108106cf
JS
968} // DatabaseDemoFrame::BuildEditorDialog()
969
970
971void DatabaseDemoFrame::BuildParameterDialog(wxWindow *parent)
972{
e70e8f4c 973 pParamDlg = new CparameterDlg(parent);
108106cf 974
e70e8f4c 975 if (!pParamDlg)
94613352 976 wxMessageBox(wxT("Unable to create the parameter dialog for some reason"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
108106cf
JS
977} // DatabaseDemoFrame::BuildParameterDialog()
978
979
980/*
f6bcfd97 981 * Constructor note: If no wxDb object is passed in, a new connection to the database
108106cf
JS
982 * is created for this instance of Ccontact. This can be a slow process depending
983 * on the database engine being used, and some database engines have a limit on the
984 * number of connections (either hard limits, or license restricted) so care should
985 * be used to use as few connections as is necessary.
e70e8f4c 986 *
f6bcfd97 987 * IMPORTANT: Objects which share a wxDb pointer are ALL acted upon whenever a member
108106cf
JS
988 * function of pDb is called (i.e. CommitTrans() or RollbackTrans(), so if modifying
989 * or creating a table objects which use the same pDb, know that all the objects
990 * will be committed or rolled back when any of the objects has this function call made.
991 */
049977d0
GT
992Ccontact::Ccontact (wxDb *pwxDb) : wxDbTable(pwxDb ? pwxDb : wxDbGetConnection(wxGetApp().DbConnectInf),
993 CONTACT_TABLE_NAME, CONTACT_NO_COLS, wxT(""),
994 !wxDB_QUERY_ONLY, wxGetApp().DbConnectInf->GetDefaultDir())
108106cf 995{
e70e8f4c
GT
996 // This is used to represent whether the database connection should be released
997 // when this instance of the object is deleted. If using the same connection
998 // for multiple instance of database objects, then the connection should only be
999 // released when the last database instance using the connection is deleted
f6bcfd97 1000 freeDbConn = !pwxDb;
e70e8f4c 1001
3fe813a9
GT
1002 if (GetDb())
1003 GetDb()->SetSqlLogging(sqlLogON);
1004
e70e8f4c 1005 SetupColumns();
108106cf
JS
1006
1007} // Ccontact Constructor
1008
1009
1010void Ccontact::Initialize()
1011{
e70e8f4c
GT
1012 Name[0] = 0;
1013 Addr1[0] = 0;
1014 Addr2[0] = 0;
1015 City[0] = 0;
1016 State[0] = 0;
1017 PostalCode[0] = 0;
1018 Country[0] = 0;
1019 JoinDate.year = 1980;
1020 JoinDate.month = 1;
1021 JoinDate.day = 1;
1022 JoinDate.hour = 0;
1023 JoinDate.minute = 0;
1024 JoinDate.second = 0;
1025 JoinDate.fraction = 0;
1026 NativeLanguage = langENGLISH;
a4054ad1 1027 IsDeveloper = FALSE;
e70e8f4c
GT
1028 Contributions = 0;
1029 LinesOfCode = 0L;
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
a4054ad1
GT
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
GT
1071#ifdef wxODBC_BLOB_SUPPORT
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
a4054ad1 1084 bool Ok = TRUE;
108106cf 1085
74de91cc 1086 wxStrcpy(idxDef[0].ColName, wxT("IS_DEV"));
a4054ad1 1087 idxDef[0].Ascending = TRUE;
108106cf 1088
74de91cc 1089 wxStrcpy(idxDef[1].ColName, wxT("NAME"));
a4054ad1 1090 idxDef[1].Ascending = TRUE;
108106cf 1091
f6bcfd97 1092 indexName = GetTableName();
74de91cc 1093 indexName += wxT("_IDX1");
a4054ad1 1094 Ok = CreateIndex(indexName.c_str(), TRUE, 2, idxDef, recreate);
108106cf 1095
e70e8f4c 1096 return Ok;
108106cf
JS
1097} // Ccontact::CreateIndexes()
1098
1099
1100/*
1101 * Having a function to do a query on the primary key (and possibly others) is
1102 * very efficient and tighter coding so that it is available where ever the object
1103 * is. Great for use with multiple tables when not using views or outer joins
1104 */
049977d0 1105bool Ccontact::FetchByName(const wxString &name)
108106cf 1106{
24e2b35d 1107 whereStr.Printf(wxT("NAME = '%s'"),name.c_str());
f6bcfd97 1108 SetWhereClause(whereStr.c_str());
94613352 1109 SetOrderByClause(wxT(""));
108106cf 1110
e70e8f4c 1111 if (!Query())
a4054ad1 1112 return(FALSE);
108106cf 1113
e70e8f4c
GT
1114 // Fetch the record
1115 return(GetNext());
108106cf
JS
1116
1117} // Ccontact::FetchByName()
1118
1119
1120/*
1121 *
1122 * ************* DIALOGS ***************
1123 *
1124 */
1125
1126
1127/* CeditorDlg constructor
1128 *
1129 * Creates the dialog used for creating/editing/deleting/copying a Ccontact object.
1130 * This dialog actually is drawn in the main frame of the program
1131 *
1132 * An instance of Ccontact is created - "Contact" - which is used to hold the Ccontact
1133 * object that is currently being worked with.
1134 */
f6fcbb63
RR
1135
1136BEGIN_EVENT_TABLE(CeditorDlg, wxPanel)
1137 EVT_BUTTON(-1, CeditorDlg::OnButton)
3f755e2d 1138 EVT_CLOSE(CeditorDlg::OnCloseWindow)
f6fcbb63
RR
1139END_EVENT_TABLE()
1140
3ca6a5f0 1141CeditorDlg::CeditorDlg(wxWindow *parent) : wxPanel (parent, 0, 0, 537, 480)
108106cf 1142{
e70e8f4c
GT
1143 // Since the ::OnCommand() function is overridden, this prevents the widget
1144 // detection in ::OnCommand() until all widgets have been initialized to prevent
1145 // uninitialized pointers from crashing the program
a4054ad1 1146 widgetPtrsSet = FALSE;
e70e8f4c 1147
a4054ad1 1148 initialized = FALSE;
e70e8f4c 1149
3fe813a9
GT
1150 SetMode(mView);
1151
a4054ad1 1152 Show(FALSE);
108106cf
JS
1153} // CeditorDlg constructor
1154
1155
e3065973 1156void CeditorDlg::OnCloseWindow(wxCloseEvent& event)
108106cf 1157{
e70e8f4c 1158 // Clean up time
3f755e2d 1159 if ((mode != mCreate) && (mode != mEdit))
e70e8f4c 1160 {
e70e8f4c
GT
1161 this->Destroy();
1162 }
1163 else
1164 {
94613352 1165 wxMessageBox(wxT("Must finish processing the current record being created/modified before exiting"),wxT("Notice..."),wxOK | wxICON_INFORMATION);
e70e8f4c
GT
1166 event.Veto();
1167 }
e3065973 1168} // CeditorDlg::OnCloseWindow()
108106cf
JS
1169
1170
3ca6a5f0 1171void CeditorDlg::OnButton(wxCommandEvent &event)
f6fcbb63 1172{
3ca6a5f0
BP
1173 wxWindow *win = (wxWindow*) event.GetEventObject();
1174 OnCommand( *win, event );
1175} // CeditorDlg::OnButton()
f6fcbb63 1176
65d7ddc4 1177
74de91cc 1178void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& WXUNUSED(event))
108106cf 1179{
e70e8f4c
GT
1180 wxString widgetName;
1181
1182 widgetName = win.GetName();
1183
1184 if (!widgetPtrsSet)
1185 return;
1186
1187 if (widgetName == pCreateBtn->GetName())
1188 {
ea24eeb2 1189 wxGetApp().Contact->Initialize();
e70e8f4c
GT
1190 PutData();
1191 SetMode( mCreate );
94613352 1192 pNameTxt->SetValue(wxT(""));
e70e8f4c
GT
1193 pNameTxt->SetFocus();
1194 return;
1195 }
1196
1197 if (widgetName == pEditBtn->GetName())
1198 {
ea24eeb2 1199 saveName = wxGetApp().Contact->Name;
e70e8f4c
GT
1200 SetMode( mEdit );
1201 pNameTxt->SetFocus();
1202 return;
1203 }
1204
1205 if (widgetName == pCopyBtn->GetName())
1206 {
1207 SetMode(mCreate);
94613352 1208 pNameTxt->SetValue(wxT(""));
e70e8f4c
GT
1209 pNameTxt->SetFocus();
1210 return;
1211 }
1212
1213 if (widgetName == pDeleteBtn->GetName())
1214 {
94613352 1215 bool Ok = (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
e70e8f4c
GT
1216
1217 if (!Ok)
1218 return;
1219
ea24eeb2 1220 if (Ok && wxGetApp().Contact->Delete())
e70e8f4c
GT
1221 {
1222 // NOTE: Deletions are not finalized until a CommitTrans() is performed.
1223 // If the commit were not performed, the program will continue to
1224 // show the table contents as if they were deleted until this instance
1225 // of Ccontact is deleted. If the Commit wasn't performed, the
1226 // database will automatically Rollback the changes when the database
1227 // connection is terminated
ea24eeb2 1228 wxGetApp().Contact->GetDb()->CommitTrans();
e70e8f4c
GT
1229
1230 // Try to get the row that followed the just deleted row in the orderBy sequence
1231 if (!GetNextRec())
1232 {
1233 // There was now row (in sequence) after the just deleted row, so get the
1234 // row which preceded the just deleted row
1235 if (!GetPrevRec())
1236 {
1237 // There are now no rows remaining, so clear the dialog widgets
ea24eeb2 1238 wxGetApp().Contact->Initialize();
e70e8f4c
GT
1239 PutData();
1240 }
1241 }
1242 SetMode(mode); // force reset of button enable/disable
1243 }
1244 else
1245 // Delete failed
ea24eeb2 1246 wxGetApp().Contact->GetDb()->RollbackTrans();
e70e8f4c
GT
1247
1248 SetMode(mView);
1249 return;
1250 }
1251
1252 if (widgetName == pSaveBtn->GetName())
1253 {
1254 Save();
1255 return;
1256 }
1257
1258 if (widgetName == pCancelBtn->GetName())
1259 {
94613352 1260 bool Ok = (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
e70e8f4c
GT
1261
1262 if (!Ok)
1263 return;
1264
94613352 1265 if (saveName.IsEmpty())
e70e8f4c 1266 {
ea24eeb2 1267 wxGetApp().Contact->Initialize();
e70e8f4c
GT
1268 PutData();
1269 SetMode(mView);
1270 return;
1271 }
1272 else
1273 {
1274 // Requery previous record
ea24eeb2 1275 if (wxGetApp().Contact->FetchByName(saveName))
e70e8f4c
GT
1276 {
1277 PutData();
1278 SetMode(mView);
1279 return;
1280 }
1281 }
1282
1283 // Previous record not available, retrieve first record in table
ea24eeb2
GT
1284 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1285 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
e70e8f4c 1286 {
ea24eeb2
GT
1287 wxGetApp().Contact->whereStr = wxT("NAME = (SELECT MIN(NAME) FROM ");
1288 wxGetApp().Contact->whereStr += wxGetApp().Contact->GetTableName();
1289 wxGetApp().Contact->whereStr += wxT(")");
1290 wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr.c_str());
e70e8f4c
GT
1291 }
1292 else
ea24eeb2 1293 wxGetApp().Contact->SetWhereClause(wxT(""));
e70e8f4c 1294
ea24eeb2 1295 if (!wxGetApp().Contact->Query())
e70e8f4c
GT
1296 {
1297 wxString tStr;
f21b2fd8 1298 tStr = wxT("ODBC error during Query()\n\n");
74de91cc 1299 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8
GT
1300 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
1301
e70e8f4c
GT
1302 SetMode(mView);
1303 return;
1304 }
ea24eeb2 1305 if (wxGetApp().Contact->GetNext()) // Successfully read first record
e70e8f4c
GT
1306 {
1307 PutData();
1308 SetMode(mView);
1309 return;
1310 }
1311 // No contacts are available, clear dialog
ea24eeb2 1312 wxGetApp().Contact->Initialize();
e70e8f4c
GT
1313 PutData();
1314 SetMode(mView);
1315 return;
1316 } // Cancel Button
1317
1318 if (widgetName == pPrevBtn->GetName())
1319 {
1320 if (!GetPrevRec())
1321 wxBell();
1322 return;
1323 } // Prev Button
1324
1325 if (widgetName == pNextBtn->GetName())
1326 {
1327 if (!GetNextRec())
1328 wxBell();
1329 return;
1330 } // Next Button
1331
1332 if (widgetName == pQueryBtn->GetName())
1333 {
1334 // Display the query dialog box
94613352 1335 wxChar qryWhere[DB_MAX_WHERE_CLAUSE_LEN+1];
ea24eeb2 1336 wxStrcpy(qryWhere, (const wxChar*) wxGetApp().Contact->qryWhereStr);
94613352 1337 wxChar *tblName[] = {(wxChar *)CONTACT_TABLE_NAME, 0};
ea24eeb2 1338 new CqueryDlg(GetParent(), wxGetApp().Contact->GetDb(), tblName, qryWhere);
e70e8f4c
GT
1339
1340 // Query the first record in the new record set and
1341 // display it, if the query string has changed.
ea24eeb2 1342 if (wxStrcmp(qryWhere, (const wxChar*) wxGetApp().Contact->qryWhereStr))
e70e8f4c 1343 {
ea24eeb2 1344 wxGetApp().Contact->whereStr.Empty();
74de91cc 1345 wxGetApp().Contact->SetOrderByClause(wxT("NAME"));
e70e8f4c 1346
ea24eeb2
GT
1347 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1348 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
e70e8f4c 1349 {
ea24eeb2
GT
1350 wxGetApp().Contact->whereStr = wxT("NAME = (SELECT MIN(NAME) FROM ");
1351 wxGetApp().Contact->whereStr += CONTACT_TABLE_NAME;
e70e8f4c
GT
1352 }
1353
1354 // Append the query where string (if there is one)
ea24eeb2 1355 wxGetApp().Contact->qryWhereStr = qryWhere;
f6bcfd97 1356 if (wxStrlen(qryWhere))
e70e8f4c 1357 {
ea24eeb2
GT
1358 wxGetApp().Contact->whereStr += wxT(" WHERE ");
1359 wxGetApp().Contact->whereStr += wxGetApp().Contact->qryWhereStr;
e70e8f4c
GT
1360 }
1361 // Close the expression with a right paren
ea24eeb2 1362 wxGetApp().Contact->whereStr += wxT(")");
e70e8f4c 1363 // Requery the table
ea24eeb2
GT
1364 wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr.c_str());
1365 if (!wxGetApp().Contact->Query())
e70e8f4c
GT
1366 {
1367 wxString tStr;
f21b2fd8 1368 tStr = wxT("ODBC error during Query()\n\n");
74de91cc 1369 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8
GT
1370 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
1371
e70e8f4c
GT
1372 return;
1373 }
1374 // Display the first record from the query set
ea24eeb2
GT
1375 if (!wxGetApp().Contact->GetNext())
1376 wxGetApp().Contact->Initialize();
e70e8f4c
GT
1377 PutData();
1378 }
1379
1380 // Enable/Disable the reset button
ea24eeb2 1381 pResetBtn->Enable(!wxGetApp().Contact->qryWhereStr.IsEmpty());
e70e8f4c
GT
1382
1383 return;
1384 } // Query button
1385
1386
1387 if (widgetName == pResetBtn->GetName())
1388 {
1389 // Clear the additional where criteria established by the query feature
ea24eeb2
GT
1390 wxGetApp().Contact->qryWhereStr = wxT("");
1391 wxGetApp().Contact->SetOrderByClause(wxT("NAME"));
e70e8f4c 1392
ea24eeb2
GT
1393 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1394 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
e70e8f4c 1395 {
ea24eeb2
GT
1396 wxGetApp().Contact->whereStr = wxT("NAME = (SELECT MIN(NAME) FROM ");
1397 wxGetApp().Contact->whereStr += CONTACT_TABLE_NAME;
1398 wxGetApp().Contact->whereStr += wxT(")");
e70e8f4c
GT
1399 }
1400
ea24eeb2
GT
1401 wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr.c_str());
1402 if (!wxGetApp().Contact->Query())
e70e8f4c
GT
1403 {
1404 wxString tStr;
f21b2fd8 1405 tStr = wxT("ODBC error during Query()\n\n");
74de91cc 1406 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 1407 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c
GT
1408 return;
1409 }
ea24eeb2
GT
1410 if (!wxGetApp().Contact->GetNext())
1411 wxGetApp().Contact->Initialize();
e70e8f4c 1412 PutData();
a4054ad1 1413 pResetBtn->Enable(FALSE);
e70e8f4c
GT
1414
1415 return;
1416 } // Reset button
1417
1418
1419 if (widgetName == pNameListBtn->GetName())
1420 {
049977d0 1421 new ClookUpDlg(/* wxWindow *parent */ this,
94613352
GT
1422 /* wxChar *windowTitle */ wxT("Select contact name"),
1423 /* wxChar *tableName */ (wxChar *) CONTACT_TABLE_NAME,
1424 /* wxChar *dispCol1 */ wxT("NAME"),
1425 /* wxChar *dispCol2 */ wxT("JOINDATE"),
1426 /* wxChar *where */ wxT(""),
1427 /* wxChar *orderBy */ wxT("NAME"),
049977d0
GT
1428 /* wxDb *pDb */ wxGetApp().READONLY_DB,
1429 /* const wxString &defDir */ wxGetApp().DbConnectInf->GetDefaultDir(),
a4054ad1 1430 /* bool distinctValues */ TRUE);
e70e8f4c 1431
f6bcfd97 1432 if (ListDB_Selection && wxStrlen(ListDB_Selection))
e70e8f4c 1433 {
94613352 1434 wxString w = wxT("NAME = '");
e70e8f4c 1435 w += ListDB_Selection;
94613352 1436 w += wxT("'");
049977d0 1437 GetRec(w);
e70e8f4c
GT
1438 }
1439
1440 return;
1441 }
3f030b48
GT
1442
1443 if (widgetName == pDataTypesBtn->GetName())
1444 {
1445 CheckSupportForAllDataTypes(wxGetApp().READONLY_DB);
74de91cc 1446 wxMessageBox(wxT("Support datatypes was dumped to stdout."));
3f030b48
GT
1447 return;
1448 } // Data types Button
1449
1450 if (widgetName == pDbDiagsBtn->GetName())
1451 {
1452 DisplayDbDiagnostics(wxGetApp().READONLY_DB);
74de91cc 1453 wxMessageBox(wxT("Diagnostics info was dumped to stdout."));
69a2b59d
GT
1454 return;
1455 }
1456
1457 if (widgetName == pCatalogBtn->GetName())
1458 {
74de91cc
JS
1459 if (wxGetApp().Contact->GetDb()->Catalog(wxT(""),wxT("catalog.txt")))
1460 wxMessageBox(wxT("The file 'catalog.txt' was created."));
69a2b59d 1461 else
74de91cc 1462 wxMessageBox(wxT("Creation of the file 'catalog.txt' was failed."));
3f030b48
GT
1463 return;
1464 }
1465
108106cf
JS
1466} // CeditorDlg::OnCommand()
1467
1468
3ca6a5f0
BP
1469bool CeditorDlg::Initialize()
1470{
1471 // Create the data structure and a new database connection.
1472 // (As there is not a pDb being passed in the constructor, a new database
1473 // connection is created)
ea24eeb2 1474 wxGetApp().Contact = new Ccontact();
3ca6a5f0 1475
ea24eeb2 1476 if (!wxGetApp().Contact)
3ca6a5f0 1477 {
94613352 1478 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
a4054ad1 1479 return FALSE;
3ca6a5f0
BP
1480 }
1481
1482 // Check if the table exists or not. If it doesn't, ask the user if they want to
1483 // create the table. Continue trying to create the table until it exists, or user aborts
ea24eeb2 1484 while (!wxGetApp().Contact->GetDb()->TableExists((wxChar *)CONTACT_TABLE_NAME,
049977d0
GT
1485 wxGetApp().DbConnectInf->GetUserID(),
1486 wxGetApp().DbConnectInf->GetDefaultDir()))
3ca6a5f0
BP
1487 {
1488 wxString tStr;
f21b2fd8
GT
1489 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);
1490 bool createTable = (wxMessageBox(tStr.c_str(),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
3ca6a5f0
BP
1491
1492 if (!createTable)
1493 {
1494// Close();
a4054ad1 1495 return FALSE;
3ca6a5f0
BP
1496 }
1497 else
a4054ad1 1498 wxGetApp().CreateDataTable(FALSE);
3ca6a5f0
BP
1499 }
1500
1501 // Tables must be "opened" before anything other than creating/deleting table can be done
ea24eeb2 1502 if (!wxGetApp().Contact->Open())
3ca6a5f0
BP
1503 {
1504 // Table does exist, or there was some problem opening it. Currently this should
973f2539 1505 // never fail, except in the case of the table not exisiting or the current
3ca6a5f0 1506 // user has insufficent privileges to access the table
3fe813a9 1507#if 1
3ca6a5f0
BP
1508// This code is experimenting with a new function that will hopefully be available
1509// in the 2.4 release. This check will determine whether the open failing was due
1510// to the table not existing, or the users privileges being insufficient to
1511// open the table.
ea24eeb2
GT
1512 if (!wxGetApp().Contact->GetDb()->TablePrivileges(CONTACT_TABLE_NAME, wxT("SELECT"),
1513 wxGetApp().Contact->GetDb()->GetUsername(),
69a2b59d
GT
1514 wxGetApp().Contact->GetDb()->GetUsername(),
1515 wxGetApp().DbConnectInf->GetDefaultDir()))
3ca6a5f0
BP
1516 {
1517 wxString tStr;
3fe813a9 1518 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 1519
74de91cc 1520 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 1521 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
3ca6a5f0
BP
1522 }
1523 else
1524#endif
ea24eeb2
GT
1525 if (!wxGetApp().Contact->GetDb()->TableExists(CONTACT_TABLE_NAME,
1526 wxGetApp().Contact->GetDb()->GetUsername(),
3fe813a9 1527 wxGetApp().DbConnectInf->GetDefaultDir()))
3ca6a5f0
BP
1528 {
1529 wxString tStr;
3fe813a9 1530 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 1531 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 1532 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
3ca6a5f0
BP
1533 }
1534
a4054ad1 1535 return FALSE;
3ca6a5f0
BP
1536 }
1537
1538 // Build the dialog
1539
94613352
GT
1540 (void)new wxStaticBox(this, EDITOR_DIALOG_FN_GROUP, wxT(""), wxPoint(15, 1), wxSize(497, 69), 0, wxT("FunctionGrp"));
1541 (void)new wxStaticBox(this, EDITOR_DIALOG_SEARCH_GROUP, wxT(""), wxPoint(417, 1), wxSize(95, 242), 0, wxT("SearchGrp"));
1542
1543 pCreateBtn = new wxButton(this, EDITOR_DIALOG_CREATE, wxT("&Create"), wxPoint( 25, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("CreateBtn"));
1544 pEditBtn = new wxButton(this, EDITOR_DIALOG_EDIT, wxT("&Edit"), wxPoint(102, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("EditBtn"));
1545 pDeleteBtn = new wxButton(this, EDITOR_DIALOG_DELETE, wxT("&Delete"), wxPoint(179, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("DeleteBtn"));
1546 pCopyBtn = new wxButton(this, EDITOR_DIALOG_COPY, wxT("Cop&y"), wxPoint(256, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("CopyBtn"));
1547 pSaveBtn = new wxButton(this, EDITOR_DIALOG_SAVE, wxT("&Save"), wxPoint(333, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("SaveBtn"));
1548 pCancelBtn = new wxButton(this, EDITOR_DIALOG_CANCEL, wxT("C&ancel"), wxPoint(430, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("CancelBtn"));
1549 pPrevBtn = new wxButton(this, EDITOR_DIALOG_PREV, wxT("<< &Prev"), wxPoint(430, 81), wxSize( 70, 35), 0, wxDefaultValidator, wxT("PrevBtn"));
1550 pNextBtn = new wxButton(this, EDITOR_DIALOG_NEXT, wxT("&Next >>"), wxPoint(430, 121), wxSize( 70, 35), 0, wxDefaultValidator, wxT("NextBtn"));
1551 pQueryBtn = new wxButton(this, EDITOR_DIALOG_QUERY, wxT("&Query"), wxPoint(430, 161), wxSize( 70, 35), 0, wxDefaultValidator, wxT("QueryBtn"));
1552 pResetBtn = new wxButton(this, EDITOR_DIALOG_RESET, wxT("&Reset"), wxPoint(430, 200), wxSize( 70, 35), 0, wxDefaultValidator, wxT("ResetBtn"));
1553 pNameMsg = new wxStaticText(this, EDITOR_DIALOG_NAME_MSG, wxT("Name:"), wxPoint( 17, 80), wxSize( -1, -1), 0, wxT("NameMsg"));
1554 pNameTxt = new wxTextCtrl(this, EDITOR_DIALOG_NAME_TEXT, wxT(""), wxPoint( 17, 97), wxSize(308, 25), 0, wxDefaultValidator, wxT("NameTxt"));
1555 pNameListBtn = new wxButton(this, EDITOR_DIALOG_LOOKUP, wxT("&Lookup"), wxPoint(333, 97), wxSize( 70, 24), 0, wxDefaultValidator, wxT("LookupBtn"));
1556 pAddress1Msg = new wxStaticText(this, EDITOR_DIALOG_ADDRESS1_MSG, wxT("Address:"), wxPoint( 17, 130), wxSize( -1, -1), 0, wxT("Address1Msg"));
1557 pAddress1Txt = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT, wxT(""), wxPoint( 17, 147), wxSize(308, 25), 0, wxDefaultValidator, wxT("Address1Txt"));
1558 pAddress2Msg = new wxStaticText(this, EDITOR_DIALOG_ADDRESS2_MSG, wxT("Address:"), wxPoint( 17, 180), wxSize( -1, -1), 0, wxT("Address2Msg"));
1559 pAddress2Txt = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT, wxT(""), wxPoint( 17, 197), wxSize(308, 25), 0, wxDefaultValidator, wxT("Address2Txt"));
1560 pCityMsg = new wxStaticText(this, EDITOR_DIALOG_CITY_MSG, wxT("City:"), wxPoint( 17, 230), wxSize( -1, -1), 0, wxT("CityMsg"));
1561 pCityTxt = new wxTextCtrl(this, EDITOR_DIALOG_CITY_TEXT, wxT(""), wxPoint( 17, 247), wxSize(225, 25), 0, wxDefaultValidator, wxT("CityTxt"));
1562 pStateMsg = new wxStaticText(this, EDITOR_DIALOG_STATE_MSG, wxT("State:"), wxPoint(250, 230), wxSize( -1, -1), 0, wxT("StateMsg"));
1563 pStateTxt = new wxTextCtrl(this, EDITOR_DIALOG_STATE_TEXT, wxT(""), wxPoint(250, 247), wxSize(153, 25), 0, wxDefaultValidator, wxT("StateTxt"));
1564 pCountryMsg = new wxStaticText(this, EDITOR_DIALOG_COUNTRY_MSG, wxT("Country:"), wxPoint( 17, 280), wxSize( -1, -1), 0, wxT("CountryMsg"));
1565 pCountryTxt = new wxTextCtrl(this, EDITOR_DIALOG_COUNTRY_TEXT, wxT(""), wxPoint( 17, 297), wxSize(225, 25), 0, wxDefaultValidator, wxT("CountryTxt"));
1566 pPostalCodeMsg = new wxStaticText(this, EDITOR_DIALOG_POSTAL_MSG, wxT("Postal Code:"),wxPoint(250, 280), wxSize( -1, -1), 0, wxT("PostalCodeMsg"));
1567 pPostalCodeTxt = new wxTextCtrl(this, EDITOR_DIALOG_POSTAL_TEXT, wxT(""), wxPoint(250, 297), wxSize(153, 25), 0, wxDefaultValidator, wxT("PostalCodeTxt"));
3ca6a5f0
BP
1568
1569 wxString choice_strings[5];
94613352
GT
1570 choice_strings[0] = wxT("English");
1571 choice_strings[1] = wxT("French");
1572 choice_strings[2] = wxT("German");
1573 choice_strings[3] = wxT("Spanish");
1574 choice_strings[4] = wxT("Other");
3ca6a5f0 1575
94613352
GT
1576 pNativeLangChoice = new wxChoice(this, EDITOR_DIALOG_LANG_CHOICE, wxPoint( 17, 346), wxSize(277, -1), 5, choice_strings);
1577 pNativeLangMsg = new wxStaticText(this, EDITOR_DIALOG_LANG_MSG, wxT("Native language:"), wxPoint( 17, 330), wxSize( -1, -1), 0, wxT("NativeLangMsg"));
3ca6a5f0
BP
1578
1579 wxString radio_strings[2];
94613352
GT
1580 radio_strings[0] = wxT("No");
1581 radio_strings[1] = wxT("Yes");
1582 pDeveloperRadio = new wxRadioBox(this,EDITOR_DIALOG_DEVELOPER, wxT("Developer:"), wxPoint(303, 330), wxSize( -1, -1), 2, radio_strings, 2, wxHORIZONTAL);
1583 pJoinDateMsg = new wxStaticText(this, EDITOR_DIALOG_JOIN_MSG, wxT("Date joined:"), wxPoint( 17, 380), wxSize( -1, -1), 0, wxT("JoinDateMsg"));
1584 pJoinDateTxt = new wxTextCtrl(this, EDITOR_DIALOG_JOIN_TEXT, wxT(""), wxPoint( 17, 397), wxSize(150, 25), 0, wxDefaultValidator, wxT("JoinDateTxt"));
1585 pContribMsg = new wxStaticText(this, EDITOR_DIALOG_CONTRIB_MSG,wxT("Contributions:"), wxPoint(175, 380), wxSize( -1, -1), 0, wxT("ContribMsg"));
1586 pContribTxt = new wxTextCtrl(this, EDITOR_DIALOG_CONTRIB_TEXT, wxT(""), wxPoint(175, 397), wxSize(120, 25), 0, wxDefaultValidator, wxT("ContribTxt"));
1587 pLinesMsg = new wxStaticText(this, EDITOR_DIALOG_LINES_MSG, wxT("Lines of code:"), wxPoint(303, 380), wxSize( -1, -1), 0, wxT("LinesMsg"));
1588 pLinesTxt = new wxTextCtrl(this, EDITOR_DIALOG_LINES_TEXT, wxT(""), wxPoint(303, 397), wxSize(100, 25), 0, wxDefaultValidator, wxT("LinesTxt"));
3ca6a5f0 1589
69a2b59d 1590 pCatalogBtn = new wxButton(this, EDITOR_DIALOG_CATALOG, wxT("Catalo&g"), wxPoint(430, 287), wxSize( 70, 35), 0, wxDefaultValidator, wxT("CatalogBtn"));
3f030b48
GT
1591 pDataTypesBtn = new wxButton(this, EDITOR_DIALOG_DATATYPES, wxT("Data&types"), wxPoint(430, 337), wxSize( 70, 35), 0, wxDefaultValidator, wxT("DataTypesBtn"));
1592 pDbDiagsBtn = new wxButton(this, EDITOR_DIALOG_DB_DIAGS, wxT("DB Dia&gs"), wxPoint(430, 387), wxSize( 70, 35), 0, wxDefaultValidator, wxT("DbDiagsBtn"));
1593
3ca6a5f0
BP
1594 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
1595 // handle all widget processing
a4054ad1 1596 widgetPtrsSet = TRUE;
3ca6a5f0
BP
1597
1598 // Setup the orderBy and where clauses to return back a single record as the result set,
1599 // as there will only be one record being shown on the dialog at a time, this optimizes
1600 // network traffic by only returning a one row result
1601
ea24eeb2 1602 wxGetApp().Contact->SetOrderByClause(wxT("NAME")); // field name to sort by
3ca6a5f0
BP
1603
1604 // The wxString "whereStr" is not a member of the wxDbTable object, it is a member variable
1605 // specifically in the Ccontact class. It is used here for simpler construction of a varying
1606 // length string, and then after the string is built, the wxDbTable member variable "where" is
1607 // assigned the pointer to the constructed string.
1608 //
1609 // The constructed where clause below has a sub-query within it "SELECT MIN(NAME) FROM %s"
1610 // to achieve a single row (in this case the first name in alphabetical order).
1611
ea24eeb2
GT
1612 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1613 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
3ca6a5f0 1614 {
ea24eeb2
GT
1615 wxGetApp().Contact->whereStr.Printf(wxT("NAME = (SELECT MIN(NAME) FROM %s)"),
1616 wxGetApp().Contact->GetTableName().c_str());
94613352 1617 // NOTE: (const wxChar*) returns a pointer which may not be valid later, so this is short term use only
ea24eeb2 1618 wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr);
3ca6a5f0
BP
1619 }
1620 else
ea24eeb2 1621 wxGetApp().Contact->SetWhereClause(wxT(""));
3ca6a5f0
BP
1622
1623 // Perform the Query to get the result set.
a4054ad1
GT
1624 // NOTE: If there are no rows returned, that is a valid result, so Query() would return TRUE.
1625 // Only if there is a database error will Query() come back as FALSE
ea24eeb2 1626 if (!wxGetApp().Contact->Query())
3ca6a5f0
BP
1627 {
1628 wxString tStr;
f21b2fd8 1629 tStr = wxT("ODBC error during Query()\n\n");
74de91cc 1630 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 1631 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
a4054ad1 1632 return FALSE;
3ca6a5f0
BP
1633 }
1634
1635 // Since Query succeeded, now get the row that was returned
ea24eeb2 1636 if (!wxGetApp().Contact->GetNext())
3ca6a5f0
BP
1637 // If the GetNext() failed at this point, then there are no rows to retrieve,
1638 // so clear the values in the members of "Contact" so that PutData() blanks the
1639 // widgets on the dialog
ea24eeb2
GT
1640 wxGetApp().Contact->Initialize();
1641/*
1642 wxGetApp().Contact->GetDb()->RollbackTrans();
1643*/
3ca6a5f0
BP
1644 SetMode(mView);
1645 PutData();
1646
a4054ad1 1647 Show(TRUE);
3ca6a5f0 1648
a4054ad1
GT
1649 initialized = TRUE;
1650 return TRUE;
3ca6a5f0
BP
1651} // CeditorDlg::Initialize()
1652
1653
108106cf
JS
1654void CeditorDlg::FieldsEditable()
1655{
3fe813a9
GT
1656 if (!widgetPtrsSet)
1657 return;
1658
e70e8f4c
GT
1659 pNameTxt->Enable((mode == mCreate) || (mode == mEdit));
1660 pAddress1Txt->Enable((mode == mCreate) || (mode == mEdit));
1661 pAddress2Txt->Enable((mode == mCreate) || (mode == mEdit));
1662 pCityTxt->Enable((mode == mCreate) || (mode == mEdit));
1663 pStateTxt->Enable((mode == mCreate) || (mode == mEdit));
1664 pPostalCodeTxt->Enable((mode == mCreate) || (mode == mEdit));
1665 pCountryTxt->Enable((mode == mCreate) || (mode == mEdit));
1666
1667 pJoinDateTxt->Enable((mode == mCreate) || (mode == mEdit));
1668 pContribTxt->Enable((mode == mCreate) || (mode == mEdit));
1669 pLinesTxt->Enable((mode == mCreate) || (mode == mEdit));
1670 pNativeLangChoice->Enable((mode == mCreate) || (mode == mEdit));
1671 pDeveloperRadio->Enable((mode == mCreate) || (mode == mEdit));
108106cf
JS
1672
1673} // CeditorDlg::FieldsEditable()
1674
1675
1676void CeditorDlg::SetMode(enum DialogModes m)
1677{
a4054ad1 1678 bool edit = FALSE;
e70e8f4c
GT
1679
1680 mode = m;
1681 switch (mode)
1682 {
1683 case mCreate:
1684 case mEdit:
a4054ad1 1685 edit = TRUE;
e70e8f4c
GT
1686 break;
1687 case mView:
1688 case mSearch:
a4054ad1 1689 edit = FALSE;
e70e8f4c
GT
1690 break;
1691 default:
1692 break;
1693 };
1694
1695 if (widgetPtrsSet)
1696 {
1697 pCreateBtn->Enable( !edit );
ea24eeb2
GT
1698 pEditBtn->Enable( !edit && (wxStrcmp(wxGetApp().Contact->Name,wxT(""))!=0) );
1699 pDeleteBtn->Enable( !edit && (wxStrcmp(wxGetApp().Contact->Name,wxT(""))!=0) );
1700 pCopyBtn->Enable( !edit && (wxStrcmp(wxGetApp().Contact->Name,wxT(""))!=0) );
e70e8f4c
GT
1701 pSaveBtn->Enable( edit );
1702 pCancelBtn->Enable( edit );
1703 pPrevBtn->Enable( !edit );
1704 pNextBtn->Enable( !edit );
1705 pQueryBtn->Enable( !edit );
ea24eeb2 1706 pResetBtn->Enable( !edit && !wxGetApp().Contact->qryWhereStr.IsEmpty() );
e70e8f4c
GT
1707 pNameListBtn->Enable( !edit );
1708 }
1709
1710 FieldsEditable();
108106cf
JS
1711} // CeditorDlg::SetMode()
1712
1713
1fc5dd6f 1714bool CeditorDlg::PutData()
108106cf 1715{
e70e8f4c 1716 wxString tStr;
108106cf 1717
ea24eeb2
GT
1718 pNameTxt->SetValue(wxGetApp().Contact->Name);
1719 pAddress1Txt->SetValue(wxGetApp().Contact->Addr1);
1720 pAddress2Txt->SetValue(wxGetApp().Contact->Addr2);
1721 pCityTxt->SetValue(wxGetApp().Contact->City);
1722 pStateTxt->SetValue(wxGetApp().Contact->State);
1723 pCountryTxt->SetValue(wxGetApp().Contact->Country);
1724 pPostalCodeTxt->SetValue(wxGetApp().Contact->PostalCode);
108106cf 1725
ea24eeb2 1726 tStr.Printf(wxT("%d/%d/%d"),wxGetApp().Contact->JoinDate.month,wxGetApp().Contact->JoinDate.day,wxGetApp().Contact->JoinDate.year);
e70e8f4c 1727 pJoinDateTxt->SetValue(tStr);
108106cf 1728
ea24eeb2 1729 tStr.Printf(wxT("%d"),wxGetApp().Contact->Contributions);
e70e8f4c 1730 pContribTxt->SetValue(tStr);
108106cf 1731
ea24eeb2 1732 tStr.Printf(wxT("%lu"),wxGetApp().Contact->LinesOfCode);
e70e8f4c 1733 pLinesTxt->SetValue(tStr);
108106cf 1734
ea24eeb2 1735 pNativeLangChoice->SetSelection(wxGetApp().Contact->NativeLanguage);
108106cf 1736
ea24eeb2 1737 pDeveloperRadio->SetSelection(wxGetApp().Contact->IsDeveloper);
108106cf 1738
a4054ad1 1739 return TRUE;
108106cf
JS
1740} // Ceditor::PutData()
1741
1742
1743/*
1744 * Reads the data out of all the widgets on the dialog. Some data evaluation is done
1745 * to ensure that there is a name entered and that the date field is valid.
1746 *
a4054ad1 1747 * A return value of TRUE means that valid data was retrieved from the dialog, otherwise
108106cf
JS
1748 * invalid data was found (and a message was displayed telling the user what to fix), and
1749 * the data was not placed into the appropraite fields of Ccontact
1750 */
1fc5dd6f 1751bool CeditorDlg::GetData()
108106cf 1752{
e70e8f4c
GT
1753 // Validate that the data currently entered into the widgets is valid data
1754
1755 wxString tStr;
1756 tStr = pNameTxt->GetValue();
94613352 1757 if (!wxStrcmp((const wxChar*) tStr,wxT("")))
e70e8f4c 1758 {
94613352 1759 wxMessageBox(wxT("A name is required for entry into the contact table"),wxT("Notice..."),wxOK | wxICON_INFORMATION);
a4054ad1 1760 return FALSE;
e70e8f4c
GT
1761 }
1762
a4054ad1 1763 bool invalid = FALSE;
f369dd4f 1764 int mm = 1,dd = 1,yyyy = 2001;
e70e8f4c
GT
1765 int first, second;
1766
1767 tStr = pJoinDateTxt->GetValue();
94613352 1768 if (tStr.Freq(wxT('/')) != 2)
a4054ad1 1769 invalid = TRUE;
e70e8f4c
GT
1770
1771 // Find the month, day, and year tokens
1772 if (!invalid)
1773 {
94613352
GT
1774 first = tStr.First(wxT('/'));
1775 second = tStr.Last(wxT('/'));
e70e8f4c 1776
74de91cc
JS
1777 mm = wxAtoi(tStr.SubString(0,first));
1778 dd = wxAtoi(tStr.SubString(first+1,second));
1779 yyyy = wxAtoi(tStr.SubString(second+1,tStr.Length()-1));
e70e8f4c
GT
1780
1781 invalid = !(mm && dd && yyyy);
1782 }
1783
1784 // Force Year 2000 compliance
1785 if (!invalid && (yyyy < 1000))
a4054ad1 1786 invalid = TRUE;
e70e8f4c
GT
1787
1788 // Check the token ranges for validity
1789 if (!invalid)
1790 {
1791 if (yyyy > 9999)
a4054ad1 1792 invalid = TRUE;
e70e8f4c 1793 else if ((mm < 1) || (mm > 12))
a4054ad1 1794 invalid = TRUE;
e70e8f4c
GT
1795 else
1796 {
1797 if (dd < 1)
a4054ad1 1798 invalid = TRUE;
e70e8f4c
GT
1799 else
1800 {
1801 int days[12] = {31,28,31,30,31,30,
1802 31,31,30,31,30,31};
1803 if (dd > days[mm-1])
1804 {
a4054ad1 1805 invalid = TRUE;
e70e8f4c
GT
1806 if ((dd == 29) && (mm == 2))
1807 {
1808 if (((yyyy % 4) == 0) && (((yyyy % 100) != 0) || ((yyyy % 400) == 0)))
a4054ad1 1809 invalid = FALSE;
e70e8f4c
GT
1810 }
1811 }
1812 }
1813 }
1814 }
1815
1816 if (!invalid)
1817 {
ea24eeb2
GT
1818 wxGetApp().Contact->JoinDate.month = mm;
1819 wxGetApp().Contact->JoinDate.day = dd;
1820 wxGetApp().Contact->JoinDate.year = yyyy;
e70e8f4c
GT
1821 }
1822 else
1823 {
94613352 1824 wxMessageBox(wxT("Improper date format. Please check the date\nspecified and try again.\n\nNOTE: Dates are in american format (MM/DD/YYYY)"),wxT("Notice..."),wxOK | wxICON_INFORMATION);
a4054ad1 1825 return FALSE;
e70e8f4c
GT
1826 }
1827
1828 tStr = pNameTxt->GetValue();
ea24eeb2
GT
1829 wxStrcpy(wxGetApp().Contact->Name,(const wxChar*) tStr);
1830 wxStrcpy(wxGetApp().Contact->Addr1,pAddress1Txt->GetValue());
1831 wxStrcpy(wxGetApp().Contact->Addr2,pAddress2Txt->GetValue());
1832 wxStrcpy(wxGetApp().Contact->City,pCityTxt->GetValue());
1833 wxStrcpy(wxGetApp().Contact->State,pStateTxt->GetValue());
1834 wxStrcpy(wxGetApp().Contact->Country,pCountryTxt->GetValue());
1835 wxStrcpy(wxGetApp().Contact->PostalCode,pPostalCodeTxt->GetValue());
e70e8f4c 1836
74de91cc
JS
1837 wxGetApp().Contact->Contributions = wxAtoi(pContribTxt->GetValue());
1838 wxGetApp().Contact->LinesOfCode = wxAtol(pLinesTxt->GetValue());
e70e8f4c 1839
ea24eeb2
GT
1840 wxGetApp().Contact->NativeLanguage = (enum Language) pNativeLangChoice->GetSelection();
1841 wxGetApp().Contact->IsDeveloper = pDeveloperRadio->GetSelection() > 0;
e70e8f4c 1842
a4054ad1 1843 return TRUE;
108106cf
JS
1844} // CeditorDlg::GetData()
1845
1846
1847/*
1848 * Retrieve data from the dialog, verify the validity of the data, and if it is valid,
1849 * try to insert/update the data to the table based on the current 'mode' the dialog
1850 * is set to.
1851 *
a4054ad1
GT
1852 * A return value of TRUE means the insert/update was completed successfully, a return
1853 * value of FALSE means that Save() failed. If returning FALSE, then this function
108106cf
JS
1854 * has displayed a detailed error message for the user.
1855 */
1fc5dd6f 1856bool CeditorDlg::Save()
108106cf 1857{
a4054ad1 1858 bool failed = FALSE;
e70e8f4c
GT
1859
1860 // Read the data in the widgets of the dialog to get the user's data
1861 if (!GetData())
a4054ad1 1862 failed = TRUE;
e70e8f4c
GT
1863
1864 // Perform any other required validations necessary before saving
1865 if (!failed)
1866 {
1867 wxBeginBusyCursor();
1868
1869 if (mode == mCreate)
1870 {
ea24eeb2 1871 RETCODE result = wxGetApp().Contact->Insert();
e70e8f4c
GT
1872
1873 failed = (result != DB_SUCCESS);
1874 if (failed)
1875 {
1876 // Some errors may be expected, like a duplicate key, so handle those instances with
1877 // specific error messages.
1878 if (result == DB_ERR_INTEGRITY_CONSTRAINT_VIOL)
1879 {
1880 wxString tStr;
f21b2fd8 1881 tStr = wxT("A duplicate key value already exists in the table.\nUnable to save record\n\n");
74de91cc 1882 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 1883 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c
GT
1884 }
1885 else
1886 {
5d59e67a 1887 // Some other unexpected error occurred
e70e8f4c 1888 wxString tStr;
f21b2fd8 1889 tStr = wxT("Database insert failed\n\n");
74de91cc 1890 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 1891 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c
GT
1892 }
1893 }
1894 }
1895 else // mode == mEdit
1896 {
5d59e67a 1897 wxGetApp().Contact->GetDb()->RollbackTrans();
74de91cc 1898 wxGetApp().Contact->whereStr.Printf(wxT("NAME = '%s'"),saveName.c_str());
ea24eeb2 1899 if (!wxGetApp().Contact->UpdateWhere(wxGetApp().Contact->whereStr))
e70e8f4c
GT
1900 {
1901 wxString tStr;
f21b2fd8 1902 tStr = wxT("Database update failed\n\n");
74de91cc 1903 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 1904 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
a4054ad1 1905 failed = TRUE;
e70e8f4c
GT
1906 }
1907 }
1908
1909 if (!failed)
1910 {
ea24eeb2 1911 wxGetApp().Contact->GetDb()->CommitTrans();
e70e8f4c
GT
1912 SetMode(mView); // Sets the dialog mode back to viewing after save is successful
1913 }
1914 else
ea24eeb2 1915 wxGetApp().Contact->GetDb()->RollbackTrans();
e70e8f4c
GT
1916
1917 wxEndBusyCursor();
1918 }
1919
1920 return !failed;
108106cf
JS
1921} // CeditorDlg::Save()
1922
1923
1924/*
1925 * Where this program is only showing a single row at a time in the dialog,
1926 * a special where clause must be built to find just the single row which,
1927 * in sequence, would follow the currently displayed row.
1928 */
1fc5dd6f 1929bool CeditorDlg::GetNextRec()
108106cf 1930{
e70e8f4c
GT
1931 wxString w;
1932
ea24eeb2
GT
1933 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1934 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
e70e8f4c 1935 {
94613352 1936 w = wxT("NAME = (SELECT MIN(NAME) FROM ");
ea24eeb2 1937 w += wxGetApp().Contact->GetTableName();
94613352 1938 w += wxT(" WHERE NAME > '");
e70e8f4c
GT
1939 }
1940 else
94613352 1941 w = wxT("(NAME > '");
e70e8f4c 1942
ea24eeb2 1943 w += wxGetApp().Contact->Name;
94613352 1944 w += wxT("'");
e70e8f4c
GT
1945
1946 // If a query where string is currently set, append that criteria
ea24eeb2 1947 if (!wxGetApp().Contact->qryWhereStr.IsEmpty())
e70e8f4c 1948 {
94613352 1949 w += wxT(" AND (");
ea24eeb2 1950 w += wxGetApp().Contact->qryWhereStr;
94613352 1951 w += wxT(")");
e70e8f4c
GT
1952 }
1953
94613352 1954 w += wxT(")");
049977d0 1955 return(GetRec(w));
108106cf
JS
1956
1957} // CeditorDlg::GetNextRec()
1958
1959
1960/*
1961 * Where this program is only showing a single row at a time in the dialog,
1962 * a special where clause must be built to find just the single row which,
1963 * in sequence, would precede the currently displayed row.
1964 */
1fc5dd6f 1965bool CeditorDlg::GetPrevRec()
108106cf 1966{
e70e8f4c 1967 wxString w;
108106cf 1968
ea24eeb2
GT
1969 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1970 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
e70e8f4c 1971 {
94613352 1972 w = wxT("NAME = (SELECT MAX(NAME) FROM ");
ea24eeb2 1973 w += wxGetApp().Contact->GetTableName();
94613352 1974 w += wxT(" WHERE NAME < '");
e70e8f4c
GT
1975 }
1976 else
94613352 1977 w = wxT("(NAME < '");
65d7ddc4 1978
ea24eeb2 1979 w += wxGetApp().Contact->Name;
94613352 1980 w += wxT("'");
108106cf 1981
e70e8f4c 1982 // If a query where string is currently set, append that criteria
ea24eeb2 1983 if (!wxGetApp().Contact->qryWhereStr.IsEmpty())
e70e8f4c 1984 {
94613352 1985 w += wxT(" AND (");
ea24eeb2 1986 w += wxGetApp().Contact->qryWhereStr;
94613352 1987 w += wxT(")");
e70e8f4c 1988 }
108106cf 1989
94613352 1990 w += wxT(")");
108106cf 1991
049977d0 1992 return(GetRec(w));
108106cf
JS
1993
1994} // CeditorDlg::GetPrevRec()
1995
1996
1997/*
1998 * This function is here to avoid duplicating this same code in both the
1999 * GetPrevRec() and GetNextRec() functions
2000 */
049977d0 2001bool CeditorDlg::GetRec(const wxString &whereStr)
108106cf 2002{
ea24eeb2
GT
2003 wxGetApp().Contact->SetWhereClause(whereStr);
2004 wxGetApp().Contact->SetOrderByClause(wxT("NAME"));
e70e8f4c 2005
ea24eeb2 2006 if (!wxGetApp().Contact->Query())
e70e8f4c
GT
2007 {
2008 wxString tStr;
f21b2fd8 2009 tStr = wxT("ODBC error during Query()\n\n");
74de91cc 2010 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 2011 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c 2012
a4054ad1 2013 return(FALSE);
e70e8f4c
GT
2014 }
2015
ea24eeb2 2016 if (wxGetApp().Contact->GetNext())
e70e8f4c
GT
2017 {
2018 PutData();
a4054ad1 2019 return(TRUE);
e70e8f4c
GT
2020 }
2021 else
a4054ad1 2022 return(FALSE);
108106cf
JS
2023} // CeditorDlg::GetRec()
2024
2025
2026
2027/*
2028 * CparameterDlg constructor
2029 */
e3065973
JS
2030
2031BEGIN_EVENT_TABLE(CparameterDlg, wxDialog)
65d7ddc4
GT
2032 EVT_BUTTON(PARAMETER_DIALOG_SAVE, CparameterDlg::OnButton)
2033 EVT_BUTTON(PARAMETER_DIALOG_CANCEL, CparameterDlg::OnButton)
e3065973
JS
2034 EVT_CLOSE(CparameterDlg::OnCloseWindow)
2035END_EVENT_TABLE()
2036
94613352 2037CparameterDlg::CparameterDlg(wxWindow *parent) : wxDialog (parent, PARAMETER_DIALOG, wxT("ODBC parameter settings"), wxPoint(-1, -1), wxSize(400, 325))
108106cf 2038{
e70e8f4c
GT
2039 // Since the ::OnCommand() function is overridden, this prevents the widget
2040 // detection in ::OnCommand() until all widgets have been initialized to prevent
2041 // uninitialized pointers from crashing the program
a4054ad1 2042 widgetPtrsSet = FALSE;
e70e8f4c 2043
94613352
GT
2044 pParamODBCSourceMsg = new wxStaticText(this, PARAMETER_DIALOG_SOURCE_MSG, wxT("ODBC data sources:"), wxPoint( 10, 10), wxSize( -1, -1), 0, wxT("ParamODBCSourceMsg"));
2045 pParamODBCSourceList = new wxListBox(this, PARAMETER_DIALOG_SOURCE_LISTBOX, wxPoint( 10, 29), wxSize(285, 150), 0, 0, wxLB_SINGLE|wxLB_ALWAYS_SB, wxDefaultValidator, wxT("ParamODBCSourceList"));
2046 pParamUserNameMsg = new wxStaticText(this, PARAMETER_DIALOG_NAME_MSG, wxT("Database user name:"), wxPoint( 10, 193), wxSize( -1, -1), 0, wxT("ParamUserNameMsg"));
2047 pParamUserNameTxt = new wxTextCtrl(this, PARAMETER_DIALOG_NAME_TEXT, wxT(""), wxPoint(10, 209), wxSize( 140, 25), 0, wxDefaultValidator, wxT("ParamUserNameTxt"));
2048 pParamPasswordMsg = new wxStaticText(this, PARAMETER_DIALOG_PASSWORD_MSG, wxT("Password:"), wxPoint(156, 193), wxSize( -1, -1), 0, wxT("ParamPasswordMsg"));
2049 pParamPasswordTxt = new wxTextCtrl(this, PARAMETER_DIALOG_PASSWORD_TEXT, wxT(""), wxPoint(156, 209), wxSize( 140, 25), 0, wxDefaultValidator, wxT("ParamPasswordTxt"));
2050 pParamDirPathMsg = new wxStaticText(this, PARAMETER_DIALOG_DIRPATH_MSG, wxT("Directory:"), wxPoint( 10, 243), wxSize( -1, -1), 0, wxT("ParamDirPathMsg"));
2051 pParamDirPathTxt = new wxTextCtrl(this, PARAMETER_DIALOG_DIRPATH_TEXT, wxT(""), wxPoint( 10, 259), wxSize(140, 25), 0, wxDefaultValidator, wxT("ParamDirPathTxt"));
2052 pParamSaveBtn = new wxButton(this, PARAMETER_DIALOG_SAVE, wxT("&Save"), wxPoint(310, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("ParamSaveBtn"));
2053 pParamCancelBtn = new wxButton(this, PARAMETER_DIALOG_CANCEL, wxT("C&ancel"), wxPoint(310, 66), wxSize( 70, 35), 0, wxDefaultValidator, wxT("ParamCancelBtn"));
e70e8f4c
GT
2054
2055 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
2056 // handle all widget processing
a4054ad1 2057 widgetPtrsSet = TRUE;
e70e8f4c 2058
a4054ad1 2059 saved = FALSE;
e70e8f4c
GT
2060 savedParamSettings = wxGetApp().params;
2061
2062 Centre(wxBOTH);
2063 PutData();
2064 ShowModal();
108106cf
JS
2065} // CparameterDlg constructor
2066
2067
e3065973 2068void CparameterDlg::OnCloseWindow(wxCloseEvent& event)
108106cf 2069{
e70e8f4c
GT
2070 // Put any additional checking necessary to make certain it is alright
2071 // to close the program here that is not done elsewhere
2072 if (!saved)
2073 {
94613352 2074 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 2075
e70e8f4c 2076 if (!Ok)
e3065973
JS
2077 {
2078 event.Veto();
e70e8f4c 2079 return;
e3065973 2080 }
3ca6a5f0 2081
e70e8f4c
GT
2082 wxGetApp().params = savedParamSettings;
2083 }
108106cf 2084
e70e8f4c
GT
2085 if (GetParent() != NULL)
2086 GetParent()->SetFocus();
e3065973 2087
3ca6a5f0
BP
2088 while (wxIsBusy())
2089 wxEndBusyCursor();
2090
a4054ad1 2091 Show(FALSE);
3ca6a5f0
BP
2092 SetReturnCode(0); // added so BoundsChecker would not report use of uninitialized variable
2093
2094 this->Destroy();
2095} // CparameterDlg::OnCloseWindow()
108106cf
JS
2096
2097
65d7ddc4
GT
2098void CparameterDlg::OnButton( wxCommandEvent &event )
2099{
e70e8f4c
GT
2100 wxWindow *win = (wxWindow*) event.GetEventObject();
2101 OnCommand( *win, event );
65d7ddc4
GT
2102}
2103
3ca6a5f0 2104
74de91cc 2105void CparameterDlg::OnCommand(wxWindow& win, wxCommandEvent& WXUNUSED(event))
108106cf 2106{
e70e8f4c
GT
2107 wxString widgetName;
2108
2109 widgetName = win.GetName();
2110
2111 if (!widgetPtrsSet)
2112 return;
2113
2114 if (widgetName == pParamSaveBtn->GetName())
2115 {
2116 if (Save())
2117 {
2118 wxString tStr;
94613352 2119 tStr = wxT("Database parameters have been saved.");
e70e8f4c 2120 if (GetParent() != NULL) // The parameter dialog was not called during startup due to a missing cfg file
94613352
GT
2121 tStr += wxT("\nNew parameters will take effect the next time the program is started.");
2122 wxMessageBox(tStr,wxT("Notice..."),wxOK | wxICON_INFORMATION);
a4054ad1 2123 saved = TRUE;
e70e8f4c
GT
2124 Close();
2125 }
2126 return;
2127 }
2128
2129 if (widgetName == pParamCancelBtn->GetName())
2130 {
2131 Close();
2132 return;
2133 }
108106cf
JS
2134} // CparameterDlg::OnCommand()
2135
2136
1fc5dd6f 2137bool CparameterDlg::PutData()
108106cf 2138{
e70e8f4c
GT
2139 // Fill the data source list box
2140 FillDataSourceList();
2141
2142 // Fill in the fields from the params object
2143 if (wxGetApp().params.ODBCSource && wxStrlen(wxGetApp().params.ODBCSource))
f369dd4f
GT
2144 {
2145 int index = pParamODBCSourceList->FindString(wxGetApp().params.ODBCSource);
2146 if (index != -1)
2147 pParamODBCSourceList->SetSelection(index);
2148 }
e70e8f4c
GT
2149 pParamUserNameTxt->SetValue(wxGetApp().params.UserName);
2150 pParamPasswordTxt->SetValue(wxGetApp().params.Password);
2151 pParamDirPathTxt->SetValue(wxGetApp().params.DirPath);
a4054ad1 2152 return TRUE;
108106cf
JS
2153} // CparameterDlg::PutData()
2154
2155
1fc5dd6f 2156bool CparameterDlg::GetData()
108106cf 2157{
e70e8f4c 2158 wxString tStr;
94613352 2159 if (pParamODBCSourceList->GetStringSelection() != wxT(""))
e70e8f4c
GT
2160 {
2161 tStr = pParamODBCSourceList->GetStringSelection();
2162 if (tStr.Length() > (sizeof(wxGetApp().params.ODBCSource)-1))
2163 {
2164 wxString errmsg;
94613352
GT
2165 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());
2166 wxMessageBox(errmsg,wxT("Internal program error..."),wxOK | wxICON_EXCLAMATION);
a4054ad1 2167 return FALSE;
e70e8f4c 2168 }
f6bcfd97 2169 wxStrcpy(wxGetApp().params.ODBCSource, tStr);
e70e8f4c
GT
2170 }
2171 else
a4054ad1 2172 return FALSE;
e70e8f4c
GT
2173
2174 tStr = pParamUserNameTxt->GetValue();
2175 if (tStr.Length() > (sizeof(wxGetApp().params.UserName)-1))
2176 {
2177 wxString errmsg;
94613352
GT
2178 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());
2179 wxMessageBox(errmsg,wxT("Internal program error..."),wxOK | wxICON_EXCLAMATION);
a4054ad1 2180 return FALSE;
e70e8f4c 2181 }
f6bcfd97 2182 wxStrcpy(wxGetApp().params.UserName, tStr);
e70e8f4c
GT
2183
2184 tStr = pParamPasswordTxt->GetValue();
2185 if (tStr.Length() > (sizeof(wxGetApp().params.Password)-1))
2186 {
2187 wxString errmsg;
94613352
GT
2188 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());
2189 wxMessageBox(errmsg,wxT("Internal program error..."),wxOK | wxICON_EXCLAMATION);
a4054ad1 2190 return FALSE;
e70e8f4c 2191 }
f6bcfd97 2192 wxStrcpy(wxGetApp().params.Password,tStr);
e70e8f4c
GT
2193
2194 tStr = pParamDirPathTxt->GetValue();
94613352 2195 tStr.Replace(wxT("\\"),wxT("/"));
e70e8f4c
GT
2196 if (tStr.Length() > (sizeof(wxGetApp().params.DirPath)-1))
2197 {
2198 wxString errmsg;
94613352
GT
2199 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());
2200 wxMessageBox(errmsg,wxT("Internal program error..."),wxOK | wxICON_EXCLAMATION);
a4054ad1 2201 return FALSE;
e70e8f4c 2202 }
f6bcfd97 2203 wxStrcpy(wxGetApp().params.DirPath,tStr);
a4054ad1 2204 return TRUE;
108106cf
JS
2205} // CparameterDlg::GetData()
2206
2207
1fc5dd6f 2208bool CparameterDlg::Save()
108106cf 2209{
049977d0
GT
2210 // Copy the current params in case user cancels changing
2211 // the params, so that we can reset them.
e70e8f4c
GT
2212 if (!GetData())
2213 {
049977d0 2214 wxGetApp().params = savedParamSettings;
a4054ad1 2215 return FALSE;
e70e8f4c
GT
2216 }
2217
049977d0 2218 wxGetApp().WriteParamFile(wxGetApp().params);
e70e8f4c 2219
a4054ad1 2220 return TRUE;
108106cf
JS
2221} // CparameterDlg::Save()
2222
2223
2224void CparameterDlg::FillDataSourceList()
2225{
94613352
GT
2226 wxChar Dsn[SQL_MAX_DSN_LENGTH + 1];
2227 wxChar DsDesc[255];
e70e8f4c 2228 wxStringList strList;
108106cf 2229
049977d0
GT
2230 while (wxDbGetDataSource(wxGetApp().DbConnectInf->GetHenv(), Dsn,
2231 SQL_MAX_DSN_LENGTH+1, DsDesc, 255))
e70e8f4c 2232 strList.Add(Dsn);
108106cf 2233
e70e8f4c 2234 strList.Sort();
94613352
GT
2235 strList.Add(wxT(""));
2236 wxChar **p = strList.ListToArray();
108106cf 2237
e70e8f4c 2238 int i;
f6bcfd97 2239 for (i = 0; wxStrlen(p[i]); i++)
e70e8f4c 2240 pParamODBCSourceList->Append(p[i]);
3ca6a5f0 2241
ea24eeb2 2242 wxDELETEA(p);
3fe813a9 2243} // CparameterDlg::FillDataSourceList()
108106cf
JS
2244
2245
f6fcbb63
RR
2246BEGIN_EVENT_TABLE(CqueryDlg, wxDialog)
2247 EVT_BUTTON(-1, 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) :
2255 wxDialog (parent, QUERY_DIALOG, wxT("Query"), wxPoint(-1, -1), wxSize(480, 360))
108106cf 2256{
e70e8f4c
GT
2257 wxBeginBusyCursor();
2258
2259 colInf = 0;
2260 dbTable = 0;
2261 masterTableName = tblName[0];
a4054ad1 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"));
2278 pQueryNotMsg = new wxStaticText(this, QUERY_DIALOG_NOT_MSG, wxT("NOT"), wxPoint(268, 10), wxSize( -1, -1), 0, wxT("QueryNotMsg"));
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
2292 pQueryOperatorMsg = new wxStaticText(this, QUERY_DIALOG_OP_MSG, wxT("Operator:"), wxPoint(305, 10), wxSize( -1, -1), 0, wxT("QueryOperatorMsg"));
2293 pQueryOperatorChoice = new wxChoice(this, QUERY_DIALOG_OP_CHOICE, wxPoint(305, 27), wxSize( 80, 27), 9, choice_strings, 0, wxDefaultValidator, wxT("QueryOperatorChoice"));
2294 pQueryCol2Msg = new wxStaticText(this, QUERY_DIALOG_COL2_MSG, wxT("Column 2:"), wxPoint( 10, 65), wxSize( 69, 16), 0, wxT("QueryCol2Msg"));
2295 pQueryCol2Choice = new wxChoice(this, QUERY_DIALOG_COL2_CHOICE, wxPoint( 10, 82), wxSize(250, 27), 0, 0, 0, wxDefaultValidator, wxT("QueryCol2Choice"));
2296 pQuerySqlWhereMsg = new wxStaticText(this, QUERY_DIALOG_WHERE_MSG, wxT("SQL where clause:"), wxPoint( 10, 141), wxSize( -1, -1), 0, wxT("QuerySqlWhereMsg"));
2297 pQuerySqlWhereMtxt = new wxTextCtrl(this, QUERY_DIALOG_WHERE_TEXT, wxT(""), wxPoint( 10, 159), wxSize(377, 134), wxTE_MULTILINE, wxDefaultValidator, wxT("QuerySqlWhereMtxt"));
2298 pQueryAddBtn = new wxButton(this, QUERY_DIALOG_ADD, wxT("&Add"), wxPoint(406, 24), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryAddBtn"));
2299 pQueryAndBtn = new wxButton(this, QUERY_DIALOG_AND, wxT("A&nd"), wxPoint(406, 58), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryAndBtn"));
2300 pQueryOrBtn = new wxButton(this, QUERY_DIALOG_OR, wxT("&Or"), wxPoint(406, 92), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryOrBtn"));
2301 pQueryLParenBtn = new wxButton(this, QUERY_DIALOG_LPAREN, wxT("("), wxPoint(406, 126), wxSize( 26, 26), 0, wxDefaultValidator, wxT("QueryLParenBtn"));
2302 pQueryRParenBtn = new wxButton(this, QUERY_DIALOG_RPAREN, wxT(")"), wxPoint(436, 126), wxSize( 26, 26), 0, wxDefaultValidator, wxT("QueryRParenBtn"));
2303 pQueryDoneBtn = new wxButton(this, QUERY_DIALOG_DONE, wxT("&Done"), wxPoint(406, 185), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryDoneBtn"));
2304 pQueryClearBtn = new wxButton(this, QUERY_DIALOG_CLEAR, wxT("C&lear"), wxPoint(406, 218), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryClearBtn"));
2305 pQueryCountBtn = new wxButton(this, QUERY_DIALOG_COUNT, wxT("&Count"), wxPoint(406, 252), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryCountBtn"));
2306 pQueryValue1Msg = new wxStaticText(this, QUERY_DIALOG_VALUE1_MSG, wxT("Value:"), wxPoint(277, 66), wxSize( -1, -1), 0, wxT("QueryValue1Msg"));
2307 pQueryValue1Txt = new wxTextCtrl(this, QUERY_DIALOG_VALUE1_TEXT, wxT(""), wxPoint(277, 83), wxSize(108, 25), 0, wxDefaultValidator, wxT("QueryValue1Txt"));
2308 pQueryValue2Msg = new wxStaticText(this, QUERY_DIALOG_VALUE2_MSG, wxT("AND"), wxPoint(238, 126), wxSize( -1, -1), 0, wxT("QueryValue2Msg"));
2309 pQueryValue2Txt = new wxTextCtrl(this, QUERY_DIALOG_VALUE2_TEXT, wxT(""), wxPoint(277, 120), wxSize(108, 25), 0, wxDefaultValidator, wxT("QueryValue2Txt"));
2310 pQueryHintGrp = new wxStaticBox(this, QUERY_DIALOG_HINT_GROUP, wxT(""), wxPoint( 10, 291), wxSize(377, 40), 0, wxT("QueryHintGrp"));
2311 pQueryHintMsg = new wxStaticText(this, QUERY_DIALOG_HINT_MSG, wxT(""), wxPoint( 16, 306), wxSize( -1, -1), 0, wxT("QueryHintMsg"));
e70e8f4c 2312
a4054ad1 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
a4054ad1
GT
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
a4054ad1
GT
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);
a4054ad1 2435 pQueryNotCheck->Enable(FALSE);
3ca6a5f0
BP
2436 break;
2437 default:
a4054ad1 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:
a4054ad1 2450 pQueryCol2Choice->Enable(TRUE);
3ca6a5f0
BP
2451 if (pQueryCol2Choice->GetSelection()) // Column name is highlighted
2452 {
a4054ad1
GT
2453 pQueryValue1Msg->Show(FALSE);
2454 pQueryValue1Txt->Show(FALSE);
3ca6a5f0
BP
2455 }
2456 else // "Value" is highlighted
2457 {
a4054ad1
GT
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);
a4054ad1
GT
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);
a4054ad1
GT
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 {
a4054ad1
GT
2492 pQueryValue1Msg->Show(FALSE);
2493 pQueryValue1Txt->Show(FALSE);
e70e8f4c
GT
2494 }
2495 else // "Value" is highlighted
2496 {
a4054ad1
GT
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
a4054ad1 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
a4054ad1 2671 bool quote = FALSE;
e70e8f4c
GT
2672 if (colInf[col1Idx].sqlDataType == SQL_VARCHAR ||
2673 oper == qryOpBEGINS ||
2674 oper == qryOpCONTAINS ||
2675 oper == qryOpLIKE)
a4054ad1 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);
a4054ad1 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
a4054ad1 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;
a4054ad1 2789 bool comma = FALSE;
69a2b59d
GT
2790
2791 s = langDBINF_DB_NAME;
2792 s += pDb->dbInf.dbmsName;
74de91cc 2793 s += wxT("\n");
69a2b59d
GT
2794
2795 s += langDBINF_DB_VER;
2796 s += pDb->dbInf.dbmsVer;
74de91cc 2797 s += wxT("\n");
69a2b59d
GT
2798
2799 s += langDBINF_DRIVER_NAME;
2800 s += pDb->dbInf.driverName;
74de91cc 2801 s += wxT("\n");
69a2b59d
GT
2802
2803 s += langDBINF_DRIVER_ODBC_VER;
2804 s += pDb->dbInf.odbcVer;
74de91cc 2805 s += wxT("\n");
69a2b59d
GT
2806
2807 s += langDBINF_DRIVER_MGR_ODBC_VER;
2808 s += pDb->dbInf.drvMgrOdbcVer;
74de91cc 2809 s += wxT("\n");
69a2b59d
GT
2810
2811 s += langDBINF_DRIVER_VER;
2812 s += pDb->dbInf.driverVer;
74de91cc 2813 s += wxT("\n");
69a2b59d
GT
2814
2815 s += langDBINF_SERVER_NAME;
2816 s += pDb->dbInf.serverName;
74de91cc 2817 s += wxT("\n");
69a2b59d
GT
2818
2819 s += langDBINF_FILENAME;
2820 s += pDb->dbInf.databaseName;
74de91cc 2821 s += wxT("\n");
69a2b59d
GT
2822
2823 s += langDBINF_OUTER_JOINS;
2824 s += pDb->dbInf.outerJoins;
74de91cc 2825 s += wxT("\n");
69a2b59d
GT
2826
2827 s += langDBINF_STORED_PROC;
2828 s += pDb->dbInf.procedureSupport;
74de91cc 2829 s += wxT("\n");
69a2b59d
GT
2830
2831 if (pDb->dbInf.maxConnections)
74de91cc 2832 t.sprintf(wxT("%s%d\n"), langDBINF_MAX_HDBC, pDb->dbInf.maxConnections);
69a2b59d 2833 else
74de91cc 2834 t.sprintf(wxT("%s%s\n"), langDBINF_MAX_HDBC, langDBINF_UNLIMITED);
69a2b59d
GT
2835 s += t;
2836
2837 if (pDb->dbInf.maxStmts)
74de91cc 2838 t.sprintf(wxT("%s%d\n"), langDBINF_MAX_HSTMT, pDb->dbInf.maxStmts);
69a2b59d 2839 else
74de91cc 2840 t.sprintf(wxT("%s%s\n"), langDBINF_MAX_HSTMT, langDBINF_UNLIMITED);
69a2b59d
GT
2841 s += t;
2842
2843 s += langDBINF_API_LVL;
2844 switch(pDb->dbInf.apiConfLvl)
2845 {
2846 case SQL_OAC_NONE: s += langDBINF_NONE; break;
2847 case SQL_OAC_LEVEL1: s += langDBINF_LEVEL1; break;
2848 case SQL_OAC_LEVEL2: s += langDBINF_LEVEL2; break;
2849 }
74de91cc 2850 s += wxT("\n");
69a2b59d
GT
2851
2852 s += langDBINF_CLI_LVL;
2853 switch(pDb->dbInf.cliConfLvl)
2854 {
2855 case SQL_OSCC_NOT_COMPLIANT: s += langDBINF_NOT_COMPLIANT; break;
2856 case SQL_OSCC_COMPLIANT: s += langDBINF_COMPLIANT; break;
2857 }
74de91cc 2858 s += wxT("\n");
69a2b59d
GT
2859
2860 s += langDBINF_SQL_LVL;
2861 switch(pDb->dbInf.sqlConfLvl)
2862 {
2863 case SQL_OSC_MINIMUM: s += langDBINF_MIN_GRAMMAR; break;
2864 case SQL_OSC_CORE: s += langDBINF_CORE_GRAMMAR; break;
2865 case SQL_OSC_EXTENDED: s += langDBINF_EXT_GRAMMAR; break;
2866 }
74de91cc 2867 s += wxT("\n");
69a2b59d
GT
2868
2869 s += langDBINF_COMMIT_BEHAVIOR;
2870 switch(pDb->dbInf.cursorCommitBehavior)
2871 {
2872 case SQL_CB_DELETE: s += langDBINF_DELETE_CURSORS; break;
2873 case SQL_CB_CLOSE: s += langDBINF_CLOSE_CURSORS; break;
2874 case SQL_CB_PRESERVE: s += langDBINF_PRESERVE_CURSORS; break;
2875 }
74de91cc 2876 s += wxT("\n");
69a2b59d
GT
2877
2878 s += langDBINF_ROLLBACK_BEHAVIOR;
2879 switch(pDb->dbInf.cursorRollbackBehavior)
2880 {
2881 case SQL_CB_DELETE: s += langDBINF_DELETE_CURSORS; break;
2882 case SQL_CB_CLOSE: s += langDBINF_CLOSE_CURSORS; break;
2883 case SQL_CB_PRESERVE: s += langDBINF_PRESERVE_CURSORS; break;
2884 }
74de91cc 2885 s += wxT("\n");
69a2b59d
GT
2886
2887 s += langDBINF_SUPP_NOT_NULL;
2888 switch(pDb->dbInf.supportNotNullClause)
2889 {
2890 case SQL_NNC_NULL: s += langNO; break;
2891 case SQL_NNC_NON_NULL: s += langYES; break;
2892 }
74de91cc 2893 s += wxT("\n");
69a2b59d
GT
2894
2895 s += langDBINF_SUPP_IEF;
2896 s += pDb->dbInf.supportIEF;
74de91cc 2897 s += wxT("\n");
69a2b59d
GT
2898
2899 // DEFAULT setting for "Transaction Isolation Level"
2900 s += langDBINF_TXN_ISOLATION;
2901 switch(pDb->dbInf.txnIsolation)
2902 {
2903 case SQL_TXN_READ_UNCOMMITTED: s += langDBINF_READ_UNCOMMITTED; break;
2904 case SQL_TXN_READ_COMMITTED: s += langDBINF_READ_COMMITTED; break;
2905 case SQL_TXN_REPEATABLE_READ: s += langDBINF_REPEATABLE_READ; break;
2906 case SQL_TXN_SERIALIZABLE: s += langDBINF_SERIALIZABLE; break;
3f030b48 2907#ifdef ODBC_V20
69a2b59d
GT
2908 case SQL_TXN_VERSIONING: s += langDBINF_VERSIONING; break;
2909#endif
2910 }
74de91cc 2911 s += wxT("\n");
69a2b59d
GT
2912
2913 // CURRENT setting for "Transaction Isolation Level"
2914 long txnIsoLvl;
2915 s += langDBINF_TXN_ISOLATION_CURR;
2916 if (SQLGetConnectOption(pDb->GetHDBC(),SQL_TXN_ISOLATION,&txnIsoLvl) == SQL_SUCCESS)
2917 {
2918 switch(txnIsoLvl)
2919 {
2920 case SQL_TXN_READ_UNCOMMITTED: s += langDBINF_READ_UNCOMMITTED; break;
2921 case SQL_TXN_READ_COMMITTED: s += langDBINF_READ_COMMITTED; break;
2922 case SQL_TXN_REPEATABLE_READ: s += langDBINF_REPEATABLE_READ; break;
2923 case SQL_TXN_SERIALIZABLE: s += langDBINF_SERIALIZABLE; break;
3f030b48 2924#ifdef ODBC_V20
69a2b59d
GT
2925 case SQL_TXN_VERSIONING: s += langDBINF_VERSIONING; break;
2926#endif
2927 }
2928 }
74de91cc 2929 s += wxT("\n");
69a2b59d 2930
abfcca57
JJ
2931#ifdef __VMS__
2932#pragma message disable incboodep
2933#endif
a4054ad1 2934 comma = FALSE;
69a2b59d
GT
2935 s += langDBINF_TXN_ISOLATION_OPTS;
2936 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_READ_UNCOMMITTED)
2937 {s += langDBINF_READ_UNCOMMITTED; comma++;}
2938 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_READ_COMMITTED)
74de91cc 2939 {if (comma++) s += wxT(", "); s += langDBINF_READ_COMMITTED;}
69a2b59d 2940 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_REPEATABLE_READ)
74de91cc 2941 {if (comma++) s += wxT(", "); s += langDBINF_REPEATABLE_READ;}
69a2b59d 2942 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_SERIALIZABLE)
74de91cc 2943 {if (comma++) s += wxT(", "); s += langDBINF_SERIALIZABLE;}
3f030b48 2944#ifdef ODBC_V20
69a2b59d 2945 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_VERSIONING)
74de91cc 2946 {if (comma++) s += wxT(", "); s += langDBINF_VERSIONING;}
69a2b59d 2947#endif
74de91cc 2948 s += wxT("\n");
69a2b59d 2949
a4054ad1 2950 comma = FALSE;
69a2b59d
GT
2951 s += langDBINF_FETCH_DIRS;
2952 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_NEXT)
2953 {s += langDBINF_NEXT; comma++;}
2954 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_PRIOR)
74de91cc 2955 {if (comma++) s += wxT(", "); s += langDBINF_PREV;}
69a2b59d 2956 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_FIRST)
74de91cc 2957 {if (comma++) s += wxT(", "); s += langDBINF_FIRST;}
69a2b59d 2958 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_LAST)
74de91cc 2959 {if (comma++) s += wxT(", "); s += langDBINF_LAST;}
69a2b59d 2960 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_ABSOLUTE)
74de91cc 2961 {if (comma++) s += wxT(", "); s += langDBINF_ABSOLUTE;}
69a2b59d 2962 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_RELATIVE)
74de91cc 2963 {if (comma++) s += wxT(", "); s += langDBINF_RELATIVE;}
3f030b48 2964#ifdef ODBC_V20
69a2b59d 2965 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_RESUME)
74de91cc 2966 {if (comma++) s += wxT(", "); s += langDBINF_RESUME;}
69a2b59d
GT
2967#endif
2968 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_BOOKMARK)
74de91cc
JS
2969 {if (comma++) s += wxT(", "); s += langDBINF_BOOKMARK;}
2970 s += wxT("\n");
69a2b59d 2971
a4054ad1 2972 comma = FALSE;
69a2b59d
GT
2973 s += langDBINF_LOCK_TYPES;
2974 if (pDb->dbInf.lockTypes & SQL_LCK_NO_CHANGE)
2975 {s += langDBINF_NO_CHANGE; comma++;}
2976 if (pDb->dbInf.lockTypes & SQL_LCK_EXCLUSIVE)
74de91cc 2977 {if (comma++) s += wxT(", "); s += langDBINF_EXCLUSIVE;}
69a2b59d 2978 if (pDb->dbInf.lockTypes & SQL_LCK_UNLOCK)
74de91cc
JS
2979 {if (comma++) s += wxT(", "); s += langDBINF_UNLOCK;}
2980 s += wxT("\n");
69a2b59d 2981
a4054ad1 2982 comma = FALSE;
69a2b59d
GT
2983 s += langDBINF_POS_OPERS;
2984 if (pDb->dbInf.posOperations & SQL_POS_POSITION)
2985 {s += langDBINF_POSITION; comma++;}
2986 if (pDb->dbInf.posOperations & SQL_POS_REFRESH)
74de91cc 2987 {if (comma++) s += wxT(", "); s += langDBINF_REFRESH;}
69a2b59d 2988 if (pDb->dbInf.posOperations & SQL_POS_UPDATE)
74de91cc 2989 {if (comma++) s += wxT(", "); s += langDBINF_UPD;}
69a2b59d 2990 if (pDb->dbInf.posOperations & SQL_POS_DELETE)
74de91cc 2991 {if (comma++) s += wxT(", "); s += langDBINF_DEL;}
69a2b59d 2992 if (pDb->dbInf.posOperations & SQL_POS_ADD)
74de91cc
JS
2993 {if (comma++) s += wxT(", "); s += langDBINF_ADD;}
2994 s += wxT("\n");
69a2b59d 2995
a4054ad1 2996 comma = FALSE;
69a2b59d
GT
2997 s += langDBINF_POS_STMTS;
2998 if (pDb->dbInf.posStmts & SQL_PS_POSITIONED_DELETE)
2999 {s += langDBINF_POS_DEL; comma++;}
3000 if (pDb->dbInf.posStmts & SQL_PS_POSITIONED_UPDATE)
74de91cc 3001 {if (comma++) s += wxT(", "); s += langDBINF_POS_UPD;}
69a2b59d 3002 if (pDb->dbInf.posStmts & SQL_PS_SELECT_FOR_UPDATE)
74de91cc
JS
3003 {if (comma++) s += wxT(", "); s += langDBINF_SELECT_FOR_UPD;}
3004 s += wxT("\n");
69a2b59d 3005
a4054ad1 3006 comma = FALSE;
69a2b59d
GT
3007 s += langDBINF_SCROLL_CONCURR;
3008 if (pDb->dbInf.scrollConcurrency & SQL_SCCO_READ_ONLY)
3009 {s += langDBINF_READ_ONLY; comma++;}
3010 if (pDb->dbInf.scrollConcurrency & SQL_SCCO_LOCK)
74de91cc 3011 {if (comma++) s += wxT(", "); s += langDBINF_LOCK;}
69a2b59d 3012 if (pDb->dbInf.scrollConcurrency & SQL_SCCO_OPT_ROWVER)
74de91cc 3013 {if (comma++) s += wxT(", "); s += langDBINF_OPT_ROWVER;}
69a2b59d 3014 if (pDb->dbInf.scrollConcurrency & SQL_SCCO_OPT_VALUES)
74de91cc
JS
3015 {if (comma++) s += wxT(", "); s += langDBINF_OPT_VALUES;}
3016 s += wxT("\n");
69a2b59d 3017
a4054ad1 3018 comma = FALSE;
69a2b59d
GT
3019 s += langDBINF_SCROLL_OPTS;
3020 if (pDb->dbInf.scrollOptions & SQL_SO_FORWARD_ONLY)
3021 {s += langDBINF_FWD_ONLY; comma++;}
3022 if (pDb->dbInf.scrollOptions & SQL_SO_STATIC)
74de91cc 3023 {if (comma++) s += wxT(", "); s += langDBINF_STATIC;}
69a2b59d 3024 if (pDb->dbInf.scrollOptions & SQL_SO_KEYSET_DRIVEN)
74de91cc 3025 {if (comma++) s += wxT(", "); s += langDBINF_KEYSET_DRIVEN;}
69a2b59d 3026 if (pDb->dbInf.scrollOptions & SQL_SO_DYNAMIC)
74de91cc 3027 {if (comma++) s += wxT(", "); s += langDBINF_DYNAMIC;}
69a2b59d 3028 if (pDb->dbInf.scrollOptions & SQL_SO_MIXED)
74de91cc
JS
3029 {if (comma++) s += wxT(", "); s += langDBINF_MIXED;}
3030 s += wxT("\n");
69a2b59d 3031
a4054ad1 3032 comma = FALSE;
69a2b59d
GT
3033 s += langDBINF_STATIC_SENS;
3034 if (pDb->dbInf.staticSensitivity & SQL_SS_ADDITIONS)
3035 {s += langDBINF_ADDITIONS; comma++;}
3036 if (pDb->dbInf.staticSensitivity & SQL_SS_DELETIONS)
74de91cc 3037 {if (comma++) s += wxT(", "); s += langDBINF_DELETIONS;}
69a2b59d 3038 if (pDb->dbInf.staticSensitivity & SQL_SS_UPDATES)
74de91cc
JS
3039 {if (comma++) s += wxT(", "); s += langDBINF_UPDATES;}
3040 s += wxT("\n");
abfcca57
JJ
3041#ifdef __VMS__
3042#pragma message enable incboodep
3043#endif
69a2b59d
GT
3044
3045
3046 s += langDBINF_TXN_CAPABLE;
3047 switch(pDb->dbInf.txnCapable)
3048 {
3049 case SQL_TC_NONE: s += langNO; break;
3050 case SQL_TC_DML: s += langDBINF_DML_ONLY; break;
3051 case SQL_TC_DDL_COMMIT: s += langDBINF_DDL_COMMIT; break;
3052 case SQL_TC_DDL_IGNORE: s += langDBINF_DDL_IGNORE; break;
3053 case SQL_TC_ALL: s += langDBINF_DDL_AND_DML; break;
3054 }
74de91cc 3055 s += wxT("\n");
69a2b59d 3056
74de91cc 3057 t.sprintf(wxT("%s%lu\n"), langDBINF_LOGIN_TIMEOUT, pDb->dbInf.loginTimeout);
69a2b59d
GT
3058 s += t;
3059
3060 // Oracle specific information
3061 if (pDb->Dbms() == dbmsORACLE)
3062 {
74de91cc 3063 s += wxT("\n");
69a2b59d 3064 s += langDBINF_ORACLE_BANNER;
74de91cc 3065 s += wxT("\n");
69a2b59d
GT
3066
3067 // Oracle cache hit ratio
3068 SDWORD cb;
3069 ULONG dbBlockGets;
74de91cc 3070 pDb->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'db block gets'"));
69a2b59d
GT
3071 pDb->GetNext();
3072 if (pDb->GetData(1, SQL_C_ULONG, &dbBlockGets, 0, &cb))
3073 {
74de91cc 3074 t.sprintf(wxT("%s: %lu\n"), langDBINF_DB_BLOCK_GETS, dbBlockGets);
69a2b59d
GT
3075 s += t;
3076 }
3077
3078 ULONG consistentGets;
74de91cc 3079 pDb->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'consistent gets'"));
69a2b59d
GT
3080 pDb->GetNext();
3081 if (pDb->GetData(1, SQL_C_ULONG, &consistentGets, 0, &cb))
3082 {
74de91cc 3083 t.sprintf(wxT("%s: %lu\n"), langDBINF_CONSISTENT_GETS, consistentGets);
69a2b59d
GT
3084 s += t;
3085 }
3086
3087 ULONG physReads;
74de91cc 3088 pDb->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'physical reads'"));
69a2b59d
GT
3089 pDb->GetNext();
3090 if (pDb->GetData(1, SQL_C_ULONG, &physReads, 0, &cb))
3091 {
74de91cc 3092 t.sprintf(wxT("%s: %lu\n"), langDBINF_PHYSICAL_READS, physReads);
69a2b59d
GT
3093 s += t;
3094 }
3095
3096 ULONG hitRatio = (ULONG)((1.00 - ((float)physReads / (float)(dbBlockGets + consistentGets))) * 100.00);
74de91cc 3097 t.sprintf(wxT("*** %s: %lu%%\n"), langDBINF_CACHE_HIT_RATIO, hitRatio);
69a2b59d
GT
3098 s += t;
3099
3100 // Tablespace information
74de91cc 3101 s += wxT("\n");
69a2b59d 3102 s += langDBINF_TABLESPACE_IO;
74de91cc 3103 s += wxT("\n");
69a2b59d
GT
3104 ULONG physWrites;
3105 char tablespaceName[257];
74de91cc 3106 pDb->ExecSql(wxT("SELECT NAME,PHYRDS,PHYWRTS FROM V$DATAFILE, V$FILESTAT WHERE V$DATAFILE.FILE# = V$FILESTAT.FILE#"));
69a2b59d
GT
3107 while (pDb->GetNext())
3108 {
3109 pDb->GetData(1, SQL_C_CHAR, tablespaceName, 257, &cb);
3110 pDb->GetData(2, SQL_C_ULONG, &physReads, 0, &cb);
3111 pDb->GetData(3, SQL_C_ULONG, &physWrites, 0, &cb);
74de91cc 3112 t.sprintf(wxT("%s\n\t%s: %lu\t%s: %lu\n"), tablespaceName,
69a2b59d
GT
3113 langDBINF_PHYSICAL_READS, physReads, langDBINF_PHYSICAL_WRITES, physWrites);
3114 s += t;
3115 }
3116
74de91cc 3117 s += wxT("\n");
69a2b59d 3118 }
3f030b48
GT
3119
3120 wxLogMessage(s);
3121
3122} // DisplayDbDiagnostics()
3123
f21b2fd8
GT
3124#if wxUSE_NEW_GRID
3125
3126BEGIN_EVENT_TABLE(DbGridFrame, wxFrame)
3127 // EVT_CLOSE(DbGridFrame::OnCloseWindow)
3128END_EVENT_TABLE()
3129
3130
3131DbGridFrame::DbGridFrame(wxWindow *parent)
3132 : wxFrame (parent, -1, wxT("Database Table"),
2f6c54eb 3133 wxDefaultPosition, wxSize(400, 325))
f21b2fd8 3134{
a4054ad1 3135 initialized = FALSE;
f21b2fd8
GT
3136}
3137
3138
3139void DbGridFrame::OnCloseWindow(wxCloseEvent& event)
3140{
3141 this->Destroy();
3142}
3143
3144
3145bool DbGridFrame::Initialize()
3146{
3147 wxGrid *grid = new wxGrid(this, -1, wxDefaultPosition);
3148
3149 grid->RegisterDataType(wxGRID_VALUE_DATETIME,
74de91cc 3150 new wxGridCellDateTimeRenderer(wxT("%d %b %Y")),
f21b2fd8
GT
3151 new wxGridCellTextEditor);
3152#ifdef CHOICEINT
3153 grid->RegisterDataType(wxGRID_VALUE_CHOICEINT,
3154 new wxGridCellEnumRenderer,
3155 new wxGridCellEnumEditor);
3156
3157 wxString NativeLangChoice( wxString::Format("%s:%s,%s,%s,%s,%s",wxGRID_VALUE_CHOICEINT,
3158 wxT("English"),
3159 wxT("French"),
3160 wxT("German"),
3161 wxT("Spanish"),
3162 wxT("Other") ));
3163#endif
3164
3165 // Columns must match the sequence specified in SetColDef() calls
3166 wxDbGridColInfo* cols =
3167 new wxDbGridColInfo( 0,wxGRID_VALUE_STRING,wxT("Name"),
3168 new wxDbGridColInfo( 1,wxGRID_VALUE_STRING,wxT("Address 1"),
3169 new wxDbGridColInfo( 2,wxGRID_VALUE_STRING,wxT("Address 2"),
3170 new wxDbGridColInfo( 3,wxGRID_VALUE_STRING,wxT("City"),
3171 new wxDbGridColInfo( 4,wxGRID_VALUE_STRING,wxT("State"),
3172 new wxDbGridColInfo( 5,wxGRID_VALUE_STRING,wxT("PostCode"),
3173 new wxDbGridColInfo( 6,wxGRID_VALUE_STRING,wxT("Country"),
3174 new wxDbGridColInfo( 7,wxGRID_VALUE_DBAUTO,wxT("Join Date"),
3175 new wxDbGridColInfo( 8,wxGRID_VALUE_BOOL, wxT("Developer"),
3176 new wxDbGridColInfo( 9,wxGRID_VALUE_NUMBER,wxT("Contributions"),
3177 new wxDbGridColInfo(10,wxGRID_VALUE_NUMBER,wxT("Lines Of Code"),
3178#ifdef CHOICEINT
3179 new wxDbGridColInfo(11,NativeLangChoice, wxT("Native Language"),NULL))))))))))));
3180#else
3181 new wxDbGridColInfo(11,wxGRID_VALUE_NUMBER,wxT("Native Language"),NULL))))))))))));
3182#endif
3183
3184 Ccontact *Contact = new Ccontact();
3185 //wxGetApp().Contact
3186
3187 if (!Contact)
3188 {
3189 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"), wxT("Error..."), wxOK | wxICON_EXCLAMATION);
a4054ad1 3190 return FALSE;
f21b2fd8
GT
3191 }
3192
3193 if (!Contact->Open())
3194 {
3195 if (Contact->GetDb()->TableExists(CONTACT_TABLE_NAME, Contact->GetDb()->GetUsername(),
3196 wxGetApp().DbConnectInf->GetDefaultDir()))
3197 {
3198 wxString tStr;
3199 tStr.Printf(wxT("Unable to open the table '%s'.\n\n"),CONTACT_TABLE_NAME);
74de91cc 3200 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8
GT
3201 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
3202 }
3203
a4054ad1 3204 return FALSE;
f21b2fd8
GT
3205 }
3206
3207 // Execute the following query using the cursor designated
3208 // for full table query
3209 Contact->SetRowMode(wxDbTable::WX_ROW_MODE_QUERY);
3210
3211 if (!Contact->Query())
3212 {
3213 wxString tStr;
3214 tStr = wxT("ODBC error during Query()\n\n");
74de91cc 3215 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 3216 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
a4054ad1 3217 return FALSE;
f21b2fd8
GT
3218 }
3219
3220 // No data has been read in from the database yet, so
3221 // we need to initialize the data members to valid values
3222 // so Fit() can correctly size the grid
3223 Contact->Initialize();
3224
a4054ad1 3225 wxDbGridTableBase* db = new wxDbGridTableBase(Contact, cols, wxUSE_QUERY, TRUE);
f21b2fd8
GT
3226
3227 delete cols;
3228
a4054ad1 3229 grid->SetTable(db,TRUE);
f21b2fd8 3230 grid->SetMargins(0, 0);
3f030b48 3231
f21b2fd8
GT
3232 grid->Fit();
3233 wxSize size = grid->GetSize();
3234 size.x += 10;
3235 size.y += 10;
3236 SetClientSize(size);
a4054ad1
GT
3237 initialized = TRUE;
3238 return TRUE;
f21b2fd8 3239} // DbGridFrame::Initialize()
3f030b48 3240
f21b2fd8 3241#endif // #if wxUSE_NEW_GRID
3f755e2d
GT
3242
3243/*
3244 TEST CODE FOR TESTING THE wxDbCreateDataSource() FUNCTION
3245
3246 int result = 0;
a4054ad1 3247 result = wxDbCreateDataSource(wxT("Microsoft Access Driver (*.mdb)"),wxT("GLT-TEST2"),wxT("GLT-Descrip"),FALSE,wxT(""),this);
3f755e2d
GT
3248 if (!result)
3249 {
3250 // check for errors caused by ConfigDSN based functions
3251 DWORD retcode = 0;
3252 WORD cb;
3253 wxChar errMsg[500+1];
94613352 3254 errMsg[0] = wxT('\0');
3f755e2d
GT
3255
3256 SQLInstallerError(1,&retcode,errMsg,500,&cb);
3257
94613352 3258 wxMessageBox(wxT("FAILED creating data source"),wxT("FAILED"));
3f755e2d
GT
3259 }
3260 else
94613352 3261 wxMessageBox(wxT("SUCCEEDED creating data source"),wxT("SUCCESS"));
3f755e2d
GT
3262*/
3263
3264