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