]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/odbc.cpp
controls can now be put in the toolbars (MSW only so far, preliminary version)
[wxWidgets.git] / src / common / odbc.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: odbc.cpp
3// Purpose: ODBC implementation
4// Author: Julian Smart, Olaf Klein (oklein@smallo.ruhr.de),
5// Patrick Halke (patrick@zaphod.ruhr.de)
6// Modified by:
7// Created: 04/01/98
8// RCS-ID: $Id$
9// Copyright: (c) Julian Smart and Markus Holzem
10// Licence: wxWindows license
11/////////////////////////////////////////////////////////////////////////////
12
13#ifdef __GNUG__
14#pragma implementation "odbc.h"
15#endif
16
17// For compilers that support precompilation, includes "wx.h".
18#include "wx/wxprec.h"
19
20#ifdef __BORLANDC__
21#pragma hdrstop
22#endif
23
24#include "wx/defs.h"
25
26// this code is old and shouldn't be used - use the new ODBC classes in db.cpp
27// and dbtable.cpp instead
28#define wxUSE_OLD_ODBC 0
29
30#if wxUSE_OLD_ODBC
31
32#ifdef __VISUALC__
33 #pragma warning(disable:4706) // assignment within conditional expression
34#endif // VC++
35
36#ifndef WX_PRECOMP
37#include "wx/utils.h"
38#include "wx/dialog.h"
39#endif
40
41#include "wx/string.h"
42#include "wx/odbc.h"
43
44#include <math.h>
45#include <stdlib.h>
46
47#if defined(__WXMSW__) && !defined(__WIN32__)
48#include <print.h>
49#endif
50
51HENV wxDatabase::hEnv = 0;
52int wxDatabase::refCount = 0;
53
54#if !USE_SHARED_LIBRARY
55IMPLEMENT_DYNAMIC_CLASS(wxDatabase, wxObject)
56IMPLEMENT_DYNAMIC_CLASS(wxQueryCol, wxObject)
57IMPLEMENT_DYNAMIC_CLASS(wxQueryField, wxObject)
58IMPLEMENT_DYNAMIC_CLASS(wxRecordSet, wxObject)
59#endif
60
61wxDatabase::wxDatabase(void)
62{
63 hDBC = 0;
64 username = NULL;
65 password = NULL;
66 datasource = NULL;
67 dbname = NULL;
68 connectstring = NULL;
69 isOpen = FALSE;
70 refCount ++;
71 retcode = 0;
72 username = NULL;
73 password = NULL;
74 err_occured = FALSE;
75
76 memset(sqlstate, 0, sizeof sqlstate);
77 memset(errmsg, 0, sizeof errmsg);
78
79 if (hEnv == 0)
80 {
81 retcode = SQLAllocEnv(&hEnv);
82
83 if (retcode != SQL_SUCCESS)
84 hEnv = 0;
85 }
86}
87
88wxDatabase::~wxDatabase(void)
89{
90 Close();
91 DeleteRecordSets(); // Added JACS
92
93 if (connectstring)
94 delete[] connectstring;
95 if (datasource)
96 delete[] datasource;
97 if (username)
98 delete[] username;
99 if (password)
100 delete[] password;
101 if (dbname)
102 delete[] dbname;
103
104 refCount --;
105 if (!refCount && hEnv)
106 {
107 retcode = SQLFreeEnv(hEnv);
108 hEnv = 0; // JACS 17/6
109 }
110}
111
112void wxDatabase::ErrorSnapshot(HSTMT hstmt)
113{
114 SWORD len = 0; // JACS: sometimes doesn't get filled in by SQLError.
115
116 err_occured = TRUE;
117 SQLError(hEnv, hDBC, hstmt, (unsigned char *)sqlstate, &nat_err, (unsigned char *)errmsg, SQL_MAX_MESSAGE_LENGTH-1, &len);
118 errmsg[len] = '\0';
119}
120
121bool wxDatabase::ErrorOccured(void)
122{
123 return err_occured;
124}
125
126char* wxDatabase::GetErrorMessage(void)
127{
128 return errmsg;
129}
130
131long wxDatabase::GetErrorNumber(void)
132{
133 return nat_err;
134}
135
136char* wxDatabase::GetErrorClass(void) {
137 return sqlstate;
138}
139
140bool wxDatabase::Open(char *thedatasource, bool WXUNUSED(exclusive),
141 bool WXUNUSED(readOnly), char *username, char *password)
142{
143 err_occured = FALSE;
144
145 if (isOpen)
146 return FALSE;
147
148 SetUsername(username);
149 SetPassword(password);
150 SetDataSource(thedatasource);
151
152 if (!hEnv)
153 return FALSE;
154
155 retcode = SQLAllocConnect(hEnv, &hDBC);
156 if (retcode != SQL_SUCCESS) {
157 hDBC = 0;
158 return FALSE;
159 }
160
161 retcode = SQLConnect(hDBC, (UCHAR FAR*)thedatasource, strlen(thedatasource), (UCHAR FAR*)username, strlen(username),
162 (UCHAR FAR*)password, strlen(password));
163
164 if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
165 ErrorSnapshot();
166 return FALSE;
167 }
168
169 isOpen = TRUE;
170
171 return TRUE;
172}
173
174bool wxDatabase::Close(void)
175{
176 // JACS: make sure the record set statements are all released.
177 ResetRecordSets();
178
179 err_occured = FALSE;
180 if (hDBC != 0)
181 {
182 retcode = SQLDisconnect(hDBC);
183
184 if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
185 ErrorSnapshot();
186 return FALSE;
187 }
188
189 retcode = SQLFreeConnect(hDBC);
190
191 hDBC = 0;
192 isOpen = FALSE;
193
194 return TRUE;
195 }
196
197 return FALSE;
198}
199
200// Database attributes
201char *wxDatabase::GetDatabaseName(void)
202{
203 err_occured = FALSE;
204 if (hDBC == 0)
205 return NULL;
206
207 char nameBuf[400];
208 int nameSize = 0;
209
210 retcode = SQLGetInfo(hDBC, SQL_DATABASE_NAME, (unsigned char*)nameBuf, sizeof(nameBuf), (short *)&nameSize);
211
212 if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
213 return NULL;
214
215 delete[] dbname;
216 dbname = NULL;
217
218 if (nameSize > 0)
219 {
220 dbname = copystring(nameBuf);
221 return dbname;
222 }
223 else
224 return NULL;
225}
226
227bool wxDatabase::CanUpdate(void)
228{
229 return FALSE;
230}
231
232bool wxDatabase::CanTransact(void)
233{
234 return FALSE;
235}
236
237bool wxDatabase::InWaitForDataSource(void)
238{
239 return FALSE;
240}
241
242void wxDatabase::SetLoginTimeout(long WXUNUSED(seconds))
243{
244}
245
246void wxDatabase::SetQueryTimeout(long WXUNUSED(seconds))
247{
248}
249
250void wxDatabase::SetSynchronousMode(bool WXUNUSED(synchronous))
251{
252}
253
254// Database operations
255bool wxDatabase::BeginTrans(void)
256{
257 return FALSE;
258}
259
260bool wxDatabase::CommitTrans(void)
261{
262 return FALSE;
263}
264
265bool wxDatabase::RollbackTrans(void)
266{
267 return FALSE;
268}
269
270void wxDatabase::Cancel(void)
271{
272}
273
274// Overridables
275void wxDatabase::OnSetOptions(wxRecordSet *WXUNUSED(recordSet))
276{
277}
278
279void wxDatabase::OnWaitForDataSource(bool WXUNUSED(stillExecuting))
280{
281}
282
283void wxDatabase::SetPassword(char *s)
284{
285 if (password)
286 delete[] password;
287 if (s)
288 {
289 password = copystring(s);
290 }
291 else
292 password = NULL;
293}
294
295void wxDatabase::SetUsername(char *s)
296{
297 delete[] username;
298
299 if (s)
300 username = copystring(s);
301 else
302 username = NULL;
303}
304
305void wxDatabase::SetDataSource(char *s)
306{
307 delete[] datasource;
308
309 if (s)
310 datasource = copystring(s);
311 else
312 datasource = NULL;
313}
314
315/*
316 * Added by JACS
317 */
318
319void wxDatabase::DeleteRecordSets(void)
320{
321 wxNode *node = recordSets.First();
322 while (node)
323 {
324 wxNode *next = node->Next();
325 wxRecordSet *rec = (wxRecordSet *)node->Data();
326 delete rec;
327 // The node is implicitly deleted by ~wxRecordSet
328 node = next;
329 }
330}
331
332void wxDatabase::ResetRecordSets(void)
333{
334 wxNode *node = recordSets.First();
335 while (node)
336 {
337 wxRecordSet *rec = (wxRecordSet *)node->Data();
338 rec->ReleaseHandle();
339
340 node = node->Next();
341 }
342}
343
344bool wxDatabase::GetInfo(long infoType, long *buf)
345{
346 short sz = 0;
347 retcode = SQLGetInfo(hDBC, (UWORD)infoType, (unsigned char*)buf, sizeof(buf), &sz);
348
349 if (retcode != SQL_ERROR)
350 return TRUE;
351 else
352 return FALSE;
353}
354
355bool wxDatabase::GetInfo(long infoType, char *buf, int bufSize)
356{
357 if (bufSize == -1)
358 bufSize = sizeof(buf);
359
360 short sz = 0;
361 retcode = SQLGetInfo(hDBC, (UWORD)infoType, (unsigned char*)buf, bufSize, &sz);
362
363 if (retcode != SQL_ERROR)
364 return TRUE;
365 else
366 return FALSE;
367}
368
369wxString wxDatabase::GetODBCVersionString(bool implementation)
370{
371 char buf[50];
372 if (!implementation)
373 {
374#ifdef SQL_SPEC_MAJOR
375 sprintf(buf, "%d%d.%d", (int)(SQL_SPEC_MAJOR/10), (int)(SQL_SPEC_MAJOR - (((int)(SQL_SPEC_MAJOR/10))*10)),
376 SQL_SPEC_MINOR);
377 return wxString(buf);
378#else
379 return wxString("00.00");
380#endif
381 }
382
383 bool noDBC = FALSE;
384 if (hDBC == 0)
385 {
386 noDBC = TRUE;
387 retcode = SQLAllocConnect(hEnv, &hDBC);
388 if (retcode != SQL_SUCCESS)
389 {
390 hDBC = 0;
391 return wxString("00.00");
392 }
393 }
394
395 int bufSize = sizeof(buf);
396
397 short sz = 0;
398 retcode = SQLGetInfo(hDBC, (UWORD)SQL_ODBC_VER, (unsigned char*)buf, bufSize, &sz);
399
400 if (hDBC != 0 && noDBC)
401 {
402 retcode = SQLFreeConnect(hDBC);
403 hDBC = 0;
404 }
405
406 if (retcode == SQL_ERROR)
407 return wxString("");
408 else
409 return wxString(buf);
410}
411
412float wxDatabase::GetODBCVersionFloat(bool implementation)
413{
414 if (!implementation)
415 {
416#ifdef SQL_SPEC_MAJOR
417 return (float)(SQL_SPEC_MAJOR + (SQL_SPEC_MINOR/100.0));
418#else
419 return 0.0;
420#endif
421 }
422
423 bool noDBC = FALSE;
424 if (hDBC == 0)
425 {
426 noDBC = TRUE;
427 retcode = SQLAllocConnect(hEnv, &hDBC);
428 if (retcode != SQL_SUCCESS)
429 {
430 hDBC = 0;
431 return (float)0.0;
432 }
433 }
434
435 char buf[50];
436 int bufSize = sizeof(buf);
437
438 short sz = 0;
439 retcode = SQLGetInfo(hDBC, (UWORD)SQL_ODBC_VER, (unsigned char*)buf, bufSize, &sz);
440
441 if (hDBC != 0 && noDBC)
442 {
443 retcode = SQLFreeConnect(hDBC);
444 hDBC = 0;
445 }
446
447 if (retcode == SQL_ERROR)
448 return 0.0;
449 else
450 return (float)atof(buf);
451}
452
453/*
454 * wxRecordSet
455 */
456
457wxRecordSet::wxRecordSet(wxDatabase *db, int typ, int opt):
458 cols(wxKEY_STRING)
459{
460 parentdb = db;
461 hStmt = 0;
462 nFields = 0;
463 nParams = 0;
464 recordFilter = NULL;
465 sortString = NULL;
466 retcode = 0;
467 cursor = 0;
468 tablename = NULL;
469 nCols = 0;
470 nRecords = 0;
471
472 type = typ;
473 options = opt;
474
475 // Added JACS
476 if (parentdb)
477 parentdb->GetRecordSets().Append(this);
478}
479
480wxRecordSet::~wxRecordSet(void)
481{
482 ReleaseHandle();
483
484 // JACS
485 if (parentdb)
486 parentdb->GetRecordSets().DeleteObject(this);
487
488 if (recordFilter)
489 delete[] recordFilter;
490 if (sortString)
491 delete[] sortString;
492 if (tablename)
493 delete[] tablename;
494}
495
496// If SQL is non-NULL, table and columns can be NULL.
497bool wxRecordSet::BeginQuery(int WXUNUSED(openType), char *WXUNUSED(sql), int WXUNUSED(options))
498{
499 // Needs to construct an appropriate SQL statement. By default
500 // (i.e. if table and columns are provided) then
501 // SELECT <columns> FROM <table>
502 // will be used.
503 if (!parentdb)
504 return FALSE;
505 if (!parentdb->GetHDBC())
506 return FALSE;
507
508 if (hStmt)
509 {
510 retcode = SQLFreeStmt(hStmt, SQL_DROP);
511 if (retcode == SQL_ERROR)
512 {
513 parentdb->ErrorSnapshot(hStmt);
514 return FALSE;
515 }
516 hStmt = 0;
517 }
518
519 retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
520 if (retcode != SQL_SUCCESS)
521 return FALSE;
522
523 return TRUE;
524}
525
526bool wxRecordSet::Query(char *columns, char *table, char *filter)
527{
528 // Needs to construct an appropriate SQL statement. By default
529 // (i.e. if table and columns are provided) then
530 // SELECT <columns> FROM <table>
531 // will be used.
532
533 char* thetable = table ? table : tablename;
534
535 if (!thetable)
536 return FALSE;
537 if (!columns)
538 return FALSE;
539
540 wxString query;
541
542 query += "SELECT ";
543 query += columns;
544 query += " FROM ";
545 query += thetable;
546
547 if (filter) {
548 query += " WHERE ";
549 query += filter;
550 }
551 retcode = SQLPrepare(hStmt, (UCHAR FAR *)query.GetData(), strlen(query.GetData()));
552 if (retcode != SQL_SUCCESS) {
553 parentdb->ErrorSnapshot(hStmt);
554 return FALSE;
555 }
556
557 retcode = SQLExecute(hStmt);
558
559 if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
560 parentdb->ErrorSnapshot(hStmt);
561 return FALSE;
562 }
563
564 return TRUE;
565}
566
567bool wxRecordSet::EndQuery(void)
568{
569 return TRUE;
570}
571
572void wxRecordSet::FillVars(int recnum) {
573 wxNode* node = cols.First();
574
575 do {
576 ((wxQueryCol*)node->Data())->FillVar(recnum);
577 } while ((node = node->Next()));
578}
579
580bool wxRecordSet::GetResultSet(void)
581{
582// long trash = SQL_NULL_DATA; // value added by JACS
583 long trash;
584 // contains the number of bytes transferred by SQLFetch()
585 // who needs this ?
586 wxNode *currow, *fetch, *curcol;
587
588 retcode = SQLNumResultCols(hStmt, &nCols);
589
590 if (!nCols)
591 return TRUE;
592
593 // delete old data first
594 cols.DeleteContents(TRUE);
595 cols.Clear();
596 fetchbuf.DeleteContents(TRUE);
597 fetchbuf.Clear();
598
599 nRecords = 0;
600 cursor = 0;
601
602 int i;
603 for (i=0; i<nCols; i++) {
604 char name[512];
605 short type, scale, nullable, namelen;
606 unsigned long len;
607
608 retcode = SQLDescribeCol(hStmt, i+1, (unsigned char *)name, 511, &namelen, &type, &len, &scale, &nullable);
609 if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode) {
610 parentdb->ErrorSnapshot(hStmt);
611 return FALSE;
612 }
613
614 wxQueryCol *col1 = new wxQueryCol;
615 curcol = cols.Append(name, col1);
616 col1->SetName(name);
617 col1->SetType(type);
618 col1->SetNullable((nullable != 0));
619
620 wxQueryField *field1 = new wxQueryField;
621 fetch = fetchbuf.Append(field1);
622 field1->SetType(type);
623 field1->SetSize(len);
624
625 SQLBindCol(hStmt, i+1, SQL_C_BINARY, (unsigned char*)field1->GetData(), field1->GetSize(), &trash);
626 }
627
628 switch (type) {
629 case wxOPEN_TYPE_SNAPSHOT:
630 // get it all !
631 // After we've done an SQLFetch, copy the data in the fetch buffer into
632 // new fields, for each column.
633 while (SQL_SUCCESS == (retcode = SQLFetch(hStmt)) || SQL_SUCCESS_WITH_INFO == retcode) {
634 nRecords++;
635
636 curcol = cols.First();
637 fetch = fetchbuf.First();
638 for (i=0; i<nCols; i++) {
639
640 wxQueryField *fetchField = (wxQueryField *)fetch->Data();
641 wxQueryCol *col = (wxQueryCol *)curcol->Data();
642 wxQueryField *field = new wxQueryField;
643
644 currow = col->fields.Append(field);
645
646 field->SetType(fetchField->GetType());
647 field->SetData(fetchField->GetData(), fetchField->GetSize());
648 curcol = curcol->Next();
649 fetchField->ClearData(); // Runs ok if this commented out and SetData commented out
650 fetch = fetch->Next();
651 }
652 }
653 // while loop should only be left, when no more data was found;
654 // otherwise it seems, that there was an error
655 if (SQL_NO_DATA_FOUND != retcode) {
656 parentdb->ErrorSnapshot(hStmt);
657 return FALSE;
658 }
659 break;
660 case wxOPEN_TYPE_DYNASET:
661 // get first record only
662 if (SQL_SUCCESS == (retcode = SQLFetch(hStmt)) || retcode == SQL_SUCCESS_WITH_INFO) {
663 nRecords = 1; // TO DO! # of records in the ODBC result set should be set here.
664
665 curcol = cols.First();
666 fetch = fetchbuf.First();
667 for (i=0; i<nCols; i++) {
668 currow = ((wxQueryCol*)curcol->Data())->fields.Append(new wxQueryField);
669
670 ((wxQueryField*)currow->Data())->SetType(((wxQueryField*)fetch->Data())->GetType());
671 ((wxQueryField*)currow->Data())->SetData(((wxQueryField*)fetch->Data())->GetData(), ((wxQueryField*)fetch->Data())->GetSize());
672 curcol = curcol->Next();
673 ((wxQueryField*)fetch->Data())->ClearData();
674 fetch = fetch->Next();
675 }
676 }
677 if (SQL_NO_DATA_FOUND != retcode) {
678 parentdb->ErrorSnapshot(hStmt);
679 return FALSE;
680 }
681 break;
682 default:
683 return FALSE;
684 }
685
686 FillVars(0);
687
688 return TRUE;
689}
690
691bool wxRecordSet::ExecuteSQL(char *sql)
692{
693 if (hStmt)
694 {
695 retcode = SQLFreeStmt(hStmt, SQL_DROP);
696 if (retcode == SQL_ERROR)
697 {
698 parentdb->ErrorSnapshot(hStmt);
699 return FALSE;
700 }
701 hStmt = NULL;
702 }
703
704 retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
705
706 if (SQL_SUCCESS != retcode) {
707 parentdb->ErrorSnapshot(hStmt);
708 return FALSE;
709 }
710
711 retcode = SQLExecDirect(hStmt, (UCHAR FAR*)sql, SQL_NTS);
712
713 if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode) {
714 parentdb->ErrorSnapshot(hStmt);
715 return FALSE;
716 }
717
718 return GetResultSet();
719}
720
721bool wxRecordSet::GetDataSources(void) {
722
723 char *dsname = "Name", *dsdesc = "Description";
724 char namebuf[64];
725 char descbuf[512];
726 short namelen, desclen;
727
728 cursor = 0;
729
730 // delete old data first
731 cols.DeleteContents(TRUE);
732 cols.Clear();
733 nRecords = 0;
734
735 // JACS This is a snapshot, not a dynaset.
736 type = wxOPEN_TYPE_SNAPSHOT;
737
738 wxNode *namecol, *desccol;
739
740 namecol = cols.Append(dsname, new wxQueryCol);
741 ((wxQueryCol*)namecol->Data())->SetName(dsname);
742 ((wxQueryCol*)namecol->Data())->SetType(SQL_CHAR);
743 desccol = cols.Append(dsdesc, new wxQueryCol);
744 ((wxQueryCol*)desccol->Data())->SetName(dsdesc);
745 ((wxQueryCol*)desccol->Data())->SetType(SQL_CHAR);
746
747 retcode = SQLDataSources(parentdb->GetHENV(), SQL_FETCH_FIRST, (unsigned char *)namebuf, 63, &namelen, (unsigned char *)descbuf, 511, &desclen);
748 while (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode) {
749 nRecords++;
750 ((wxQueryCol*)namecol->Data())->AppendField(namebuf, namelen);
751 ((wxQueryCol*)desccol->Data())->AppendField(descbuf, desclen);
752 retcode = SQLDataSources(parentdb->GetHENV(), SQL_FETCH_NEXT, (unsigned char *)namebuf, 63, &namelen, (unsigned char *)descbuf, 511, &desclen);
753 }
754
755 if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode && SQL_NO_DATA_FOUND != retcode) {
756 parentdb->ErrorSnapshot();
757 return FALSE;
758 }
759
760 cursor = 0;
761
762 return TRUE;
763}
764
765// Attributes
766void wxRecordSet::SetTableName(char* name) {
767 delete[] tablename;
768 tablename = NULL;
769
770 if (name)
771 tablename = copystring(name);
772}
773
774bool wxRecordSet::GetTables(void)
775{
776 if (hStmt)
777 {
778 retcode = SQLFreeStmt(hStmt, SQL_DROP);
779 if (retcode == SQL_ERROR)
780 {
781 parentdb->ErrorSnapshot(hStmt);
782 return FALSE;
783 }
784
785 hStmt = NULL;
786 }
787
788 retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
789
790 if (SQL_SUCCESS != retcode) {
791 parentdb->ErrorSnapshot();
792 return FALSE;
793 }
794
795 retcode = SQLTables(hStmt, NULL, 0, NULL, 0, NULL, 0, NULL, 0);
796
797 if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode) {
798 parentdb->ErrorSnapshot(hStmt);
799 return FALSE;
800 }
801
802 return GetResultSet();
803}
804
805bool wxRecordSet::GetColumns(char* table)
806{
807 char* name=NULL;
808// char* wildcard = "%";
809
810 name = table ? table : tablename;
811
812 if (!name)
813 return FALSE;
814
815 if (hStmt)
816 {
817 retcode = SQLFreeStmt(hStmt, SQL_DROP);
818 if (retcode == SQL_ERROR)
819 {
820 parentdb->ErrorSnapshot(hStmt);
821 return FALSE;
822 }
823 hStmt = NULL;
824 }
825
826 retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
827
828 if (SQL_SUCCESS != retcode) {
829 parentdb->ErrorSnapshot();
830 return FALSE;
831 }
832
833 //retcode = SQLColumns(hstmt, (unsigned char*)parentdb->GetDataSource(), strlen(parentdb->GetDataSource()), wildcard, 1, name, strlen(name), wildcard, 1);
834 retcode = SQLColumns(hStmt, NULL, 0, NULL, 0, (unsigned char *)name, strlen(name), NULL, 0);
835
836 if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode) {
837 parentdb->ErrorSnapshot(hStmt);
838 return FALSE;
839 }
840
841 return GetResultSet();
842}
843
844// It is derived from previous GetColumns
845bool wxRecordSet::GetPrimaryKeys(char* table)
846{
847 char* name=NULL;
848// char* wildcard = "%";
849
850 name = table ? table : tablename;
851
852 if (!name)
853 return FALSE;
854
855 if (hStmt)
856 {
857 retcode = SQLFreeStmt(hStmt, SQL_DROP);
858 if (retcode == SQL_ERROR)
859 {
860 parentdb->ErrorSnapshot(hStmt);
861 return FALSE;
862 }
863 hStmt = NULL;
864 }
865
866 retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
867
868 if (SQL_SUCCESS != retcode) {
869 parentdb->ErrorSnapshot();
870 return FALSE;
871 }
872
873 retcode = SQLPrimaryKeys(hStmt, NULL, 0, NULL, 0, (unsigned char *)name, SQL_NTS);
874
875 if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode) {
876 parentdb->ErrorSnapshot(hStmt);
877 return FALSE;
878 }
879
880 return GetResultSet();
881}
882
883bool wxRecordSet::GetForeignKeys(char* PkTableName, char * FkTableName)
884{
885 char* Pkname=NULL;
886 char* Fkname=NULL;
887// char* wildcard = "%";
888
889// Try to disable situation: both PkTableName and FkTableName are NULL
890// set Pkname from tablename
891 if( !PkTableName && !FkTableName ) {
892 Pkname = PkTableName ? PkTableName : tablename;
893 Fkname = FkTableName ;
894 if (!Pkname )
895 return FALSE;
896 } else {
897 Pkname = PkTableName ;
898 Fkname = FkTableName ;
899 }
900
901 if (hStmt)
902 {
903 retcode = SQLFreeStmt(hStmt, SQL_DROP);
904 if (retcode == SQL_ERROR)
905 {
906 parentdb->ErrorSnapshot(hStmt);
907 return FALSE;
908 }
909 hStmt = NULL;
910 }
911
912 retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
913
914 if (SQL_SUCCESS != retcode) {
915 parentdb->ErrorSnapshot();
916 return FALSE;
917 }
918
919 retcode = SQLForeignKeys(hStmt, NULL, 0, NULL, 0, (unsigned char *)Pkname,
920 (Pkname ? SQL_NTS : 0), NULL, 0, NULL, 0, (unsigned char *)Fkname ,(Fkname ?SQL_NTS : 0) );
921
922 if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode) {
923 parentdb->ErrorSnapshot(hStmt);
924 return FALSE;
925 }
926
927 return GetResultSet();
928}
929
930long wxRecordSet::GetNumberRecords(void)
931{
932 return nRecords;
933}
934
935long wxRecordSet::GetNumberCols(void)
936{
937 return nCols;
938}
939
940char* wxRecordSet::GetColName(int col)
941{
942 wxNode* node = cols.Nth(col);
943
944 if (!node)
945 return NULL;
946
947 return ((wxQueryCol*)node->Data())->GetName();
948}
949
950short wxRecordSet::GetColType(int col)
951{
952 wxNode* node = cols.Nth(col);
953
954 if (!node)
955 return SQL_TYPE_NULL;
956
957 return ((wxQueryCol*)node->Data())->GetType();
958}
959
960short wxRecordSet::GetColType(const char *col)
961{
962 wxNode* node = cols.Find(col);
963
964 if (!node)
965 return SQL_TYPE_NULL;
966
967 return ((wxQueryCol*)node->Data())->GetType();
968}
969
970bool wxRecordSet::GetFieldData(int col, int type, void* data)
971{
972 wxNode* node = cols.Nth(col);
973
974 if (!node)
975 return FALSE;
976
977 if (((wxQueryCol*)node->Data())->GetType() != type)
978 return FALSE;
979
980 void* src = ((wxQueryCol*)node->Data())->GetData(cursor);
981
982 if (!src)
983 return FALSE;
984
985 memcpy(data, src, ((wxQueryCol*)node->Data())->GetSize(cursor));
986
987 return TRUE;
988}
989
990bool wxRecordSet::GetFieldData(const char* name, int type, void *data)
991{
992 wxNode* node = cols.Find(name);
993
994 if (!node)
995 return FALSE;
996
997 if (((wxQueryCol*)node->Data())->GetType() != type)
998 return FALSE;
999
1000 void* src = ((wxQueryCol*)node->Data())->GetData(cursor);
1001
1002 if (!src)
1003 return FALSE;
1004
1005 memcpy(data, src, ((wxQueryCol*)node->Data())->GetSize(cursor));
1006
1007 return TRUE;
1008}
1009
1010void* wxRecordSet::GetFieldDataPtr(int col, int type)
1011{
1012 wxNode* node = cols.Nth(col);
1013
1014 if (!node)
1015 return NULL;
1016
1017 if (((wxQueryCol*)node->Data())->GetType() != type)
1018 return NULL;
1019
1020 return ((wxQueryCol*)node->Data())->GetData(cursor);
1021}
1022
1023void* wxRecordSet::GetFieldDataPtr(const char* name, int type)
1024{
1025 wxNode* node = cols.Find(name);
1026
1027 if (!node)
1028 return NULL;
1029
1030 if (((wxQueryCol*)node->Data())->GetType() != type)
1031 return NULL;
1032
1033 return ((wxQueryCol*)node->Data())->GetData(cursor);
1034}
1035
1036void* wxRecordSet::BindVar(int col, void* var, long size) {
1037 wxNode* node = cols.Nth(col);
1038
1039 if (!node)
1040 return NULL;
1041
1042 return ((wxQueryCol*)node->Data())->BindVar(var, size);
1043}
1044
1045void* wxRecordSet::BindVar(const char* name, void* var, long size) {
1046 wxNode* node = cols.Find(name);
1047
1048 if (!node)
1049 return NULL;
1050
1051 return ((wxQueryCol*)node->Data())->BindVar(var, size);
1052}
1053
1054void wxRecordSet::SetType(int typ) {
1055 type = typ;
1056}
1057
1058int wxRecordSet::GetType(void) {
1059 return type;
1060}
1061
1062void wxRecordSet::SetOptions(int opts) {
1063 options = opts;
1064}
1065
1066int wxRecordSet::GetOptions(void) {
1067 return options;
1068}
1069
1070bool wxRecordSet::CanAppend(void)
1071{
1072 return FALSE;
1073}
1074
1075bool wxRecordSet::CanRestart(void)
1076{
1077 return FALSE;
1078}
1079
1080bool wxRecordSet::CanScroll(void)
1081{
1082 return FALSE;
1083}
1084
1085bool wxRecordSet::CanTransact(void)
1086{
1087 return FALSE;
1088}
1089
1090bool wxRecordSet::CanUpdate(void)
1091{
1092 return FALSE;
1093}
1094
1095long wxRecordSet::GetCurrentRecord(void)
1096{
1097 return -1L;
1098}
1099
1100bool wxRecordSet::RecordCountFinal(void)
1101{
1102 return FALSE;
1103}
1104
1105char* wxRecordSet::GetTableName(void)
1106{
1107 return tablename;
1108}
1109
1110char *wxRecordSet::GetSQL(void)
1111{
1112 return NULL;
1113}
1114
1115bool wxRecordSet::IsOpen(void)
1116{
1117 return parentdb->IsOpen();
1118}
1119
1120bool wxRecordSet::IsBOF(void)
1121{
1122 return cursor < 0;
1123}
1124
1125bool wxRecordSet::IsEOF(void)
1126{
1127 return cursor >= nRecords;
1128}
1129
1130bool wxRecordSet::IsDeleted(void)
1131{
1132 return FALSE;
1133}
1134
1135// Update operations
1136void wxRecordSet::AddNew(void)
1137{
1138}
1139
1140bool wxRecordSet::Delete(void)
1141{
1142 return FALSE;
1143}
1144
1145void wxRecordSet::Edit(void)
1146{
1147}
1148
1149bool wxRecordSet::Update(void)
1150{
1151 return FALSE;
1152}
1153
1154// Record navigation
1155bool wxRecordSet::Move(long rows)
1156{
1157 if (!nRecords) {
1158 cursor = -1;
1159 return FALSE;
1160 }
1161
1162 switch (type) {
1163 case wxOPEN_TYPE_SNAPSHOT:
1164 cursor += (int)rows;
1165 if (cursor < 0) {
1166 cursor = -1;
1167 return FALSE;
1168 }
1169 if (cursor > nRecords-1) {
1170 cursor = nRecords;
1171 return FALSE;
1172 }
1173 return TRUE;
1174
1175 case wxOPEN_TYPE_DYNASET:
1176 return FALSE;
1177 default:
1178 return FALSE;
1179 }
1180}
1181
1182bool wxRecordSet::GoTo(long row)
1183{
1184 if (!nRecords) {
1185 cursor = -1;
1186 return FALSE;
1187 }
1188
1189 switch (type) {
1190 case wxOPEN_TYPE_SNAPSHOT:
1191 cursor = (int)row;
1192 if (cursor < 0) {
1193 cursor = -1;
1194 return FALSE;
1195 }
1196 if (cursor > nRecords-1) {
1197 cursor = nRecords;
1198 return FALSE;
1199 }
1200 return TRUE;
1201
1202 case wxOPEN_TYPE_DYNASET:
1203 return FALSE;
1204 default:
1205 return FALSE;
1206 }
1207}
1208
1209bool wxRecordSet::MoveFirst(void)
1210{
1211 if (!nRecords) {
1212 cursor = -1;
1213 return FALSE;
1214 }
1215
1216 switch (type) {
1217 case wxOPEN_TYPE_SNAPSHOT:
1218 cursor = 0;
1219 return TRUE;
1220
1221 case wxOPEN_TYPE_DYNASET:
1222 return FALSE;
1223 default:
1224 return FALSE;
1225 }
1226}
1227
1228bool wxRecordSet::MoveLast(void)
1229{
1230 if (!nRecords) {
1231 cursor = -1;
1232 return FALSE;
1233 }
1234
1235 switch (type) {
1236 case wxOPEN_TYPE_SNAPSHOT:
1237 cursor = nRecords-1;
1238 return TRUE;
1239
1240 case wxOPEN_TYPE_DYNASET:
1241 return FALSE;
1242 default:
1243 return FALSE;
1244 }
1245}
1246
1247bool wxRecordSet::MoveNext(void)
1248{
1249 if (!nRecords) {
1250 cursor = -1;
1251 return FALSE;
1252 }
1253
1254 switch (type) {
1255 case wxOPEN_TYPE_SNAPSHOT:
1256 cursor++;
1257 if (cursor >= nRecords) {
1258 cursor = nRecords;
1259 return FALSE;
1260 }
1261 return TRUE;
1262
1263 case wxOPEN_TYPE_DYNASET:
1264 return FALSE;
1265 default:
1266 return FALSE;
1267 }
1268}
1269
1270bool wxRecordSet::MovePrev(void)
1271{
1272 if (!nRecords) {
1273 cursor = -1;
1274 return FALSE;
1275 }
1276
1277 switch (type) {
1278 case wxOPEN_TYPE_SNAPSHOT:
1279 cursor--;
1280 if (cursor < 0) {
1281 cursor = 0;
1282 return FALSE;
1283 }
1284 return TRUE;
1285
1286 case wxOPEN_TYPE_DYNASET:
1287 return FALSE;
1288 default:
1289 return FALSE;
1290 }
1291}
1292
1293// Others
1294void wxRecordSet::Cancel(void)
1295{
1296}
1297
1298bool wxRecordSet::IsFieldDirty(int col)
1299{
1300 wxNode* node = cols.Nth(col);
1301
1302 if (!node)
1303 return FALSE;
1304
1305 return ((wxQueryCol*)node->Data())->IsFieldDirty(cursor);
1306}
1307
1308bool wxRecordSet::IsFieldDirty(const char* name)
1309{
1310 wxNode* node = cols.Find(name);
1311
1312 if (!node)
1313 return FALSE;
1314
1315 return ((wxQueryCol*)node->Data())->IsFieldDirty(cursor);
1316}
1317
1318bool wxRecordSet::IsFieldNull(int col)
1319{
1320 wxNode* node = cols.Nth(col);
1321
1322 if (!node)
1323 return TRUE;
1324
1325 return NULL != ((wxQueryCol*)node->Data())->GetData(cursor);
1326}
1327
1328bool wxRecordSet::IsFieldNull(const char* name)
1329{
1330 wxNode* node = cols.Find(name);
1331
1332 if (!node)
1333 return TRUE;
1334
1335 return NULL != ((wxQueryCol*)node->Data())->GetData(cursor);
1336}
1337
1338bool wxRecordSet::IsColNullable(int col)
1339{
1340 wxNode* node = cols.Nth(col);
1341
1342 if (!node)
1343 return FALSE;
1344
1345 return ((wxQueryCol*)node->Data())->IsNullable();
1346}
1347
1348bool wxRecordSet::IsColNullable(const char* name)
1349{
1350 wxNode* node = cols.Find(name);
1351
1352 if (!node)
1353 return FALSE;
1354
1355 return ((wxQueryCol*)node->Data())->IsNullable();
1356}
1357
1358bool wxRecordSet::Requery(void)
1359{
1360 return FALSE;
1361}
1362
1363void wxRecordSet::SetFieldDirty(int col, bool dirty)
1364{
1365 wxNode* node = cols.Nth(col);
1366
1367 if (!node)
1368 return;
1369
1370 ((wxQueryCol*)node->Data())->SetFieldDirty(cursor, dirty);
1371}
1372
1373void wxRecordSet::SetFieldDirty(const char* name, bool dirty)
1374{
1375 wxNode* node = cols.Find(name);
1376
1377 if (!node)
1378 return;
1379
1380 ((wxQueryCol*)node->Data())->SetFieldDirty(cursor, dirty);
1381}
1382
1383void wxRecordSet::SetFieldNull(void *WXUNUSED(p), bool WXUNUSED(isNull))
1384{
1385}
1386
1387// Overridables
1388char *wxRecordSet::GetDefaultConnect(void)
1389{
1390 return NULL;
1391}
1392
1393char *wxRecordSet::GetDefaultSQL(void)
1394{
1395 return NULL;
1396}
1397
1398void wxRecordSet::SetDefaultSQL(char *s)
1399{
1400 delete[] defaultSQL;
1401
1402 if (s)
1403 defaultSQL = copystring(s);
1404 else
1405 defaultSQL = NULL;
1406}
1407
1408// Build SQL query from column specification
1409bool wxRecordSet::ConstructDefaultSQL(void)
1410{
1411// if (queryCols.Number() == 0)
1412 return FALSE;
1413}
1414
1415bool wxRecordSet::ReleaseHandle(void)
1416{
1417 if (hStmt)
1418 {
1419 retcode = SQLFreeStmt(hStmt, SQL_DROP);
1420 if (retcode == SQL_ERROR)
1421 {
1422 if (parentdb)
1423 parentdb->ErrorSnapshot(hStmt);
1424 return FALSE;
1425 }
1426 hStmt = 0;
1427 }
1428 return TRUE;
1429}
1430
1431wxQueryCol::wxQueryCol(void) {
1432// __type = wxTYPE_QUERYCOL;
1433 name = NULL;
1434 type = SQL_TYPE_NULL;
1435 nullable = FALSE;
1436 var = NULL;
1437 varsize = 0;
1438}
1439
1440wxQueryCol::~wxQueryCol(void) {
1441 // delete all data
1442 fields.DeleteContents(TRUE);
1443 fields.Clear();
1444
1445 if (name)
1446 delete[] name;
1447}
1448
1449void wxQueryCol::SetName(char* n) {
1450 name = new char[strlen(n)+1];
1451 strcpy(name, n);
1452}
1453
1454bool wxQueryCol::SetData(int row, void* buf, long len) {
1455 wxNode* node = fields.Nth(row);
1456
1457 if (!node)
1458 return FALSE;
1459
1460 return ((wxQueryField*)node->Data())->SetData(buf, len);
1461}
1462
1463void wxQueryCol::SetFieldDirty(int row, bool dirty) {
1464 wxNode* node = fields.Nth(row);
1465
1466 if (!node)
1467 return;
1468
1469 ((wxQueryField*)node->Data())->SetDirty(dirty);
1470}
1471
1472void wxQueryCol::AppendField(void* buf, long len) {
1473 wxNode* node = fields.Append(new wxQueryField);
1474 ((wxQueryField*)node->Data())->SetType(type);
1475 ((wxQueryField*)node->Data())->SetData(buf, len);
1476}
1477
1478void wxQueryCol::SetType(short t) {
1479 type = t;
1480}
1481
1482void* wxQueryCol::BindVar(void* v, long s) {
1483 void* oldvar = var;
1484
1485 var = v;
1486 varsize = s;
1487
1488 return oldvar;
1489}
1490
1491void wxQueryCol::FillVar(int recnum) {
1492 if (!var)
1493 return;
1494
1495 wxNode* node = fields.Nth(recnum);
1496
1497 if (!node)
1498 return;
1499
1500 long actsize = ((wxQueryField*)node->Data())->GetSize();
1501 if (actsize > varsize)
1502 actsize = varsize;
1503
1504 memcpy(var, ((wxQueryField*)node->Data())->GetData(), actsize);
1505}
1506
1507void wxQueryCol::SetNullable(bool n) {
1508 nullable = n;
1509}
1510
1511char* wxQueryCol::GetName(void) {
1512 return name;
1513}
1514
1515short wxQueryCol::GetType(void) {
1516 return type;
1517}
1518
1519bool wxQueryCol::IsNullable(void) {
1520 return nullable;
1521}
1522
1523
1524bool wxQueryCol::IsFieldDirty(int row) {
1525 wxNode* node = fields.Nth(row);
1526
1527 if (!node)
1528 return FALSE;
1529
1530 return ((wxQueryField*)node->Data())->IsDirty();
1531}
1532
1533void* wxQueryCol::GetData(int row) {
1534 wxNode* node = fields.Nth(row);
1535
1536 if (!node)
1537 return NULL;
1538
1539 return ((wxQueryField*)node->Data())->GetData();
1540}
1541
1542long wxQueryCol::GetSize(int row) {
1543 wxNode* node = fields.Nth(row);
1544
1545 if (!node)
1546 return 0;
1547
1548 return ((wxQueryField*)node->Data())->GetSize();
1549}
1550
1551wxQueryField::wxQueryField(void) {
1552// __type = wxTYPE_QUERYROW;
1553 data = NULL;
1554 type = SQL_TYPE_NULL;
1555 size = 0;
1556 dirty = FALSE;
1557}
1558
1559wxQueryField::~wxQueryField(void) {
1560 switch (type)
1561 {
1562 case SQL_NUMERIC:
1563 case SQL_DECIMAL:
1564 case SQL_CHAR:
1565 case SQL_VARCHAR:
1566 if (data) // JACS
1567 delete[] (char*)data;
1568 break;
1569 case SQL_INTEGER:
1570 if (data) // JACS
1571 delete (long*)data;
1572 break;
1573 case SQL_SMALLINT:
1574 if (data)
1575 delete (short*)data;
1576 break;
1577 case SQL_FLOAT:
1578 case SQL_DOUBLE:
1579 if (data)
1580 delete (double*)data;
1581 break;
1582 case SQL_REAL:
1583 if (data)
1584 delete (float*)data;
1585 break;
1586 case SQL_TIME:
1587 if (data)
1588 delete (TIME_STRUCT *)data;
1589 break;
1590 case SQL_DATE:
1591 if (data)
1592 delete (DATE_STRUCT *)data;
1593 break;
1594 case SQL_TIMESTAMP:
1595 if (data)
1596 delete (TIMESTAMP_STRUCT *)data;
1597 break;
1598 }
1599}
1600
1601bool wxQueryField::AllocData(void) {
1602 switch (type)
1603 {
1604 case SQL_NUMERIC:
1605 case SQL_DECIMAL:
1606 case SQL_CHAR:
1607 case SQL_VARCHAR:
1608 {
1609 if (data) // JACS
1610 delete[] (char*)data;
1611 if ((data = new char[size+1]))
1612 {
1613 char *str = (char *)data;
1614 int i;
1615 for (i = 0; i < size; i++)
1616 str[i] = 0;
1617// memset(data, 0, size+1);
1618 }
1619 break;
1620 }
1621 case SQL_INTEGER:
1622 {
1623 if (data) // JACS
1624 delete (long*)data;
1625 if ((data = new long))
1626 *(long*)data = 0L;
1627 break;
1628 }
1629 case SQL_SMALLINT:
1630 {
1631 if (data)
1632 delete (short*)data;
1633 if ((data = new short))
1634 *(short*)data = 0;
1635 break;
1636 }
1637 case SQL_FLOAT:
1638 case SQL_DOUBLE:
1639 {
1640 if (data)
1641 delete (double*)data;
1642 if ((data = new double))
1643 *(double*)data = 0;
1644 break;
1645 }
1646 case SQL_REAL:
1647 {
1648 if (data)
1649 delete (float*)data;
1650 if ((data = new float))
1651 *(float*)data = (float)0;
1652 break;
1653 }
1654 case SQL_TIME:
1655 {
1656 if (data)
1657 delete (TIME_STRUCT *)data;
1658 data = new TIME_STRUCT;
1659 memset(data, 0, sizeof(TIME_STRUCT));
1660 break;
1661 }
1662 case SQL_DATE:
1663 {
1664 if (data)
1665 delete (DATE_STRUCT *)data;
1666 data = new DATE_STRUCT;
1667 memset(data, 0, sizeof(DATE_STRUCT));
1668 break;
1669 }
1670 case SQL_TIMESTAMP:
1671 {
1672 if (data)
1673 delete (TIMESTAMP_STRUCT *)data;
1674 data = new TIMESTAMP_STRUCT;
1675 memset(data, 0, sizeof(TIMESTAMP_STRUCT));
1676 break;
1677 }
1678 default:
1679 return FALSE;
1680 }
1681
1682 return TRUE;
1683}
1684
1685bool wxQueryField::SetData(void* d, long s) {
1686 size = s;
1687 if (AllocData() && d)
1688 {
1689// memcpy(data, d, s);
1690 switch (type)
1691 {
1692 case SQL_NUMERIC:
1693 case SQL_DECIMAL:
1694 case SQL_CHAR:
1695 case SQL_VARCHAR:
1696 {
1697 char *str = (char *)data;
1698 int i;
1699 for (i = 0; i < size; i++)
1700 str[i] = 0;
1701
1702 strncpy(str, (char *)d, (int)size);
1703 str[size] = 0;
1704 break;
1705 }
1706 case SQL_INTEGER:
1707 {
1708 *(long*)data = *((long *)d);
1709 break;
1710 }
1711 case SQL_SMALLINT:
1712 {
1713 *(short*)data = *((short*)d);
1714 break;
1715 }
1716 case SQL_FLOAT:
1717 case SQL_DOUBLE:
1718 {
1719 *(double*)data = *((double*)d);
1720 break;
1721 }
1722 case SQL_REAL:
1723 {
1724 *(float*)data = *((float*)d);
1725 break;
1726 }
1727 case SQL_TIME:
1728 {
1729 *(TIME_STRUCT *)data = *((TIME_STRUCT*)d);
1730 break;
1731 }
1732 case SQL_TIMESTAMP:
1733 {
1734 *(TIMESTAMP_STRUCT *)data = *((TIMESTAMP_STRUCT*)d);
1735 break;
1736 }
1737 case SQL_DATE:
1738 {
1739 *(DATE_STRUCT *)data = *((DATE_STRUCT*)d);
1740 break;
1741 }
1742 default:
1743 return FALSE;
1744 }
1745 return TRUE;
1746 }
1747 return FALSE;
1748}
1749
1750void wxQueryField::ClearData(void) {
1751 if (data)
1752 {
1753 // memset(data, 0, size);
1754 switch (type)
1755 {
1756 case SQL_NUMERIC:
1757 case SQL_DECIMAL:
1758 case SQL_CHAR:
1759 case SQL_VARCHAR:
1760 {
1761 char *str = (char *)data;
1762 int i;
1763 for (i = 0; i < size; i++)
1764 str[i] = 0;
1765 break;
1766 }
1767 case SQL_INTEGER:
1768 {
1769 *(long*)data = 0L;
1770 break;
1771 }
1772 case SQL_SMALLINT:
1773 {
1774 *(short*)data = 0;
1775 break;
1776 }
1777 case SQL_FLOAT:
1778 case SQL_DOUBLE:
1779 {
1780 *(double*)data = (double)0.0;
1781 break;
1782 }
1783 case SQL_REAL:
1784 {
1785 *(float*)data = (float)0.0;
1786 break;
1787 }
1788 case SQL_TIME:
1789 {
1790 memset(data, 0, sizeof(TIME_STRUCT));
1791 break;
1792 }
1793 case SQL_DATE:
1794 {
1795 memset(data, 0, sizeof(DATE_STRUCT));
1796 break;
1797 }
1798 case SQL_TIMESTAMP:
1799 {
1800 memset(data, 0, sizeof(TIMESTAMP_STRUCT));
1801 break;
1802 }
1803 default:
1804 return;
1805 }
1806 }
1807}
1808
1809void wxQueryField::SetDirty(bool d) {
1810 dirty = d;
1811}
1812
1813void wxQueryField::SetType(short t) {
1814 type = t;
1815}
1816
1817void wxQueryField::SetSize(long s) {
1818 size = s;
1819 AllocData();
1820}
1821
1822void* wxQueryField::GetData(void) {
1823 return data;
1824}
1825
1826short wxQueryField::GetType(void) {
1827 return type;
1828}
1829
1830long wxQueryField::GetSize(void) {
1831 return size;
1832}
1833
1834bool wxQueryField::IsDirty(void) {
1835 return dirty;
1836}
1837
1838#ifdef __VISUALC__
1839 #pragma warning(default:4706) // assignment within conditional expression
1840#endif // VC++
1841
1842#endif // wxUSE_OLD_ODBC