]>
git.saurik.com Git - wxWidgets.git/blob - src/common/odbc.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: ODBC implementation
4 // Author: Julian Smart, Olaf Klein (oklein@smallo.ruhr.de),
5 // Patrick Halke (patrick@zaphod.ruhr.de)
9 // Copyright: (c) Julian Smart and Markus Holzem
10 // Licence: wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
14 #pragma implementation "odbc.h"
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
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
33 #pragma warning(disable:4706) // assignment within conditional expression
38 #include "wx/dialog.h"
41 #include "wx/string.h"
47 #if defined(__WXMSW__) && !defined(__WIN32__)
51 HENV
wxDatabase::hEnv
= 0;
52 int wxDatabase::refCount
= 0;
54 #if !USE_SHARED_LIBRARY
55 IMPLEMENT_DYNAMIC_CLASS(wxDatabase
, wxObject
)
56 IMPLEMENT_DYNAMIC_CLASS(wxQueryCol
, wxObject
)
57 IMPLEMENT_DYNAMIC_CLASS(wxQueryField
, wxObject
)
58 IMPLEMENT_DYNAMIC_CLASS(wxRecordSet
, wxObject
)
61 wxDatabase::wxDatabase(void)
76 memset(sqlstate
, 0, sizeof sqlstate
);
77 memset(errmsg
, 0, sizeof errmsg
);
81 retcode
= SQLAllocEnv(&hEnv
);
83 if (retcode
!= SQL_SUCCESS
)
88 wxDatabase::~wxDatabase(void)
91 DeleteRecordSets(); // Added JACS
94 delete[] connectstring
;
105 if (!refCount
&& hEnv
)
107 retcode
= SQLFreeEnv(hEnv
);
108 hEnv
= 0; // JACS 17/6
112 void wxDatabase::ErrorSnapshot(HSTMT hstmt
)
114 SWORD len
= 0; // JACS: sometimes doesn't get filled in by SQLError.
117 SQLError(hEnv
, hDBC
, hstmt
, (unsigned char *)sqlstate
, &nat_err
, (unsigned char *)errmsg
, SQL_MAX_MESSAGE_LENGTH
-1, &len
);
121 bool wxDatabase::ErrorOccured(void)
126 char* wxDatabase::GetErrorMessage(void)
131 long wxDatabase::GetErrorNumber(void)
136 char* wxDatabase::GetErrorClass(void) {
140 bool wxDatabase::Open(char *thedatasource
, bool WXUNUSED(exclusive
),
141 bool WXUNUSED(readOnly
), char *username
, char *password
)
148 SetUsername(username
);
149 SetPassword(password
);
150 SetDataSource(thedatasource
);
155 retcode
= SQLAllocConnect(hEnv
, &hDBC
);
156 if (retcode
!= SQL_SUCCESS
) {
161 retcode
= SQLConnect(hDBC
, (UCHAR FAR
*)thedatasource
, strlen(thedatasource
), (UCHAR FAR
*)username
, strlen(username
),
162 (UCHAR FAR
*)password
, strlen(password
));
164 if (retcode
!= SQL_SUCCESS
&& retcode
!= SQL_SUCCESS_WITH_INFO
) {
174 bool wxDatabase::Close(void)
176 // JACS: make sure the record set statements are all released.
182 retcode
= SQLDisconnect(hDBC
);
184 if (retcode
!= SQL_SUCCESS
&& retcode
!= SQL_SUCCESS_WITH_INFO
) {
189 retcode
= SQLFreeConnect(hDBC
);
200 // Database attributes
201 char *wxDatabase::GetDatabaseName(void)
210 retcode
= SQLGetInfo(hDBC
, SQL_DATABASE_NAME
, (unsigned char*)nameBuf
, sizeof(nameBuf
), (short *)&nameSize
);
212 if (retcode
!= SQL_SUCCESS
&& retcode
!= SQL_SUCCESS_WITH_INFO
)
220 dbname
= copystring(nameBuf
);
227 bool wxDatabase::CanUpdate(void)
232 bool wxDatabase::CanTransact(void)
237 bool wxDatabase::InWaitForDataSource(void)
242 void wxDatabase::SetLoginTimeout(long WXUNUSED(seconds
))
246 void wxDatabase::SetQueryTimeout(long WXUNUSED(seconds
))
250 void wxDatabase::SetSynchronousMode(bool WXUNUSED(synchronous
))
254 // Database operations
255 bool wxDatabase::BeginTrans(void)
260 bool wxDatabase::CommitTrans(void)
265 bool wxDatabase::RollbackTrans(void)
270 void wxDatabase::Cancel(void)
275 void wxDatabase::OnSetOptions(wxRecordSet
*WXUNUSED(recordSet
))
279 void wxDatabase::OnWaitForDataSource(bool WXUNUSED(stillExecuting
))
283 void wxDatabase::SetPassword(char *s
)
289 password
= copystring(s
);
295 void wxDatabase::SetUsername(char *s
)
300 username
= copystring(s
);
305 void wxDatabase::SetDataSource(char *s
)
310 datasource
= copystring(s
);
319 void wxDatabase::DeleteRecordSets(void)
321 wxNode
*node
= recordSets
.First();
324 wxNode
*next
= node
->Next();
325 wxRecordSet
*rec
= (wxRecordSet
*)node
->Data();
327 // The node is implicitly deleted by ~wxRecordSet
332 void wxDatabase::ResetRecordSets(void)
334 wxNode
*node
= recordSets
.First();
337 wxRecordSet
*rec
= (wxRecordSet
*)node
->Data();
338 rec
->ReleaseHandle();
344 bool wxDatabase::GetInfo(long infoType
, long *buf
)
347 retcode
= SQLGetInfo(hDBC
, (UWORD
)infoType
, (unsigned char*)buf
, sizeof(buf
), &sz
);
349 if (retcode
!= SQL_ERROR
)
355 bool wxDatabase::GetInfo(long infoType
, char *buf
, int bufSize
)
358 bufSize
= sizeof(buf
);
361 retcode
= SQLGetInfo(hDBC
, (UWORD
)infoType
, (unsigned char*)buf
, bufSize
, &sz
);
363 if (retcode
!= SQL_ERROR
)
369 wxString
wxDatabase::GetODBCVersionString(bool implementation
)
374 #ifdef SQL_SPEC_MAJOR
375 sprintf(buf
, "%d%d.%d", (int)(SQL_SPEC_MAJOR
/10), (int)(SQL_SPEC_MAJOR
- (((int)(SQL_SPEC_MAJOR
/10))*10)),
377 return wxString(buf
);
379 return wxString("00.00");
387 retcode
= SQLAllocConnect(hEnv
, &hDBC
);
388 if (retcode
!= SQL_SUCCESS
)
391 return wxString("00.00");
395 int bufSize
= sizeof(buf
);
398 retcode
= SQLGetInfo(hDBC
, (UWORD
)SQL_ODBC_VER
, (unsigned char*)buf
, bufSize
, &sz
);
400 if (hDBC
!= 0 && noDBC
)
402 retcode
= SQLFreeConnect(hDBC
);
406 if (retcode
== SQL_ERROR
)
409 return wxString(buf
);
412 float wxDatabase::GetODBCVersionFloat(bool implementation
)
416 #ifdef SQL_SPEC_MAJOR
417 return (float)(SQL_SPEC_MAJOR
+ (SQL_SPEC_MINOR
/100.0));
427 retcode
= SQLAllocConnect(hEnv
, &hDBC
);
428 if (retcode
!= SQL_SUCCESS
)
436 int bufSize
= sizeof(buf
);
439 retcode
= SQLGetInfo(hDBC
, (UWORD
)SQL_ODBC_VER
, (unsigned char*)buf
, bufSize
, &sz
);
441 if (hDBC
!= 0 && noDBC
)
443 retcode
= SQLFreeConnect(hDBC
);
447 if (retcode
== SQL_ERROR
)
450 return (float)atof(buf
);
457 wxRecordSet::wxRecordSet(wxDatabase
*db
, int typ
, int opt
):
477 parentdb
->GetRecordSets().Append(this);
480 wxRecordSet::~wxRecordSet(void)
486 parentdb
->GetRecordSets().DeleteObject(this);
489 delete[] recordFilter
;
496 // If SQL is non-NULL, table and columns can be NULL.
497 bool wxRecordSet::BeginQuery(int WXUNUSED(openType
), char *WXUNUSED(sql
), int WXUNUSED(options
))
499 // Needs to construct an appropriate SQL statement. By default
500 // (i.e. if table and columns are provided) then
501 // SELECT <columns> FROM <table>
505 if (!parentdb
->GetHDBC())
510 retcode
= SQLFreeStmt(hStmt
, SQL_DROP
);
511 if (retcode
== SQL_ERROR
)
513 parentdb
->ErrorSnapshot(hStmt
);
519 retcode
= SQLAllocStmt(parentdb
->GetHDBC(), &hStmt
);
520 if (retcode
!= SQL_SUCCESS
)
526 bool wxRecordSet::Query(char *columns
, char *table
, char *filter
)
528 // Needs to construct an appropriate SQL statement. By default
529 // (i.e. if table and columns are provided) then
530 // SELECT <columns> FROM <table>
533 char* thetable
= table
? table
: tablename
;
551 retcode
= SQLPrepare(hStmt
, (UCHAR FAR
*)query
.GetData(), strlen(query
.GetData()));
552 if (retcode
!= SQL_SUCCESS
) {
553 parentdb
->ErrorSnapshot(hStmt
);
557 retcode
= SQLExecute(hStmt
);
559 if (retcode
!= SQL_SUCCESS
&& retcode
!= SQL_SUCCESS_WITH_INFO
) {
560 parentdb
->ErrorSnapshot(hStmt
);
567 bool wxRecordSet::EndQuery(void)
572 void wxRecordSet::FillVars(int recnum
) {
573 wxNode
* node
= cols
.First();
576 ((wxQueryCol
*)node
->Data())->FillVar(recnum
);
577 } while ((node
= node
->Next()));
580 bool wxRecordSet::GetResultSet(void)
582 // long trash = SQL_NULL_DATA; // value added by JACS
584 // contains the number of bytes transferred by SQLFetch()
586 wxNode
*currow
, *fetch
, *curcol
;
588 retcode
= SQLNumResultCols(hStmt
, &nCols
);
593 // delete old data first
594 cols
.DeleteContents(TRUE
);
596 fetchbuf
.DeleteContents(TRUE
);
603 for (i
=0; i
<nCols
; i
++) {
605 short type
, scale
, nullable
, namelen
;
608 retcode
= SQLDescribeCol(hStmt
, i
+1, (unsigned char *)name
, 511, &namelen
, &type
, &len
, &scale
, &nullable
);
609 if (SQL_SUCCESS
!= retcode
&& SQL_SUCCESS_WITH_INFO
!= retcode
) {
610 parentdb
->ErrorSnapshot(hStmt
);
614 wxQueryCol
*col1
= new wxQueryCol
;
615 curcol
= cols
.Append(name
, col1
);
618 col1
->SetNullable((nullable
!= 0));
620 wxQueryField
*field1
= new wxQueryField
;
621 fetch
= fetchbuf
.Append(field1
);
622 field1
->SetType(type
);
623 field1
->SetSize(len
);
625 SQLBindCol(hStmt
, i
+1, SQL_C_BINARY
, (unsigned char*)field1
->GetData(), field1
->GetSize(), &trash
);
629 case wxOPEN_TYPE_SNAPSHOT
:
631 // After we've done an SQLFetch, copy the data in the fetch buffer into
632 // new fields, for each column.
633 while (SQL_SUCCESS
== (retcode
= SQLFetch(hStmt
)) || SQL_SUCCESS_WITH_INFO
== retcode
) {
636 curcol
= cols
.First();
637 fetch
= fetchbuf
.First();
638 for (i
=0; i
<nCols
; i
++) {
640 wxQueryField
*fetchField
= (wxQueryField
*)fetch
->Data();
641 wxQueryCol
*col
= (wxQueryCol
*)curcol
->Data();
642 wxQueryField
*field
= new wxQueryField
;
644 currow
= col
->fields
.Append(field
);
646 field
->SetType(fetchField
->GetType());
647 field
->SetData(fetchField
->GetData(), fetchField
->GetSize());
648 curcol
= curcol
->Next();
649 fetchField
->ClearData(); // Runs ok if this commented out and SetData commented out
650 fetch
= fetch
->Next();
653 // while loop should only be left, when no more data was found;
654 // otherwise it seems, that there was an error
655 if (SQL_NO_DATA_FOUND
!= retcode
) {
656 parentdb
->ErrorSnapshot(hStmt
);
660 case wxOPEN_TYPE_DYNASET
:
661 // get first record only
662 if (SQL_SUCCESS
== (retcode
= SQLFetch(hStmt
)) || retcode
== SQL_SUCCESS_WITH_INFO
) {
663 nRecords
= 1; // TO DO! # of records in the ODBC result set should be set here.
665 curcol
= cols
.First();
666 fetch
= fetchbuf
.First();
667 for (i
=0; i
<nCols
; i
++) {
668 currow
= ((wxQueryCol
*)curcol
->Data())->fields
.Append(new wxQueryField
);
670 ((wxQueryField
*)currow
->Data())->SetType(((wxQueryField
*)fetch
->Data())->GetType());
671 ((wxQueryField
*)currow
->Data())->SetData(((wxQueryField
*)fetch
->Data())->GetData(), ((wxQueryField
*)fetch
->Data())->GetSize());
672 curcol
= curcol
->Next();
673 ((wxQueryField
*)fetch
->Data())->ClearData();
674 fetch
= fetch
->Next();
677 if (SQL_NO_DATA_FOUND
!= retcode
) {
678 parentdb
->ErrorSnapshot(hStmt
);
691 bool wxRecordSet::ExecuteSQL(char *sql
)
695 retcode
= SQLFreeStmt(hStmt
, SQL_DROP
);
696 if (retcode
== SQL_ERROR
)
698 parentdb
->ErrorSnapshot(hStmt
);
704 retcode
= SQLAllocStmt(parentdb
->GetHDBC(), &hStmt
);
706 if (SQL_SUCCESS
!= retcode
) {
707 parentdb
->ErrorSnapshot(hStmt
);
711 retcode
= SQLExecDirect(hStmt
, (UCHAR FAR
*)sql
, SQL_NTS
);
713 if (SQL_SUCCESS
!= retcode
&& SQL_SUCCESS_WITH_INFO
!= retcode
) {
714 parentdb
->ErrorSnapshot(hStmt
);
718 return GetResultSet();
721 bool wxRecordSet::GetDataSources(void) {
723 char *dsname
= "Name", *dsdesc
= "Description";
726 short namelen
, desclen
;
730 // delete old data first
731 cols
.DeleteContents(TRUE
);
735 // JACS This is a snapshot, not a dynaset.
736 type
= wxOPEN_TYPE_SNAPSHOT
;
738 wxNode
*namecol
, *desccol
;
740 namecol
= cols
.Append(dsname
, new wxQueryCol
);
741 ((wxQueryCol
*)namecol
->Data())->SetName(dsname
);
742 ((wxQueryCol
*)namecol
->Data())->SetType(SQL_CHAR
);
743 desccol
= cols
.Append(dsdesc
, new wxQueryCol
);
744 ((wxQueryCol
*)desccol
->Data())->SetName(dsdesc
);
745 ((wxQueryCol
*)desccol
->Data())->SetType(SQL_CHAR
);
747 retcode
= SQLDataSources(parentdb
->GetHENV(), SQL_FETCH_FIRST
, (unsigned char *)namebuf
, 63, &namelen
, (unsigned char *)descbuf
, 511, &desclen
);
748 while (SQL_SUCCESS
== retcode
|| SQL_SUCCESS_WITH_INFO
== retcode
) {
750 ((wxQueryCol
*)namecol
->Data())->AppendField(namebuf
, namelen
);
751 ((wxQueryCol
*)desccol
->Data())->AppendField(descbuf
, desclen
);
752 retcode
= SQLDataSources(parentdb
->GetHENV(), SQL_FETCH_NEXT
, (unsigned char *)namebuf
, 63, &namelen
, (unsigned char *)descbuf
, 511, &desclen
);
755 if (SQL_SUCCESS
!= retcode
&& SQL_SUCCESS_WITH_INFO
!= retcode
&& SQL_NO_DATA_FOUND
!= retcode
) {
756 parentdb
->ErrorSnapshot();
766 void wxRecordSet::SetTableName(char* name
) {
771 tablename
= copystring(name
);
774 bool wxRecordSet::GetTables(void)
778 retcode
= SQLFreeStmt(hStmt
, SQL_DROP
);
779 if (retcode
== SQL_ERROR
)
781 parentdb
->ErrorSnapshot(hStmt
);
788 retcode
= SQLAllocStmt(parentdb
->GetHDBC(), &hStmt
);
790 if (SQL_SUCCESS
!= retcode
) {
791 parentdb
->ErrorSnapshot();
795 retcode
= SQLTables(hStmt
, NULL
, 0, NULL
, 0, NULL
, 0, NULL
, 0);
797 if (SQL_SUCCESS
!= retcode
&& SQL_SUCCESS_WITH_INFO
!= retcode
) {
798 parentdb
->ErrorSnapshot(hStmt
);
802 return GetResultSet();
805 bool wxRecordSet::GetColumns(char* table
)
808 // char* wildcard = "%";
810 name
= table
? table
: tablename
;
817 retcode
= SQLFreeStmt(hStmt
, SQL_DROP
);
818 if (retcode
== SQL_ERROR
)
820 parentdb
->ErrorSnapshot(hStmt
);
826 retcode
= SQLAllocStmt(parentdb
->GetHDBC(), &hStmt
);
828 if (SQL_SUCCESS
!= retcode
) {
829 parentdb
->ErrorSnapshot();
833 //retcode = SQLColumns(hstmt, (unsigned char*)parentdb->GetDataSource(), strlen(parentdb->GetDataSource()), wildcard, 1, name, strlen(name), wildcard, 1);
834 retcode
= SQLColumns(hStmt
, NULL
, 0, NULL
, 0, (unsigned char *)name
, strlen(name
), NULL
, 0);
836 if (SQL_SUCCESS
!= retcode
&& SQL_SUCCESS_WITH_INFO
!= retcode
) {
837 parentdb
->ErrorSnapshot(hStmt
);
841 return GetResultSet();
844 // It is derived from previous GetColumns
845 bool wxRecordSet::GetPrimaryKeys(char* table
)
848 // char* wildcard = "%";
850 name
= table
? table
: tablename
;
857 retcode
= SQLFreeStmt(hStmt
, SQL_DROP
);
858 if (retcode
== SQL_ERROR
)
860 parentdb
->ErrorSnapshot(hStmt
);
866 retcode
= SQLAllocStmt(parentdb
->GetHDBC(), &hStmt
);
868 if (SQL_SUCCESS
!= retcode
) {
869 parentdb
->ErrorSnapshot();
873 retcode
= SQLPrimaryKeys(hStmt
, NULL
, 0, NULL
, 0, (unsigned char *)name
, SQL_NTS
);
875 if (SQL_SUCCESS
!= retcode
&& SQL_SUCCESS_WITH_INFO
!= retcode
) {
876 parentdb
->ErrorSnapshot(hStmt
);
880 return GetResultSet();
883 bool wxRecordSet::GetForeignKeys(char* PkTableName
, char * FkTableName
)
887 // char* wildcard = "%";
889 // Try to disable situation: both PkTableName and FkTableName are NULL
890 // set Pkname from tablename
891 if( !PkTableName
&& !FkTableName
) {
892 Pkname
= PkTableName
? PkTableName
: tablename
;
893 Fkname
= FkTableName
;
897 Pkname
= PkTableName
;
898 Fkname
= FkTableName
;
903 retcode
= SQLFreeStmt(hStmt
, SQL_DROP
);
904 if (retcode
== SQL_ERROR
)
906 parentdb
->ErrorSnapshot(hStmt
);
912 retcode
= SQLAllocStmt(parentdb
->GetHDBC(), &hStmt
);
914 if (SQL_SUCCESS
!= retcode
) {
915 parentdb
->ErrorSnapshot();
919 retcode
= SQLForeignKeys(hStmt
, NULL
, 0, NULL
, 0, (unsigned char *)Pkname
,
920 (Pkname
? SQL_NTS
: 0), NULL
, 0, NULL
, 0, (unsigned char *)Fkname
,(Fkname
?SQL_NTS
: 0) );
922 if (SQL_SUCCESS
!= retcode
&& SQL_SUCCESS_WITH_INFO
!= retcode
) {
923 parentdb
->ErrorSnapshot(hStmt
);
927 return GetResultSet();
930 long wxRecordSet::GetNumberRecords(void)
935 long wxRecordSet::GetNumberCols(void)
940 char* wxRecordSet::GetColName(int col
)
942 wxNode
* node
= cols
.Nth(col
);
947 return ((wxQueryCol
*)node
->Data())->GetName();
950 short wxRecordSet::GetColType(int col
)
952 wxNode
* node
= cols
.Nth(col
);
955 return SQL_TYPE_NULL
;
957 return ((wxQueryCol
*)node
->Data())->GetType();
960 short wxRecordSet::GetColType(const char *col
)
962 wxNode
* node
= cols
.Find(col
);
965 return SQL_TYPE_NULL
;
967 return ((wxQueryCol
*)node
->Data())->GetType();
970 bool wxRecordSet::GetFieldData(int col
, int type
, void* data
)
972 wxNode
* node
= cols
.Nth(col
);
977 if (((wxQueryCol
*)node
->Data())->GetType() != type
)
980 void* src
= ((wxQueryCol
*)node
->Data())->GetData(cursor
);
985 memcpy(data
, src
, ((wxQueryCol
*)node
->Data())->GetSize(cursor
));
990 bool wxRecordSet::GetFieldData(const char* name
, int type
, void *data
)
992 wxNode
* node
= cols
.Find(name
);
997 if (((wxQueryCol
*)node
->Data())->GetType() != type
)
1000 void* src
= ((wxQueryCol
*)node
->Data())->GetData(cursor
);
1005 memcpy(data
, src
, ((wxQueryCol
*)node
->Data())->GetSize(cursor
));
1010 void* wxRecordSet::GetFieldDataPtr(int col
, int type
)
1012 wxNode
* node
= cols
.Nth(col
);
1017 if (((wxQueryCol
*)node
->Data())->GetType() != type
)
1020 return ((wxQueryCol
*)node
->Data())->GetData(cursor
);
1023 void* wxRecordSet::GetFieldDataPtr(const char* name
, int type
)
1025 wxNode
* node
= cols
.Find(name
);
1030 if (((wxQueryCol
*)node
->Data())->GetType() != type
)
1033 return ((wxQueryCol
*)node
->Data())->GetData(cursor
);
1036 void* wxRecordSet::BindVar(int col
, void* var
, long size
) {
1037 wxNode
* node
= cols
.Nth(col
);
1042 return ((wxQueryCol
*)node
->Data())->BindVar(var
, size
);
1045 void* wxRecordSet::BindVar(const char* name
, void* var
, long size
) {
1046 wxNode
* node
= cols
.Find(name
);
1051 return ((wxQueryCol
*)node
->Data())->BindVar(var
, size
);
1054 void wxRecordSet::SetType(int typ
) {
1058 int wxRecordSet::GetType(void) {
1062 void wxRecordSet::SetOptions(int opts
) {
1066 int wxRecordSet::GetOptions(void) {
1070 bool wxRecordSet::CanAppend(void)
1075 bool wxRecordSet::CanRestart(void)
1080 bool wxRecordSet::CanScroll(void)
1085 bool wxRecordSet::CanTransact(void)
1090 bool wxRecordSet::CanUpdate(void)
1095 long wxRecordSet::GetCurrentRecord(void)
1100 bool wxRecordSet::RecordCountFinal(void)
1105 char* wxRecordSet::GetTableName(void)
1110 char *wxRecordSet::GetSQL(void)
1115 bool wxRecordSet::IsOpen(void)
1117 return parentdb
->IsOpen();
1120 bool wxRecordSet::IsBOF(void)
1125 bool wxRecordSet::IsEOF(void)
1127 return cursor
>= nRecords
;
1130 bool wxRecordSet::IsDeleted(void)
1135 // Update operations
1136 void wxRecordSet::AddNew(void)
1140 bool wxRecordSet::Delete(void)
1145 void wxRecordSet::Edit(void)
1149 bool wxRecordSet::Update(void)
1154 // Record navigation
1155 bool wxRecordSet::Move(long rows
)
1163 case wxOPEN_TYPE_SNAPSHOT
:
1164 cursor
+= (int)rows
;
1169 if (cursor
> nRecords
-1) {
1175 case wxOPEN_TYPE_DYNASET
:
1182 bool wxRecordSet::GoTo(long row
)
1190 case wxOPEN_TYPE_SNAPSHOT
:
1196 if (cursor
> nRecords
-1) {
1202 case wxOPEN_TYPE_DYNASET
:
1209 bool wxRecordSet::MoveFirst(void)
1217 case wxOPEN_TYPE_SNAPSHOT
:
1221 case wxOPEN_TYPE_DYNASET
:
1228 bool wxRecordSet::MoveLast(void)
1236 case wxOPEN_TYPE_SNAPSHOT
:
1237 cursor
= nRecords
-1;
1240 case wxOPEN_TYPE_DYNASET
:
1247 bool wxRecordSet::MoveNext(void)
1255 case wxOPEN_TYPE_SNAPSHOT
:
1257 if (cursor
>= nRecords
) {
1263 case wxOPEN_TYPE_DYNASET
:
1270 bool wxRecordSet::MovePrev(void)
1278 case wxOPEN_TYPE_SNAPSHOT
:
1286 case wxOPEN_TYPE_DYNASET
:
1294 void wxRecordSet::Cancel(void)
1298 bool wxRecordSet::IsFieldDirty(int col
)
1300 wxNode
* node
= cols
.Nth(col
);
1305 return ((wxQueryCol
*)node
->Data())->IsFieldDirty(cursor
);
1308 bool wxRecordSet::IsFieldDirty(const char* name
)
1310 wxNode
* node
= cols
.Find(name
);
1315 return ((wxQueryCol
*)node
->Data())->IsFieldDirty(cursor
);
1318 bool wxRecordSet::IsFieldNull(int col
)
1320 wxNode
* node
= cols
.Nth(col
);
1325 return NULL
!= ((wxQueryCol
*)node
->Data())->GetData(cursor
);
1328 bool wxRecordSet::IsFieldNull(const char* name
)
1330 wxNode
* node
= cols
.Find(name
);
1335 return NULL
!= ((wxQueryCol
*)node
->Data())->GetData(cursor
);
1338 bool wxRecordSet::IsColNullable(int col
)
1340 wxNode
* node
= cols
.Nth(col
);
1345 return ((wxQueryCol
*)node
->Data())->IsNullable();
1348 bool wxRecordSet::IsColNullable(const char* name
)
1350 wxNode
* node
= cols
.Find(name
);
1355 return ((wxQueryCol
*)node
->Data())->IsNullable();
1358 bool wxRecordSet::Requery(void)
1363 void wxRecordSet::SetFieldDirty(int col
, bool dirty
)
1365 wxNode
* node
= cols
.Nth(col
);
1370 ((wxQueryCol
*)node
->Data())->SetFieldDirty(cursor
, dirty
);
1373 void wxRecordSet::SetFieldDirty(const char* name
, bool dirty
)
1375 wxNode
* node
= cols
.Find(name
);
1380 ((wxQueryCol
*)node
->Data())->SetFieldDirty(cursor
, dirty
);
1383 void wxRecordSet::SetFieldNull(void *WXUNUSED(p
), bool WXUNUSED(isNull
))
1388 char *wxRecordSet::GetDefaultConnect(void)
1393 char *wxRecordSet::GetDefaultSQL(void)
1398 void wxRecordSet::SetDefaultSQL(char *s
)
1400 delete[] defaultSQL
;
1403 defaultSQL
= copystring(s
);
1408 // Build SQL query from column specification
1409 bool wxRecordSet::ConstructDefaultSQL(void)
1411 // if (queryCols.Number() == 0)
1415 bool wxRecordSet::ReleaseHandle(void)
1419 retcode
= SQLFreeStmt(hStmt
, SQL_DROP
);
1420 if (retcode
== SQL_ERROR
)
1423 parentdb
->ErrorSnapshot(hStmt
);
1431 wxQueryCol::wxQueryCol(void) {
1432 // __type = wxTYPE_QUERYCOL;
1434 type
= SQL_TYPE_NULL
;
1440 wxQueryCol::~wxQueryCol(void) {
1442 fields
.DeleteContents(TRUE
);
1449 void wxQueryCol::SetName(char* n
) {
1450 name
= new char[strlen(n
)+1];
1454 bool wxQueryCol::SetData(int row
, void* buf
, long len
) {
1455 wxNode
* node
= fields
.Nth(row
);
1460 return ((wxQueryField
*)node
->Data())->SetData(buf
, len
);
1463 void wxQueryCol::SetFieldDirty(int row
, bool dirty
) {
1464 wxNode
* node
= fields
.Nth(row
);
1469 ((wxQueryField
*)node
->Data())->SetDirty(dirty
);
1472 void wxQueryCol::AppendField(void* buf
, long len
) {
1473 wxNode
* node
= fields
.Append(new wxQueryField
);
1474 ((wxQueryField
*)node
->Data())->SetType(type
);
1475 ((wxQueryField
*)node
->Data())->SetData(buf
, len
);
1478 void wxQueryCol::SetType(short t
) {
1482 void* wxQueryCol::BindVar(void* v
, long s
) {
1491 void wxQueryCol::FillVar(int recnum
) {
1495 wxNode
* node
= fields
.Nth(recnum
);
1500 long actsize
= ((wxQueryField
*)node
->Data())->GetSize();
1501 if (actsize
> varsize
)
1504 memcpy(var
, ((wxQueryField
*)node
->Data())->GetData(), actsize
);
1507 void wxQueryCol::SetNullable(bool n
) {
1511 char* wxQueryCol::GetName(void) {
1515 short wxQueryCol::GetType(void) {
1519 bool wxQueryCol::IsNullable(void) {
1524 bool wxQueryCol::IsFieldDirty(int row
) {
1525 wxNode
* node
= fields
.Nth(row
);
1530 return ((wxQueryField
*)node
->Data())->IsDirty();
1533 void* wxQueryCol::GetData(int row
) {
1534 wxNode
* node
= fields
.Nth(row
);
1539 return ((wxQueryField
*)node
->Data())->GetData();
1542 long wxQueryCol::GetSize(int row
) {
1543 wxNode
* node
= fields
.Nth(row
);
1548 return ((wxQueryField
*)node
->Data())->GetSize();
1551 wxQueryField::wxQueryField(void) {
1552 // __type = wxTYPE_QUERYROW;
1554 type
= SQL_TYPE_NULL
;
1559 wxQueryField::~wxQueryField(void) {
1567 delete[] (char*)data
;
1575 delete (short*)data
;
1580 delete (double*)data
;
1584 delete (float*)data
;
1588 delete (TIME_STRUCT
*)data
;
1592 delete (DATE_STRUCT
*)data
;
1596 delete (TIMESTAMP_STRUCT
*)data
;
1601 bool wxQueryField::AllocData(void) {
1610 delete[] (char*)data
;
1611 if ((data
= new char[size
+1]))
1613 char *str
= (char *)data
;
1615 for (i
= 0; i
< size
; i
++)
1617 // memset(data, 0, size+1);
1625 if ((data
= new long))
1632 delete (short*)data
;
1633 if ((data
= new short))
1641 delete (double*)data
;
1642 if ((data
= new double))
1649 delete (float*)data
;
1650 if ((data
= new float))
1651 *(float*)data
= (float)0;
1657 delete (TIME_STRUCT
*)data
;
1658 data
= new TIME_STRUCT
;
1659 memset(data
, 0, sizeof(TIME_STRUCT
));
1665 delete (DATE_STRUCT
*)data
;
1666 data
= new DATE_STRUCT
;
1667 memset(data
, 0, sizeof(DATE_STRUCT
));
1673 delete (TIMESTAMP_STRUCT
*)data
;
1674 data
= new TIMESTAMP_STRUCT
;
1675 memset(data
, 0, sizeof(TIMESTAMP_STRUCT
));
1685 bool wxQueryField::SetData(void* d
, long s
) {
1687 if (AllocData() && d
)
1689 // memcpy(data, d, s);
1697 char *str
= (char *)data
;
1699 for (i
= 0; i
< size
; i
++)
1702 strncpy(str
, (char *)d
, (int)size
);
1708 *(long*)data
= *((long *)d
);
1713 *(short*)data
= *((short*)d
);
1719 *(double*)data
= *((double*)d
);
1724 *(float*)data
= *((float*)d
);
1729 *(TIME_STRUCT
*)data
= *((TIME_STRUCT
*)d
);
1734 *(TIMESTAMP_STRUCT
*)data
= *((TIMESTAMP_STRUCT
*)d
);
1739 *(DATE_STRUCT
*)data
= *((DATE_STRUCT
*)d
);
1750 void wxQueryField::ClearData(void) {
1753 // memset(data, 0, size);
1761 char *str
= (char *)data
;
1763 for (i
= 0; i
< size
; i
++)
1780 *(double*)data
= (double)0.0;
1785 *(float*)data
= (float)0.0;
1790 memset(data
, 0, sizeof(TIME_STRUCT
));
1795 memset(data
, 0, sizeof(DATE_STRUCT
));
1800 memset(data
, 0, sizeof(TIMESTAMP_STRUCT
));
1809 void wxQueryField::SetDirty(bool d
) {
1813 void wxQueryField::SetType(short t
) {
1817 void wxQueryField::SetSize(long s
) {
1822 void* wxQueryField::GetData(void) {
1826 short wxQueryField::GetType(void) {
1830 long wxQueryField::GetSize(void) {
1834 bool wxQueryField::IsDirty(void) {
1839 #pragma warning(default:4706) // assignment within conditional expression
1842 #endif // wxUSE_OLD_ODBC