\section{Database classes overview}\label{odbcoverview}
-\normalboxd{The more sophisticated wxODBC classes (wxDb/wxDbTable) are the
-recommended classes for doing database/ODBC work with wxWindows. These new
-classes replace the wxWindows v1.6x classes wxDatabase. Documentation for the
-old wxDatabase class and its associated classes is still
-included in the class documentation and in this overview section, but support
-for these old classes has been phased out, and all future development work
-is being done solely on the new wxDb/wxDbTable classes.}
-
-\subsection{Different ODBC Class Libraries in wxWindows}
-
Following is a detailed overview of how to use the wxWindows ODBC classes - \helpref{wxDb}{wxdb}
and \helpref{wxDbTable}{wxdbtable} and their associated functions. These are
the ODBC classes donated by Remstar International, and are collectively
-referred to herein as the wxODBC classes. Since their initial inclusion with
-wxWindows v2.x, they have become the recommended wxWindows classes for database
-access.
-
-An older version of some classes ported over from wxWindows v1.68 still exist
-(see \helpref{wxDatabase}{wxdatabase} in odbc.cpp), but are now deprecated in favor of the more
-robust and comprehensive wxDb/wxDbTable classes. All current and future
-feature development, as well as active debugging, are only being done on
-the wxODBC classes. Documentation for the older classes is still provided
-in this manual. The \helpref{wxDatabase overview}{wxdatabaseoverview} of the
-older classes follows the overview of the new classes.
+referred to herein as the wxODBC classes.
\subsection{wxDb/wxDbTable wxODBC Overview}\label{wxodbcoverview}
\end{verbatim}
-\subsection{wxDatabase ODBC class overview [DEPRECATED]}\label{oldwxodbcoverview}
-
-Classes: \helpref{wxDatabase}{wxdatabase}, \helpref{wxRecordSet}{wxrecordset}, \helpref{wxQueryCol}{wxquerycol},
-\rtfsp\helpref{wxQueryField}{wxqueryfield}
-
-\normalboxd{The more sophisticated wxODBC classes (wxDb/wxDbTable) are the
-recommended classes for doing database/ODBC work with wxWindows. These new
-classes replace the wxWindows v1.6x classes wxDatabase.
-
-Documentation for the old wxDatabase class and its associated classes is still
-included in the class documentation and in this overview section, but support
-for these old classes has been phased out, and all future development work
-is being done solely on the new wxDb/wxDbTable classes.}
-
-wxWindows provides a set of classes for accessing a subset of Microsoft's ODBC (Open Database Connectivity)
-product. Currently, this wrapper is available under MS Windows only, although
-ODBC may appear on other platforms, and a generic or product-specific SQL emulator for the ODBC
-classes may be provided in wxWindows at a later date.
-
-ODBC presents a unified API (Application Programmer's Interface) to a
-wide variety of databases, by interfacing indirectly to each database or
-file via an ODBC driver. The language for most of the database
-operations is SQL, so you need to learn a small amount of SQL as well as
-the wxWindows ODBC wrapper API. Even though the databases may not be
-SQL-based, the ODBC drivers translate SQL into appropriate operations
-for the database or file: even text files have rudimentary ODBC support,
-along with dBASE, Access, Excel and other file formats.
-
-The run-time files for ODBC are bundled with many existing database
-packages, including MS Office. The required header files, sql.h and
-sqlext.h, are bundled with several compilers including MS VC++ and
-Watcom C++. The only other way to obtain these header files is from the
-ODBC SDK, which is only available with the MS Developer Network CD-ROMs
--- at great expense. If you have odbc.dll, you can make the required
-import library odbc.lib using the tool `implib'. You need to have odbc.lib
-in your compiler library path.
-
-The minimum you need to distribute with your application is odbc.dll, which must
-go in the Windows system directory. For the application to function correctly,
-ODBC drivers must be installed on the user's machine. If you do not use the database
-classes, odbc.dll will be loaded but not called (so ODBC does not need to be
-setup fully if no ODBC calls will be made).
-
-A sample is distributed with wxWindows in {\tt samples/odbc}. You will need to install
-the sample dbf file as a data source using the ODBC setup utility, available from
-the control panel if ODBC has been fully installed.
-
-\subsection{Procedures for writing an ODBC application using wxDatabase [DEPRECATED]}
-
-You first need to create a wxDatabase object. If you want to get information
-from the ODBC manager instead of from a particular database (for example
-using \helpref{wxRecordSet::GetDataSources}{wxrecordsetgetdatasources}), then you
-do not need to call \helpref{wxDatabase::Open}{wxdatabaseopen}.
-If you do wish to connect to a datasource, then call wxDatabase::Open.
-You can reuse your wxDatabase object, calling wxDatabase::Close and wxDatabase::Open
-multiple times.
-
-Then, create a wxRecordSet object for retrieving or sending information.
-For ODBC manager information retrieval, you can create it as a dynaset (retrieve the
-information as needed) or a snapshot (get all the data at once).
-If you are going to call \helpref{wxRecordSet::ExecuteSQL}{wxrecordsetexecutesql}, you need to create it as a snapshot.
-Dynaset mode is not yet implemented for user data.
-
-Having called a function such as wxRecordSet::ExecuteSQL or
-wxRecordSet::GetDataSources, you may have a number of records
-associated with the recordset, if appropriate to the operation. You can
-now retrieve information such as the number of records retrieved and the
-actual data itself. Use \helpref{wxRecordSet::GetFieldData}{wxrecordsetgetfielddata} or
-\helpref{wxRecordSet::GetFieldDataPtr}{wxrecordsetgetfielddataptr} to get the data or a pointer to it, passing
-a column index or name. The data returned will be for the current
-record. To move around the records, use \helpref{wxRecordSet::MoveNext}{wxrecordsetmovenext},
-\rtfsp\helpref{wxRecordSet::MovePrev}{wxrecordsetmoveprev} and associated functions.
-
-You can use the same recordset for multiple operations, or delete
-the recordset and create a new one.
-
-Note that when you delete a wxDatabase, any associated recordsets
-also get deleted, so beware of holding onto invalid pointers.
-
-\subsection{wxDatabase class overview [DEPRECATED]}\label{wxdatabaseoverview}
-
-Class: \helpref{wxDatabase}{wxdatabase}
-
-\wxheading{DEPRECATED}
-
-Use \helpref{wxDb}{wxdb} and \helpref{wxDbTable}{wxdbtable} instead.
-
-Every database object represents an ODBC connection. To do anything useful
-with a database object you need to bind a wxRecordSet object to it. All you
-can do with wxDatabase is opening/closing connections and getting some info
-about it (users, passwords, and so on).
-
-\wxheading{See also}
-
-\helpref{Database classes overview}{odbcoverview}
-
-\subsection{wxQueryCol class overview [DEPRECATED]}\label{wxquerycoloverview}
-
-Class: \helpref{wxQueryCol}{wxquerycol}
-
-\wxheading{DEPRECATED}
-
-Use \helpref{wxDb}{wxdb} and \helpref{wxDbTable}{wxdbtable} instead.
-
-Every data column is represented by an instance of this class.
-It contains the name and type of a column and a list of wxQueryFields where
-the real data is stored. The links to user-defined variables are stored
-here, as well.
-
-\wxheading{See also}
-
-\helpref{Database classes overview}{odbcoverview}
-
-\subsection{wxQueryField class overview [DEPRECATED]}\label{wxqueryfieldoverview}
-
-Class: \helpref{wxQueryField}{wxqueryfield}
-
-\wxheading{DEPRECATED}
-
-Use \helpref{wxDb}{wxdb} and \helpref{wxDbTable}{wxdbtable} instead.
-
-As every data column is represented by an instance of the class wxQueryCol,
-every data item of a specific column is represented by an instance of
-wxQueryField. Each column contains a list of wxQueryFields. If wxRecordSet is
-of the type wxOPEN\_TYPE\_DYNASET, there will be only one field for each column,
-which will be updated every time you call functions like wxRecordSet::Move
-or wxRecordSet::GoTo. If wxRecordSet is of the type wxOPEN\_TYPE\_SNAPSHOT,
-all data returned by an ODBC function will be loaded at once and the number
-of wxQueryField instances for each column will depend on the number of records.
-
-\wxheading{See also}
-
-\helpref{Database classes overview}{odbcoverview}
-
-\subsection{wxRecordSet overview [DEPRECATED]}\label{wxrecordsetoverview}
-
-Class: \helpref{wxRecordSet}{wxrecordset}
-
-\wxheading{DEPRECATED}
-
-Use \helpref{wxDb}{wxdb} and \helpref{wxDbTable}{wxdbtable} instead.
-
-Each wxRecordSet represents a database query. You can make multiple queries
-at a time by using multiple wxRecordSets with a wxDatabase or you can make
-your queries in sequential order using the same wxRecordSet.
-
-\wxheading{See also}
-
-\helpref{Database classes overview}{odbcoverview}
-
-\subsection{ODBC SQL data types [DEPRECATED]}\label{sqltypes}
-
-These are the data types supported in ODBC SQL. Note that there are other, extended level conformance
-types, not currently supported in wxWindows.
-
-\begin{twocollist}\itemsep=0pt
-\twocolitem{CHAR(n)}{A character string of fixed length {\it n}.}
-\twocolitem{VARCHAR(n)}{A varying length character string of maximum length {\it n}.}
-\twocolitem{LONG VARCHAR(n)}{A varying length character string: equivalent to VARCHAR for the purposes
-of ODBC.}
-\twocolitem{DECIMAL(p, s)}{An exact numeric of precision {\it p} and scale {\it s}.}
-\twocolitem{NUMERIC(p, s)}{Same as DECIMAL.}
-\twocolitem{SMALLINT}{A 2 byte integer.}
-\twocolitem{INTEGER}{A 4 byte integer.}
-\twocolitem{REAL}{A 4 byte floating point number.}
-\twocolitem{FLOAT}{An 8 byte floating point number.}
-\twocolitem{DOUBLE PRECISION}{Same as FLOAT.}
-\end{twocollist}
-
-These data types correspond to the following ODBC identifiers:
-
-\begin{twocollist}\itemsep=0pt
-\twocolitem{SQL\_CHAR}{A character string of fixed length.}
-\twocolitem{SQL\_VARCHAR}{A varying length character string.}
-\twocolitem{SQL\_DECIMAL}{An exact numeric.}
-\twocolitem{SQL\_NUMERIC}{Same as SQL\_DECIMAL.}
-\twocolitem{SQL\_SMALLINT}{A 2 byte integer.}
-\twocolitem{SQL\_INTEGER}{A 4 byte integer.}
-\twocolitem{SQL\_REAL}{A 4 byte floating point number.}
-\twocolitem{SQL\_FLOAT}{An 8 byte floating point number.}
-\twocolitem{SQL\_DOUBLE}{Same as SQL\_FLOAT.}
-\end{twocollist}
-
-\wxheading{See also}
-
-\helpref{Database classes overview}{odbcoverview}
-
-\subsection{A selection of SQL commands [DEPRECATED]}\label{sqlcommands}
+\subsection{A selection of SQL commands}\label{sqlcommands}
The following is a very brief description of some common SQL commands, with
examples.
+++ /dev/null
-/////////////////////////////////////////////////////////////////////////////
-// Name: odbc.h
-// Purpose: ODBC classes
-// Author: Olaf Klein, Patrick Halke, Julian Smart
-// Modified by:
-// Created: 01/02/97
-// RCS-ID: $Id$
-// Copyright: (c) Olaf Klein, Patrick Halke, Julian Smart
-// Licence: wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
-
-#include "wx/setup.h"
-
-#if wxUSE_ODBC
-
-#if defined(__GNUG__) && !defined(__APPLE__)
-#pragma interface "odbc.h"
-#endif
-
-#ifndef _WX_ODBCH__
-#define _WX_ODBCH__
-
-//#ifdef __WXMSW__
-//#include <windows.h>
-//#endif
-
-
-#ifdef __UNIX__
-extern "C"
-{
- #include "wx/isql.h"
- #include "wx/isqlext.h"
-
- typedef float SFLOAT;
- typedef double SDOUBLE;
-
- #define ULONG UDWORD
- #define SQL_SQLSTATE_SIZE 5
-}
-#else // !Unix
- #include <sqlext.h>
-#endif // Unix/!Unix
-
-#include "wx/defs.h"
-#include "wx/list.h"
-#include "wx/string.h"
-
-typedef RETCODE wxRETCODE;
-
-// Recordset open types
-#define wxOPEN_TYPE_DYNASET 1
-#define wxOPEN_TYPE_SNAPSHOT 2
-#define wxOPEN_TYPE_FORWARD_ONLY 3
-
-// Recordset open options
-#define wxOPTION_DEFAULT 1
-#define wxOPTION_APPEND_ONLY 2
-#define wxOPTION_READ_ONLY 3
-
-// Data types
-class WXDLLEXPORT wxRecordSet;
-
-class WXDLLEXPORT wxDatabase: public wxObject
-{
- DECLARE_DYNAMIC_CLASS(wxDatabase)
- protected:
- static HENV hEnv;
- static int refCount;
-
- HDBC hDBC;
- char* username;
- char* password;
- char* datasource;
- char* dbname;
- char* connectstring;
- bool isOpen;
-
- // error-handling variables
- wxRETCODE retcode;
- char sqlstate[SQL_SQLSTATE_SIZE+1]; // error class and subclass
- char errmsg[SQL_MAX_MESSAGE_LENGTH]; // error message
- long nat_err; // error number by ODBC driver
- bool err_occured;
-
- wxList recordSets; // Record sets: Added by JACS
-
- public:
- wxDatabase();
- ~wxDatabase();
-
- bool Open(char *, bool exclusive =FALSE, bool readOnly =TRUE, char *username ="ODBC", char *password ="");
- bool Close();
-
- // Cleanup operations, added by JACS
- void DeleteRecordSets(void); // Called when the database is deleted
- void ResetRecordSets(void); // Required if the database is closed
- inline wxList& GetRecordSets(void) { return recordSets; }
-
- inline char *GetUsername(void) { return username; }
- inline char *GetPassword(void) { return password; }
- inline char *GetDataSource(void) { return datasource; }
- inline bool IsOpen(void) { return isOpen; }
- inline wxRETCODE GetErrorCode(void) { return retcode; }
- inline HDBC GetHDBC(void) { return hDBC; }
- inline HENV GetHENV(void) { return hEnv; }
-
- void SetPassword(char *s);
- void SetUsername(char *s);
- void SetDataSource(char *s);
-
- // Database attributes
- char *GetDatabaseName();
- bool CanUpdate();
- bool CanTransact();
- bool InWaitForDataSource();
- void SetLoginTimeout(long seconds);
- void SetQueryTimeout(long seconds);
- void SetSynchronousMode(bool synchronous);
-
- // Database operations
- bool BeginTrans();
- bool CommitTrans();
- bool RollbackTrans();
- void Cancel();
-
- // Error handling
- bool ErrorOccured();
- char* GetErrorMessage();
- long GetErrorNumber();
- char* GetErrorClass();
- inline void ErrorSnapshot(HSTMT =SQL_NULL_HSTMT);
-
- // Overridables
- virtual void OnSetOptions(wxRecordSet *recordSet);
- virtual void OnWaitForDataSource(bool stillExecuting);
-
- bool GetInfo(long infoType, long *buf);
- bool GetInfo(long infoType, char *buf, int bufSize = -1);
-
- // implementation = TRUE means get the DLL version.
- // Otherwise, returns header file version.
- wxString GetODBCVersionString(bool implementation = TRUE);
- float GetODBCVersionFloat(bool implementation = TRUE);
-};
-
-// Represents a data row
-class WXDLLEXPORT wxQueryField: public wxObject
-{
- // JACS
- DECLARE_DYNAMIC_CLASS(wxQueryField)
- private:
- void *data;
- short type;
- long size;
- bool dirty;
-
- bool AllocData();
-
- public:
- wxQueryField();
- ~wxQueryField();
-
- bool SetData(void*, long);
- void SetDirty(bool =TRUE);
- void ClearData();
- void SetType(short);
- void SetSize(long);
-
- void* GetData();
- short GetType();
- long GetSize();
-
- bool IsDirty();
-};
-
-// Represents a column description
-class WXDLLEXPORT wxQueryCol: public wxObject
-{
- // JACS
- DECLARE_DYNAMIC_CLASS(wxQueryCol)
- private:
- short type;
- char *name;
- bool nullable;
- long varsize;
- void* var;
-
- public:
- wxList fields;
-
- wxQueryCol();
- ~wxQueryCol();
-
- void* BindVar(void*, long);
- void FillVar(int);
- void AppendField(void*, long);
- bool SetData(int, void*, long);
- void SetName(char*);
- void SetNullable(bool);
- void SetFieldDirty(int, bool =TRUE);
- void SetType(short);
-
- char* GetName();
- short GetType();
- bool IsNullable();
- void* GetData(int);
- long GetSize(int);
-
- bool IsFieldDirty(int);
-};
-
-class WXDLLEXPORT wxRecordSet: public wxObject
-{
- // JACS
- DECLARE_DYNAMIC_CLASS(wxRecordSet)
- private:
- int cursor;
- int type;
- int options;
-
- protected:
- HSTMT hStmt;
- int nFields;
- int nParams;
- int nRecords;
- short nCols;
- char *recordFilter;
- char *sortString;
- char *defaultSQL;
- char* tablename;
- wxDatabase *parentdb;
- wxRETCODE retcode;
- wxList cols;
- wxList fetchbuf;
-
- void FillVars(int);
-
- public:
- // JACS gave parent a default value for benefit of IMPLEMENT_DYNAMIC_CLASS
- wxRecordSet(wxDatabase *parent = NULL,
- int = wxOPEN_TYPE_DYNASET,
- int = wxOPTION_DEFAULT);
- ~wxRecordSet();
-
- // My own, lower-level functions.
- bool BeginQuery(int openType, char *sql = NULL, int options = wxOPTION_DEFAULT);
- bool EndQuery();
- bool Query(char* columns, char* table =NULL, char *filter =NULL);
-
- // Attributes
- inline int GetNumberFields(void) { return nFields; }
- inline int GetNumberParams(void) { return nParams; }
- long GetNumberRecords();
- long GetNumberCols();
- inline char *GetFilter(void) { return recordFilter; }
- inline char *GetSortString(void) { return sortString; }
- inline wxDatabase *GetDatabase(void) { return parentdb; }
- inline wxRETCODE GetErrorCode(void) { return retcode; }
- bool CanAppend();
- bool CanRestart();
- bool CanScroll();
- bool CanTransact();
- bool CanUpdate();
- long GetCurrentRecord();
- bool RecordCountFinal();
- bool GetResultSet();
- bool ExecuteSQL(char*);
- bool GetTables();
- bool GetColumns(char* =NULL);
- bool GetPrimaryKeys(char* =NULL);
- bool GetForeignKeys(char* , char * );
- char *GetTableName();
- void SetTableName(char*);
- char *GetSQL();
- bool IsOpen();
- bool IsBOF();
- bool IsEOF();
- bool IsDeleted();
-
- bool GetFieldData(int colPos, int dataType, void *dataPtr);
- bool GetFieldData(const char*, int dataType, void *dataPtr);
- void* GetFieldDataPtr(int, int);
- void* GetFieldDataPtr(const char*, int);
- char* GetColName(int);
- short GetColType(int);
- short GetColType(const char*);
- void* BindVar(int, void*, long);
- void* BindVar(const char*, void*, long);
-
- void SetType(int);
- int GetType();
- void SetOptions(int);
- int GetOptions();
-
- // Update operations
- void AddNew();
- bool Delete();
- void Edit();
- bool Update();
-
- // Record navigation
- virtual bool Move(long rows);
- virtual bool MoveFirst();
- virtual bool MoveLast();
- virtual bool MoveNext();
- virtual bool MovePrev();
- virtual bool GoTo(long);
-
- // Others
- bool GetDataSources();
-
- // Associate a column name/position with a data location
- // bool BindColumn(int colPos, int dataType, void *dataPtr);
-
- void Cancel();
- bool IsFieldDirty(int);
- bool IsFieldDirty(const char*);
- bool IsFieldNull(int);
- bool IsFieldNull(const char*);
- bool IsColNullable(int);
- bool IsColNullable(const char*);
- virtual bool Requery();
- virtual void SetFieldDirty(int, bool dirty = TRUE);
- virtual void SetFieldDirty(const char*, bool dirty = TRUE);
- void SetFieldNull(void *p, bool isNull = TRUE);
-
- // Overridables
- virtual char *GetDefaultConnect();
- virtual char *GetDefaultSQL();
-
- // Internal
-
- // Build SQL query from column specification
- bool ConstructDefaultSQL();
- void SetDefaultSQL(char *s);
- bool ReleaseHandle(void); // Added JACS
-};
-
-#endif
-
-#endif // wxUSE_ODBC
+++ /dev/null
-/////////////////////////////////////////////////////////////////////////////
-// Name: odbc.cpp
-// Purpose: ODBC implementation
-// Author: Julian Smart, Olaf Klein (oklein@smallo.ruhr.de),
-// Patrick Halke (patrick@zaphod.ruhr.de)
-// Modified by:
-// Created: 04/01/98
-// RCS-ID: $Id$
-// Copyright: (c) Julian Smart
-// Licence: wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
-
-#ifdef __GNUG__
-#pragma implementation "odbc.h"
-#endif
-
-// For compilers that support precompilation, includes "wx.h".
-#include "wx/wxprec.h"
-
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
-#include "wx/defs.h"
-
-// this code is old and shouldn't be used - use the new ODBC classes in db.cpp
-// and dbtable.cpp instead
-#define wxUSE_OLD_ODBC 0
-
-#if wxUSE_OLD_ODBC
-
-#ifdef __VISUALC__
- #pragma warning(disable:4706) // assignment within conditional expression
-#endif // VC++
-
-#ifndef WX_PRECOMP
-#include "wx/utils.h"
-#include "wx/dialog.h"
-#endif
-
-#include "wx/string.h"
-#include "wx/odbc.h"
-
-#include <math.h>
-#include <stdlib.h>
-
-#if defined(__WXMSW__) && !defined(__WIN32__)
-#include <print.h>
-#endif
-
-HENV wxDatabase::hEnv = 0;
-int wxDatabase::refCount = 0;
-
-IMPLEMENT_DYNAMIC_CLASS(wxDatabase, wxObject)
-IMPLEMENT_DYNAMIC_CLASS(wxQueryCol, wxObject)
-IMPLEMENT_DYNAMIC_CLASS(wxQueryField, wxObject)
-IMPLEMENT_DYNAMIC_CLASS(wxRecordSet, wxObject)
-
-wxDatabase::wxDatabase(void)
-{
- hDBC = 0;
- username = NULL;
- password = NULL;
- datasource = NULL;
- dbname = NULL;
- connectstring = NULL;
- isOpen = FALSE;
- refCount ++;
- retcode = 0;
- username = NULL;
- password = NULL;
- err_occured = FALSE;
-
- memset(sqlstate, 0, sizeof sqlstate);
- memset(errmsg, 0, sizeof errmsg);
-
- if (hEnv == 0)
- {
- retcode = SQLAllocEnv(&hEnv);
-
- if (retcode != SQL_SUCCESS)
- hEnv = 0;
- }
-}
-
-wxDatabase::~wxDatabase(void)
-{
- Close();
- DeleteRecordSets(); // Added JACS
-
- if (connectstring)
- delete[] connectstring;
- if (datasource)
- delete[] datasource;
- if (username)
- delete[] username;
- if (password)
- delete[] password;
- if (dbname)
- delete[] dbname;
-
- refCount --;
- if (!refCount && hEnv)
- {
- retcode = SQLFreeEnv(hEnv);
- hEnv = 0; // JACS 17/6
- }
-}
-
-void wxDatabase::ErrorSnapshot(HSTMT hstmt)
-{
- SWORD len = 0; // JACS: sometimes doesn't get filled in by SQLError.
-
- err_occured = TRUE;
- SQLError(hEnv, hDBC, hstmt, (unsigned char *)sqlstate, &nat_err, (unsigned char *)errmsg, SQL_MAX_MESSAGE_LENGTH-1, &len);
- errmsg[len] = '\0';
-}
-
-bool wxDatabase::ErrorOccured(void)
-{
- return err_occured;
-}
-
-char* wxDatabase::GetErrorMessage(void)
-{
- return errmsg;
-}
-
-long wxDatabase::GetErrorNumber(void)
-{
- return nat_err;
-}
-
-char* wxDatabase::GetErrorClass(void) {
- return sqlstate;
-}
-
-bool wxDatabase::Open(char *thedatasource, bool WXUNUSED(exclusive),
- bool WXUNUSED(readOnly), char *username, char *password)
-{
- err_occured = FALSE;
-
- if (isOpen)
- return FALSE;
-
- SetUsername(username);
- SetPassword(password);
- SetDataSource(thedatasource);
-
- if (!hEnv)
- return FALSE;
-
- retcode = SQLAllocConnect(hEnv, &hDBC);
- if (retcode != SQL_SUCCESS) {
- hDBC = 0;
- return FALSE;
- }
-
- retcode = SQLConnect(hDBC, (UCHAR FAR*)thedatasource, strlen(thedatasource), (UCHAR FAR*)username, strlen(username),
- (UCHAR FAR*)password, strlen(password));
-
- if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
- ErrorSnapshot();
- return FALSE;
- }
-
- isOpen = TRUE;
-
- return TRUE;
-}
-
-bool wxDatabase::Close(void)
-{
- // JACS: make sure the record set statements are all released.
- ResetRecordSets();
-
- err_occured = FALSE;
- if (hDBC != 0)
- {
- retcode = SQLDisconnect(hDBC);
-
- if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
- ErrorSnapshot();
- return FALSE;
- }
-
- retcode = SQLFreeConnect(hDBC);
-
- hDBC = 0;
- isOpen = FALSE;
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-// Database attributes
-char *wxDatabase::GetDatabaseName(void)
-{
- err_occured = FALSE;
- if (hDBC == 0)
- return NULL;
-
- char nameBuf[400];
- int nameSize = 0;
-
- retcode = SQLGetInfo(hDBC, SQL_DATABASE_NAME, (unsigned char*)nameBuf, sizeof(nameBuf), (short *)&nameSize);
-
- if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
- return NULL;
-
- delete[] dbname;
- dbname = NULL;
-
- if (nameSize > 0)
- {
- dbname = copystring(nameBuf);
- return dbname;
- }
- else
- return NULL;
-}
-
-bool wxDatabase::CanUpdate(void)
-{
- return FALSE;
-}
-
-bool wxDatabase::CanTransact(void)
-{
- return FALSE;
-}
-
-bool wxDatabase::InWaitForDataSource(void)
-{
- return FALSE;
-}
-
-void wxDatabase::SetLoginTimeout(long WXUNUSED(seconds))
-{
-}
-
-void wxDatabase::SetQueryTimeout(long WXUNUSED(seconds))
-{
-}
-
-void wxDatabase::SetSynchronousMode(bool WXUNUSED(synchronous))
-{
-}
-
-// Database operations
-bool wxDatabase::BeginTrans(void)
-{
- return FALSE;
-}
-
-bool wxDatabase::CommitTrans(void)
-{
- return FALSE;
-}
-
-bool wxDatabase::RollbackTrans(void)
-{
- return FALSE;
-}
-
-void wxDatabase::Cancel(void)
-{
-}
-
-// Overridables
-void wxDatabase::OnSetOptions(wxRecordSet *WXUNUSED(recordSet))
-{
-}
-
-void wxDatabase::OnWaitForDataSource(bool WXUNUSED(stillExecuting))
-{
-}
-
-void wxDatabase::SetPassword(char *s)
-{
- if (password)
- delete[] password;
- if (s)
- {
- password = copystring(s);
- }
- else
- password = NULL;
-}
-
-void wxDatabase::SetUsername(char *s)
-{
- delete[] username;
-
- if (s)
- username = copystring(s);
- else
- username = NULL;
-}
-
-void wxDatabase::SetDataSource(char *s)
-{
- delete[] datasource;
-
- if (s)
- datasource = copystring(s);
- else
- datasource = NULL;
-}
-
-/*
- * Added by JACS
- */
-
-void wxDatabase::DeleteRecordSets(void)
-{
- wxNode *node = recordSets.First();
- while (node)
- {
- wxNode *next = node->Next();
- wxRecordSet *rec = (wxRecordSet *)node->Data();
- delete rec;
- // The node is implicitly deleted by ~wxRecordSet
- node = next;
- }
-}
-
-void wxDatabase::ResetRecordSets(void)
-{
- wxNode *node = recordSets.First();
- while (node)
- {
- wxRecordSet *rec = (wxRecordSet *)node->Data();
- rec->ReleaseHandle();
-
- node = node->Next();
- }
-}
-
-bool wxDatabase::GetInfo(long infoType, long *buf)
-{
- short sz = 0;
- retcode = SQLGetInfo(hDBC, (UWORD)infoType, (unsigned char*)buf, sizeof(buf), &sz);
-
- if (retcode != SQL_ERROR)
- return TRUE;
- else
- return FALSE;
-}
-
-bool wxDatabase::GetInfo(long infoType, char *buf, int bufSize)
-{
- if (bufSize == -1)
- bufSize = sizeof(buf);
-
- short sz = 0;
- retcode = SQLGetInfo(hDBC, (UWORD)infoType, (unsigned char*)buf, bufSize, &sz);
-
- if (retcode != SQL_ERROR)
- return TRUE;
- else
- return FALSE;
-}
-
-wxString wxDatabase::GetODBCVersionString(bool implementation)
-{
- char buf[50];
- if (!implementation)
- {
-#ifdef SQL_SPEC_MAJOR
- sprintf(buf, "%d%d.%d", (int)(SQL_SPEC_MAJOR/10), (int)(SQL_SPEC_MAJOR - (((int)(SQL_SPEC_MAJOR/10))*10)),
- SQL_SPEC_MINOR);
- return wxString(buf);
-#else
- return wxString("00.00");
-#endif
- }
-
- bool noDBC = FALSE;
- if (hDBC == 0)
- {
- noDBC = TRUE;
- retcode = SQLAllocConnect(hEnv, &hDBC);
- if (retcode != SQL_SUCCESS)
- {
- hDBC = 0;
- return wxString("00.00");
- }
- }
-
- int bufSize = sizeof(buf);
-
- short sz = 0;
- retcode = SQLGetInfo(hDBC, (UWORD)SQL_ODBC_VER, (unsigned char*)buf, bufSize, &sz);
-
- if (hDBC != 0 && noDBC)
- {
- retcode = SQLFreeConnect(hDBC);
- hDBC = 0;
- }
-
- if (retcode == SQL_ERROR)
- return wxString("");
- else
- return wxString(buf);
-}
-
-float wxDatabase::GetODBCVersionFloat(bool implementation)
-{
- if (!implementation)
- {
-#ifdef SQL_SPEC_MAJOR
- return (float)(SQL_SPEC_MAJOR + (SQL_SPEC_MINOR/100.0));
-#else
- return 0.0;
-#endif
- }
-
- bool noDBC = FALSE;
- if (hDBC == 0)
- {
- noDBC = TRUE;
- retcode = SQLAllocConnect(hEnv, &hDBC);
- if (retcode != SQL_SUCCESS)
- {
- hDBC = 0;
- return (float)0.0;
- }
- }
-
- char buf[50];
- int bufSize = sizeof(buf);
-
- short sz = 0;
- retcode = SQLGetInfo(hDBC, (UWORD)SQL_ODBC_VER, (unsigned char*)buf, bufSize, &sz);
-
- if (hDBC != 0 && noDBC)
- {
- retcode = SQLFreeConnect(hDBC);
- hDBC = 0;
- }
-
- if (retcode == SQL_ERROR)
- return 0.0;
- else
- return (float)atof(buf);
-}
-
-/*
- * wxRecordSet
- */
-
-wxRecordSet::wxRecordSet(wxDatabase *db, int typ, int opt):
- cols(wxKEY_STRING)
-{
- parentdb = db;
- hStmt = 0;
- nFields = 0;
- nParams = 0;
- recordFilter = NULL;
- sortString = NULL;
- retcode = 0;
- cursor = 0;
- tablename = NULL;
- nCols = 0;
- nRecords = 0;
-
- type = typ;
- options = opt;
-
- // Added JACS
- if (parentdb)
- parentdb->GetRecordSets().Append(this);
-}
-
-wxRecordSet::~wxRecordSet(void)
-{
- ReleaseHandle();
-
- // JACS
- if (parentdb)
- parentdb->GetRecordSets().DeleteObject(this);
-
- if (recordFilter)
- delete[] recordFilter;
- if (sortString)
- delete[] sortString;
- if (tablename)
- delete[] tablename;
-}
-
-// If SQL is non-NULL, table and columns can be NULL.
-bool wxRecordSet::BeginQuery(int WXUNUSED(openType), char *WXUNUSED(sql), int WXUNUSED(options))
-{
- // Needs to construct an appropriate SQL statement. By default
- // (i.e. if table and columns are provided) then
- // SELECT <columns> FROM <table>
- // will be used.
- if (!parentdb)
- return FALSE;
- if (!parentdb->GetHDBC())
- return FALSE;
-
- if (hStmt)
- {
- retcode = SQLFreeStmt(hStmt, SQL_DROP);
- if (retcode == SQL_ERROR)
- {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
- hStmt = 0;
- }
-
- retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
- if (retcode != SQL_SUCCESS)
- return FALSE;
-
- return TRUE;
-}
-
-bool wxRecordSet::Query(char *columns, char *table, char *filter)
-{
- // Needs to construct an appropriate SQL statement. By default
- // (i.e. if table and columns are provided) then
- // SELECT <columns> FROM <table>
- // will be used.
-
- char* thetable = table ? table : tablename;
-
- if (!thetable)
- return FALSE;
- if (!columns)
- return FALSE;
-
- wxString query;
-
- query += "SELECT ";
- query += columns;
- query += " FROM ";
- query += thetable;
-
- if (filter) {
- query += " WHERE ";
- query += filter;
- }
- retcode = SQLPrepare(hStmt, (UCHAR FAR *)query.GetData(), strlen(query.GetData()));
- if (retcode != SQL_SUCCESS) {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
-
- retcode = SQLExecute(hStmt);
-
- if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
-
- return TRUE;
-}
-
-bool wxRecordSet::EndQuery(void)
-{
- return TRUE;
-}
-
-void wxRecordSet::FillVars(int recnum) {
- wxNode* node = cols.First();
-
- do {
- ((wxQueryCol*)node->Data())->FillVar(recnum);
- } while ((node = node->Next()));
-}
-
-bool wxRecordSet::GetResultSet(void)
-{
-// long trash = SQL_NULL_DATA; // value added by JACS
- long trash;
- // contains the number of bytes transferred by SQLFetch()
- // who needs this ?
- wxNode *currow, *fetch, *curcol;
-
- retcode = SQLNumResultCols(hStmt, &nCols);
-
- if (!nCols)
- return TRUE;
-
- // delete old data first
- cols.DeleteContents(TRUE);
- cols.Clear();
- fetchbuf.DeleteContents(TRUE);
- fetchbuf.Clear();
-
- nRecords = 0;
- cursor = 0;
-
- int i;
- for (i=0; i<nCols; i++) {
- char name[512];
- short type, scale, nullable, namelen;
- unsigned long len;
-
- retcode = SQLDescribeCol(hStmt, i+1, (unsigned char *)name, 511, &namelen, &type, &len, &scale, &nullable);
- if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode) {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
-
- wxQueryCol *col1 = new wxQueryCol;
- curcol = cols.Append(name, col1);
- col1->SetName(name);
- col1->SetType(type);
- col1->SetNullable((nullable != 0));
-
- wxQueryField *field1 = new wxQueryField;
- fetch = fetchbuf.Append(field1);
- field1->SetType(type);
- field1->SetSize(len);
-
- SQLBindCol(hStmt, i+1, SQL_C_BINARY, (unsigned char*)field1->GetData(), field1->GetSize(), &trash);
- }
-
- switch (type) {
- case wxOPEN_TYPE_SNAPSHOT:
- // get it all !
- // After we've done an SQLFetch, copy the data in the fetch buffer into
- // new fields, for each column.
- while (SQL_SUCCESS == (retcode = SQLFetch(hStmt)) || SQL_SUCCESS_WITH_INFO == retcode) {
- nRecords++;
-
- curcol = cols.First();
- fetch = fetchbuf.First();
- for (i=0; i<nCols; i++) {
-
- wxQueryField *fetchField = (wxQueryField *)fetch->Data();
- wxQueryCol *col = (wxQueryCol *)curcol->Data();
- wxQueryField *field = new wxQueryField;
-
- currow = col->fields.Append(field);
-
- field->SetType(fetchField->GetType());
- field->SetData(fetchField->GetData(), fetchField->GetSize());
- curcol = curcol->Next();
- fetchField->ClearData(); // Runs ok if this commented out and SetData commented out
- fetch = fetch->Next();
- }
- }
- // while loop should only be left, when no more data was found;
- // otherwise it seems, that there was an error
- if (SQL_NO_DATA_FOUND != retcode) {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
- break;
- case wxOPEN_TYPE_DYNASET:
- // get first record only
- if (SQL_SUCCESS == (retcode = SQLFetch(hStmt)) || retcode == SQL_SUCCESS_WITH_INFO) {
- nRecords = 1; // TO DO! # of records in the ODBC result set should be set here.
-
- curcol = cols.First();
- fetch = fetchbuf.First();
- for (i=0; i<nCols; i++) {
- currow = ((wxQueryCol*)curcol->Data())->fields.Append(new wxQueryField);
-
- ((wxQueryField*)currow->Data())->SetType(((wxQueryField*)fetch->Data())->GetType());
- ((wxQueryField*)currow->Data())->SetData(((wxQueryField*)fetch->Data())->GetData(), ((wxQueryField*)fetch->Data())->GetSize());
- curcol = curcol->Next();
- ((wxQueryField*)fetch->Data())->ClearData();
- fetch = fetch->Next();
- }
- }
- if (SQL_NO_DATA_FOUND != retcode) {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
- break;
- default:
- return FALSE;
- }
-
- FillVars(0);
-
- return TRUE;
-}
-
-bool wxRecordSet::ExecuteSQL(char *sql)
-{
- if (hStmt)
- {
- retcode = SQLFreeStmt(hStmt, SQL_DROP);
- if (retcode == SQL_ERROR)
- {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
- hStmt = NULL;
- }
-
- retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
-
- if (SQL_SUCCESS != retcode) {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
-
- retcode = SQLExecDirect(hStmt, (UCHAR FAR*)sql, SQL_NTS);
-
- if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode) {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
-
- return GetResultSet();
-}
-
-bool wxRecordSet::GetDataSources(void) {
-
- char *dsname = "Name", *dsdesc = "Description";
- char namebuf[64];
- char descbuf[512];
- short namelen, desclen;
-
- cursor = 0;
-
- // delete old data first
- cols.DeleteContents(TRUE);
- cols.Clear();
- nRecords = 0;
-
- // JACS This is a snapshot, not a dynaset.
- type = wxOPEN_TYPE_SNAPSHOT;
-
- wxNode *namecol, *desccol;
-
- namecol = cols.Append(dsname, new wxQueryCol);
- ((wxQueryCol*)namecol->Data())->SetName(dsname);
- ((wxQueryCol*)namecol->Data())->SetType(SQL_CHAR);
- desccol = cols.Append(dsdesc, new wxQueryCol);
- ((wxQueryCol*)desccol->Data())->SetName(dsdesc);
- ((wxQueryCol*)desccol->Data())->SetType(SQL_CHAR);
-
- retcode = SQLDataSources(parentdb->GetHENV(), SQL_FETCH_FIRST, (unsigned char *)namebuf, 63, &namelen, (unsigned char *)descbuf, 511, &desclen);
- while (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode) {
- nRecords++;
- ((wxQueryCol*)namecol->Data())->AppendField(namebuf, namelen);
- ((wxQueryCol*)desccol->Data())->AppendField(descbuf, desclen);
- retcode = SQLDataSources(parentdb->GetHENV(), SQL_FETCH_NEXT, (unsigned char *)namebuf, 63, &namelen, (unsigned char *)descbuf, 511, &desclen);
- }
-
- if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode && SQL_NO_DATA_FOUND != retcode) {
- parentdb->ErrorSnapshot();
- return FALSE;
- }
-
- cursor = 0;
-
- return TRUE;
-}
-
-// Attributes
-void wxRecordSet::SetTableName(char* name) {
- delete[] tablename;
- tablename = NULL;
-
- if (name)
- tablename = copystring(name);
-}
-
-bool wxRecordSet::GetTables(void)
-{
- if (hStmt)
- {
- retcode = SQLFreeStmt(hStmt, SQL_DROP);
- if (retcode == SQL_ERROR)
- {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
-
- hStmt = NULL;
- }
-
- retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
-
- if (SQL_SUCCESS != retcode) {
- parentdb->ErrorSnapshot();
- return FALSE;
- }
-
- retcode = SQLTables(hStmt, NULL, 0, NULL, 0, NULL, 0, NULL, 0);
-
- if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode) {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
-
- return GetResultSet();
-}
-
-bool wxRecordSet::GetColumns(char* table)
-{
- char* name=NULL;
-// char* wildcard = "%";
-
- name = table ? table : tablename;
-
- if (!name)
- return FALSE;
-
- if (hStmt)
- {
- retcode = SQLFreeStmt(hStmt, SQL_DROP);
- if (retcode == SQL_ERROR)
- {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
- hStmt = NULL;
- }
-
- retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
-
- if (SQL_SUCCESS != retcode) {
- parentdb->ErrorSnapshot();
- return FALSE;
- }
-
- //retcode = SQLColumns(hstmt, (unsigned char*)parentdb->GetDataSource(), strlen(parentdb->GetDataSource()), wildcard, 1, name, strlen(name), wildcard, 1);
- retcode = SQLColumns(hStmt, NULL, 0, NULL, 0, (unsigned char *)name, strlen(name), NULL, 0);
-
- if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode) {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
-
- return GetResultSet();
-}
-
-// It is derived from previous GetColumns
-bool wxRecordSet::GetPrimaryKeys(char* table)
-{
- char* name=NULL;
-// char* wildcard = "%";
-
- name = table ? table : tablename;
-
- if (!name)
- return FALSE;
-
- if (hStmt)
- {
- retcode = SQLFreeStmt(hStmt, SQL_DROP);
- if (retcode == SQL_ERROR)
- {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
- hStmt = NULL;
- }
-
- retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
-
- if (SQL_SUCCESS != retcode) {
- parentdb->ErrorSnapshot();
- return FALSE;
- }
-
- retcode = SQLPrimaryKeys(hStmt, NULL, 0, NULL, 0, (unsigned char *)name, SQL_NTS);
-
- if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode) {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
-
- return GetResultSet();
-}
-
-bool wxRecordSet::GetForeignKeys(char* PkTableName, char * FkTableName)
-{
- char* Pkname=NULL;
- char* Fkname=NULL;
-// char* wildcard = "%";
-
-// Try to disable situation: both PkTableName and FkTableName are NULL
-// set Pkname from tablename
- if( !PkTableName && !FkTableName ) {
- Pkname = PkTableName ? PkTableName : tablename;
- Fkname = FkTableName ;
- if (!Pkname )
- return FALSE;
- } else {
- Pkname = PkTableName ;
- Fkname = FkTableName ;
- }
-
- if (hStmt)
- {
- retcode = SQLFreeStmt(hStmt, SQL_DROP);
- if (retcode == SQL_ERROR)
- {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
- hStmt = NULL;
- }
-
- retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
-
- if (SQL_SUCCESS != retcode) {
- parentdb->ErrorSnapshot();
- return FALSE;
- }
-
- retcode = SQLForeignKeys(hStmt, NULL, 0, NULL, 0, (unsigned char *)Pkname,
- (Pkname ? SQL_NTS : 0), NULL, 0, NULL, 0, (unsigned char *)Fkname ,(Fkname ?SQL_NTS : 0) );
-
- if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode) {
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
-
- return GetResultSet();
-}
-
-long wxRecordSet::GetNumberRecords(void)
-{
- return nRecords;
-}
-
-long wxRecordSet::GetNumberCols(void)
-{
- return nCols;
-}
-
-char* wxRecordSet::GetColName(int col)
-{
- wxNode* node = cols.Nth(col);
-
- if (!node)
- return NULL;
-
- return ((wxQueryCol*)node->Data())->GetName();
-}
-
-short wxRecordSet::GetColType(int col)
-{
- wxNode* node = cols.Nth(col);
-
- if (!node)
- return SQL_TYPE_NULL;
-
- return ((wxQueryCol*)node->Data())->GetType();
-}
-
-short wxRecordSet::GetColType(const char *col)
-{
- wxNode* node = cols.Find(col);
-
- if (!node)
- return SQL_TYPE_NULL;
-
- return ((wxQueryCol*)node->Data())->GetType();
-}
-
-bool wxRecordSet::GetFieldData(int col, int type, void* data)
-{
- wxNode* node = cols.Nth(col);
-
- if (!node)
- return FALSE;
-
- if (((wxQueryCol*)node->Data())->GetType() != type)
- return FALSE;
-
- void* src = ((wxQueryCol*)node->Data())->GetData(cursor);
-
- if (!src)
- return FALSE;
-
- memcpy(data, src, ((wxQueryCol*)node->Data())->GetSize(cursor));
-
- return TRUE;
-}
-
-bool wxRecordSet::GetFieldData(const char* name, int type, void *data)
-{
- wxNode* node = cols.Find(name);
-
- if (!node)
- return FALSE;
-
- if (((wxQueryCol*)node->Data())->GetType() != type)
- return FALSE;
-
- void* src = ((wxQueryCol*)node->Data())->GetData(cursor);
-
- if (!src)
- return FALSE;
-
- memcpy(data, src, ((wxQueryCol*)node->Data())->GetSize(cursor));
-
- return TRUE;
-}
-
-void* wxRecordSet::GetFieldDataPtr(int col, int type)
-{
- wxNode* node = cols.Nth(col);
-
- if (!node)
- return NULL;
-
- if (((wxQueryCol*)node->Data())->GetType() != type)
- return NULL;
-
- return ((wxQueryCol*)node->Data())->GetData(cursor);
-}
-
-void* wxRecordSet::GetFieldDataPtr(const char* name, int type)
-{
- wxNode* node = cols.Find(name);
-
- if (!node)
- return NULL;
-
- if (((wxQueryCol*)node->Data())->GetType() != type)
- return NULL;
-
- return ((wxQueryCol*)node->Data())->GetData(cursor);
-}
-
-void* wxRecordSet::BindVar(int col, void* var, long size) {
- wxNode* node = cols.Nth(col);
-
- if (!node)
- return NULL;
-
- return ((wxQueryCol*)node->Data())->BindVar(var, size);
-}
-
-void* wxRecordSet::BindVar(const char* name, void* var, long size) {
- wxNode* node = cols.Find(name);
-
- if (!node)
- return NULL;
-
- return ((wxQueryCol*)node->Data())->BindVar(var, size);
-}
-
-void wxRecordSet::SetType(int typ) {
- type = typ;
-}
-
-int wxRecordSet::GetType(void) {
- return type;
-}
-
-void wxRecordSet::SetOptions(int opts) {
- options = opts;
-}
-
-int wxRecordSet::GetOptions(void) {
- return options;
-}
-
-bool wxRecordSet::CanAppend(void)
-{
- return FALSE;
-}
-
-bool wxRecordSet::CanRestart(void)
-{
- return FALSE;
-}
-
-bool wxRecordSet::CanScroll(void)
-{
- return FALSE;
-}
-
-bool wxRecordSet::CanTransact(void)
-{
- return FALSE;
-}
-
-bool wxRecordSet::CanUpdate(void)
-{
- return FALSE;
-}
-
-long wxRecordSet::GetCurrentRecord(void)
-{
- return -1L;
-}
-
-bool wxRecordSet::RecordCountFinal(void)
-{
- return FALSE;
-}
-
-char* wxRecordSet::GetTableName(void)
-{
- return tablename;
-}
-
-char *wxRecordSet::GetSQL(void)
-{
- return NULL;
-}
-
-bool wxRecordSet::IsOpen(void)
-{
- return parentdb->IsOpen();
-}
-
-bool wxRecordSet::IsBOF(void)
-{
- return cursor < 0;
-}
-
-bool wxRecordSet::IsEOF(void)
-{
- return cursor >= nRecords;
-}
-
-bool wxRecordSet::IsDeleted(void)
-{
- return FALSE;
-}
-
-// Update operations
-void wxRecordSet::AddNew(void)
-{
-}
-
-bool wxRecordSet::Delete(void)
-{
- return FALSE;
-}
-
-void wxRecordSet::Edit(void)
-{
-}
-
-bool wxRecordSet::Update(void)
-{
- return FALSE;
-}
-
-// Record navigation
-bool wxRecordSet::Move(long rows)
-{
- if (!nRecords) {
- cursor = -1;
- return FALSE;
- }
-
- switch (type) {
- case wxOPEN_TYPE_SNAPSHOT:
- cursor += (int)rows;
- if (cursor < 0) {
- cursor = -1;
- return FALSE;
- }
- if (cursor > nRecords-1) {
- cursor = nRecords;
- return FALSE;
- }
- return TRUE;
-
- case wxOPEN_TYPE_DYNASET:
- return FALSE;
- default:
- return FALSE;
- }
-}
-
-bool wxRecordSet::GoTo(long row)
-{
- if (!nRecords) {
- cursor = -1;
- return FALSE;
- }
-
- switch (type) {
- case wxOPEN_TYPE_SNAPSHOT:
- cursor = (int)row;
- if (cursor < 0) {
- cursor = -1;
- return FALSE;
- }
- if (cursor > nRecords-1) {
- cursor = nRecords;
- return FALSE;
- }
- return TRUE;
-
- case wxOPEN_TYPE_DYNASET:
- return FALSE;
- default:
- return FALSE;
- }
-}
-
-bool wxRecordSet::MoveFirst(void)
-{
- if (!nRecords) {
- cursor = -1;
- return FALSE;
- }
-
- switch (type) {
- case wxOPEN_TYPE_SNAPSHOT:
- cursor = 0;
- return TRUE;
-
- case wxOPEN_TYPE_DYNASET:
- return FALSE;
- default:
- return FALSE;
- }
-}
-
-bool wxRecordSet::MoveLast(void)
-{
- if (!nRecords) {
- cursor = -1;
- return FALSE;
- }
-
- switch (type) {
- case wxOPEN_TYPE_SNAPSHOT:
- cursor = nRecords-1;
- return TRUE;
-
- case wxOPEN_TYPE_DYNASET:
- return FALSE;
- default:
- return FALSE;
- }
-}
-
-bool wxRecordSet::MoveNext(void)
-{
- if (!nRecords) {
- cursor = -1;
- return FALSE;
- }
-
- switch (type) {
- case wxOPEN_TYPE_SNAPSHOT:
- cursor++;
- if (cursor >= nRecords) {
- cursor = nRecords;
- return FALSE;
- }
- return TRUE;
-
- case wxOPEN_TYPE_DYNASET:
- return FALSE;
- default:
- return FALSE;
- }
-}
-
-bool wxRecordSet::MovePrev(void)
-{
- if (!nRecords) {
- cursor = -1;
- return FALSE;
- }
-
- switch (type) {
- case wxOPEN_TYPE_SNAPSHOT:
- cursor--;
- if (cursor < 0) {
- cursor = 0;
- return FALSE;
- }
- return TRUE;
-
- case wxOPEN_TYPE_DYNASET:
- return FALSE;
- default:
- return FALSE;
- }
-}
-
-// Others
-void wxRecordSet::Cancel(void)
-{
-}
-
-bool wxRecordSet::IsFieldDirty(int col)
-{
- wxNode* node = cols.Nth(col);
-
- if (!node)
- return FALSE;
-
- return ((wxQueryCol*)node->Data())->IsFieldDirty(cursor);
-}
-
-bool wxRecordSet::IsFieldDirty(const char* name)
-{
- wxNode* node = cols.Find(name);
-
- if (!node)
- return FALSE;
-
- return ((wxQueryCol*)node->Data())->IsFieldDirty(cursor);
-}
-
-bool wxRecordSet::IsFieldNull(int col)
-{
- wxNode* node = cols.Nth(col);
-
- if (!node)
- return TRUE;
-
- return NULL != ((wxQueryCol*)node->Data())->GetData(cursor);
-}
-
-bool wxRecordSet::IsFieldNull(const char* name)
-{
- wxNode* node = cols.Find(name);
-
- if (!node)
- return TRUE;
-
- return NULL != ((wxQueryCol*)node->Data())->GetData(cursor);
-}
-
-bool wxRecordSet::IsColNullable(int col)
-{
- wxNode* node = cols.Nth(col);
-
- if (!node)
- return FALSE;
-
- return ((wxQueryCol*)node->Data())->IsNullable();
-}
-
-bool wxRecordSet::IsColNullable(const char* name)
-{
- wxNode* node = cols.Find(name);
-
- if (!node)
- return FALSE;
-
- return ((wxQueryCol*)node->Data())->IsNullable();
-}
-
-bool wxRecordSet::Requery(void)
-{
- return FALSE;
-}
-
-void wxRecordSet::SetFieldDirty(int col, bool dirty)
-{
- wxNode* node = cols.Nth(col);
-
- if (!node)
- return;
-
- ((wxQueryCol*)node->Data())->SetFieldDirty(cursor, dirty);
-}
-
-void wxRecordSet::SetFieldDirty(const char* name, bool dirty)
-{
- wxNode* node = cols.Find(name);
-
- if (!node)
- return;
-
- ((wxQueryCol*)node->Data())->SetFieldDirty(cursor, dirty);
-}
-
-void wxRecordSet::SetFieldNull(void *WXUNUSED(p), bool WXUNUSED(isNull))
-{
-}
-
-// Overridables
-char *wxRecordSet::GetDefaultConnect(void)
-{
- return NULL;
-}
-
-char *wxRecordSet::GetDefaultSQL(void)
-{
- return NULL;
-}
-
-void wxRecordSet::SetDefaultSQL(char *s)
-{
- delete[] defaultSQL;
-
- if (s)
- defaultSQL = copystring(s);
- else
- defaultSQL = NULL;
-}
-
-// Build SQL query from column specification
-bool wxRecordSet::ConstructDefaultSQL(void)
-{
-// if (queryCols.Number() == 0)
- return FALSE;
-}
-
-bool wxRecordSet::ReleaseHandle(void)
-{
- if (hStmt)
- {
- retcode = SQLFreeStmt(hStmt, SQL_DROP);
- if (retcode == SQL_ERROR)
- {
- if (parentdb)
- parentdb->ErrorSnapshot(hStmt);
- return FALSE;
- }
- hStmt = 0;
- }
- return TRUE;
-}
-
-wxQueryCol::wxQueryCol(void) {
-// __type = wxTYPE_QUERYCOL;
- name = NULL;
- type = SQL_TYPE_NULL;
- nullable = FALSE;
- var = NULL;
- varsize = 0;
-}
-
-wxQueryCol::~wxQueryCol(void) {
- // delete all data
- fields.DeleteContents(TRUE);
- fields.Clear();
-
- if (name)
- delete[] name;
-}
-
-void wxQueryCol::SetName(char* n) {
- name = new char[strlen(n)+1];
- strcpy(name, n);
-}
-
-bool wxQueryCol::SetData(int row, void* buf, long len) {
- wxNode* node = fields.Nth(row);
-
- if (!node)
- return FALSE;
-
- return ((wxQueryField*)node->Data())->SetData(buf, len);
-}
-
-void wxQueryCol::SetFieldDirty(int row, bool dirty) {
- wxNode* node = fields.Nth(row);
-
- if (!node)
- return;
-
- ((wxQueryField*)node->Data())->SetDirty(dirty);
-}
-
-void wxQueryCol::AppendField(void* buf, long len) {
- wxNode* node = fields.Append(new wxQueryField);
- ((wxQueryField*)node->Data())->SetType(type);
- ((wxQueryField*)node->Data())->SetData(buf, len);
-}
-
-void wxQueryCol::SetType(short t) {
- type = t;
-}
-
-void* wxQueryCol::BindVar(void* v, long s) {
- void* oldvar = var;
-
- var = v;
- varsize = s;
-
- return oldvar;
-}
-
-void wxQueryCol::FillVar(int recnum) {
- if (!var)
- return;
-
- wxNode* node = fields.Nth(recnum);
-
- if (!node)
- return;
-
- long actsize = ((wxQueryField*)node->Data())->GetSize();
- if (actsize > varsize)
- actsize = varsize;
-
- memcpy(var, ((wxQueryField*)node->Data())->GetData(), actsize);
-}
-
-void wxQueryCol::SetNullable(bool n) {
- nullable = n;
-}
-
-char* wxQueryCol::GetName(void) {
- return name;
-}
-
-short wxQueryCol::GetType(void) {
- return type;
-}
-
-bool wxQueryCol::IsNullable(void) {
- return nullable;
-}
-
-
-bool wxQueryCol::IsFieldDirty(int row) {
- wxNode* node = fields.Nth(row);
-
- if (!node)
- return FALSE;
-
- return ((wxQueryField*)node->Data())->IsDirty();
-}
-
-void* wxQueryCol::GetData(int row) {
- wxNode* node = fields.Nth(row);
-
- if (!node)
- return NULL;
-
- return ((wxQueryField*)node->Data())->GetData();
-}
-
-long wxQueryCol::GetSize(int row) {
- wxNode* node = fields.Nth(row);
-
- if (!node)
- return 0;
-
- return ((wxQueryField*)node->Data())->GetSize();
-}
-
-wxQueryField::wxQueryField(void) {
-// __type = wxTYPE_QUERYROW;
- data = NULL;
- type = SQL_TYPE_NULL;
- size = 0;
- dirty = FALSE;
-}
-
-wxQueryField::~wxQueryField(void) {
- switch (type)
- {
- case SQL_NUMERIC:
- case SQL_DECIMAL:
- case SQL_CHAR:
- case SQL_VARCHAR:
- if (data) // JACS
- delete[] (char*)data;
- break;
- case SQL_INTEGER:
- if (data) // JACS
- delete (long*)data;
- break;
- case SQL_SMALLINT:
- if (data)
- delete (short*)data;
- break;
- case SQL_FLOAT:
- case SQL_DOUBLE:
- if (data)
- delete (double*)data;
- break;
- case SQL_REAL:
- if (data)
- delete (float*)data;
- break;
- case SQL_TIME:
- if (data)
- delete (TIME_STRUCT *)data;
- break;
- case SQL_DATE:
- if (data)
- delete (DATE_STRUCT *)data;
- break;
- case SQL_TIMESTAMP:
- if (data)
- delete (TIMESTAMP_STRUCT *)data;
- break;
- }
-}
-
-bool wxQueryField::AllocData(void) {
- switch (type)
- {
- case SQL_NUMERIC:
- case SQL_DECIMAL:
- case SQL_CHAR:
- case SQL_VARCHAR:
- {
- if (data) // JACS
- delete[] (char*)data;
- if ((data = new char[size+1]))
- {
- char *str = (char *)data;
- int i;
- for (i = 0; i < size; i++)
- str[i] = 0;
-// memset(data, 0, size+1);
- }
- break;
- }
- case SQL_INTEGER:
- {
- if (data) // JACS
- delete (long*)data;
- if ((data = new long))
- *(long*)data = 0L;
- break;
- }
- case SQL_SMALLINT:
- {
- if (data)
- delete (short*)data;
- if ((data = new short))
- *(short*)data = 0;
- break;
- }
- case SQL_FLOAT:
- case SQL_DOUBLE:
- {
- if (data)
- delete (double*)data;
- if ((data = new double))
- *(double*)data = 0;
- break;
- }
- case SQL_REAL:
- {
- if (data)
- delete (float*)data;
- if ((data = new float))
- *(float*)data = (float)0;
- break;
- }
- case SQL_TIME:
- {
- if (data)
- delete (TIME_STRUCT *)data;
- data = new TIME_STRUCT;
- memset(data, 0, sizeof(TIME_STRUCT));
- break;
- }
- case SQL_DATE:
- {
- if (data)
- delete (DATE_STRUCT *)data;
- data = new DATE_STRUCT;
- memset(data, 0, sizeof(DATE_STRUCT));
- break;
- }
- case SQL_TIMESTAMP:
- {
- if (data)
- delete (TIMESTAMP_STRUCT *)data;
- data = new TIMESTAMP_STRUCT;
- memset(data, 0, sizeof(TIMESTAMP_STRUCT));
- break;
- }
- default:
- return FALSE;
- }
-
- return TRUE;
-}
-
-bool wxQueryField::SetData(void* d, long s) {
- size = s;
- if (AllocData() && d)
- {
-// memcpy(data, d, s);
- switch (type)
- {
- case SQL_NUMERIC:
- case SQL_DECIMAL:
- case SQL_CHAR:
- case SQL_VARCHAR:
- {
- char *str = (char *)data;
- int i;
- for (i = 0; i < size; i++)
- str[i] = 0;
-
- strncpy(str, (char *)d, (int)size);
- str[size] = 0;
- break;
- }
- case SQL_INTEGER:
- {
- *(long*)data = *((long *)d);
- break;
- }
- case SQL_SMALLINT:
- {
- *(short*)data = *((short*)d);
- break;
- }
- case SQL_FLOAT:
- case SQL_DOUBLE:
- {
- *(double*)data = *((double*)d);
- break;
- }
- case SQL_REAL:
- {
- *(float*)data = *((float*)d);
- break;
- }
- case SQL_TIME:
- {
- *(TIME_STRUCT *)data = *((TIME_STRUCT*)d);
- break;
- }
- case SQL_TIMESTAMP:
- {
- *(TIMESTAMP_STRUCT *)data = *((TIMESTAMP_STRUCT*)d);
- break;
- }
- case SQL_DATE:
- {
- *(DATE_STRUCT *)data = *((DATE_STRUCT*)d);
- break;
- }
- default:
- return FALSE;
- }
- return TRUE;
- }
- return FALSE;
-}
-
-void wxQueryField::ClearData(void) {
- if (data)
- {
- // memset(data, 0, size);
- switch (type)
- {
- case SQL_NUMERIC:
- case SQL_DECIMAL:
- case SQL_CHAR:
- case SQL_VARCHAR:
- {
- char *str = (char *)data;
- int i;
- for (i = 0; i < size; i++)
- str[i] = 0;
- break;
- }
- case SQL_INTEGER:
- {
- *(long*)data = 0L;
- break;
- }
- case SQL_SMALLINT:
- {
- *(short*)data = 0;
- break;
- }
- case SQL_FLOAT:
- case SQL_DOUBLE:
- {
- *(double*)data = (double)0.0;
- break;
- }
- case SQL_REAL:
- {
- *(float*)data = (float)0.0;
- break;
- }
- case SQL_TIME:
- {
- memset(data, 0, sizeof(TIME_STRUCT));
- break;
- }
- case SQL_DATE:
- {
- memset(data, 0, sizeof(DATE_STRUCT));
- break;
- }
- case SQL_TIMESTAMP:
- {
- memset(data, 0, sizeof(TIMESTAMP_STRUCT));
- break;
- }
- default:
- return;
- }
- }
-}
-
-void wxQueryField::SetDirty(bool d) {
- dirty = d;
-}
-
-void wxQueryField::SetType(short t) {
- type = t;
-}
-
-void wxQueryField::SetSize(long s) {
- size = s;
- AllocData();
-}
-
-void* wxQueryField::GetData(void) {
- return data;
-}
-
-short wxQueryField::GetType(void) {
- return type;
-}
-
-long wxQueryField::GetSize(void) {
- return size;
-}
-
-bool wxQueryField::IsDirty(void) {
- return dirty;
-}
-
-#ifdef __VISUALC__
- #pragma warning(default:4706) // assignment within conditional expression
-#endif // VC++
-
-#endif // wxUSE_OLD_ODBC