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