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