Added ODBC database classes and sample from RemStar (sample needs work for wxWin 2)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@385 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
1998-07-28 09:43:44 +00:00
parent b3324be240
commit 108106cfe7
16 changed files with 6352 additions and 10 deletions

362
include/wx/db.h Normal file
View File

@@ -0,0 +1,362 @@
///////////////////////////////////////////////////////////////////////////////
// Name: db.h
// Purpose: Header file wxDB class. The wxDB class represents a connection
// to an ODBC data source. The wxDB class allows operations on the data
// source such as opening and closing the data source.
// Author: Doug Card
// Modified by:
// Created: 9.96
// RCS-ID: $Id$
// Copyright: (c) 1996 Remstar International, Inc.
// Licence: wxWindows licence, plus:
// Notice: This class library and its intellectual design are free of charge for use,
// modification, enhancement, debugging under the following conditions:
// 1) These classes may only be used as part of the implementation of a
// wxWindows-based application
// 2) All enhancements and bug fixes are to be submitted back to the wxWindows
// user groups free of all charges for use with the wxWindows library.
// 3) These classes may not be distributed as part of any other class library,
// DLL, text (written or electronic), other than a complete distribution of
// the wxWindows GUI development toolkit.
///////////////////////////////////////////////////////////////////////////////
/*
// SYNOPSIS START
// SYNOPSIS STOP
*/
#ifndef DB_DOT_H
#define DB_DOT_H
#ifdef __GNUG__
#pragma interface "db.h"
#endif
#if defined(wx_msw) || defined(WIN32)
#include <windows.h>
#endif
#define ODBCVER 0x0250
#include <sql.h>
#include <sqlext.h>
enum enumDummy {enumDum1};
#define SQL_C_BOOLEAN (sizeof(int) == 2 ? SQL_C_USHORT : SQL_C_ULONG)
#define SQL_C_ENUM (sizeof(enumDummy) == 2 ? SQL_C_USHORT : SQL_C_ULONG) //glt 2-21-97
/*
#ifndef Bool
#define Bool int
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
*/
// Database Globals
const DB_TYPE_NAME_LEN = 40;
const DB_MAX_STATEMENT_LEN = 2048;
const DB_MAX_WHERE_CLAUSE_LEN = 1024;
const DB_MAX_ERROR_MSG_LEN = 512;
const DB_MAX_ERROR_HISTORY = 5;
const DB_MAX_TABLE_NAME_LEN = 128;
const DB_MAX_COLUMN_NAME_LEN = 128;
const DB_DATA_TYPE_VARCHAR = 1;
const DB_DATA_TYPE_INTEGER = 2;
const DB_DATA_TYPE_FLOAT = 3;
const DB_DATA_TYPE_DATE = 4;
const DB_SELECT_KEYFIELDS = 1;
const DB_SELECT_WHERE = 2;
const DB_SELECT_MATCHING = 3;
const DB_SELECT_STATEMENT = 4;
const DB_UPD_KEYFIELDS = 1;
const DB_UPD_WHERE = 2;
const DB_DEL_KEYFIELDS = 1;
const DB_DEL_WHERE = 2;
const DB_DEL_MATCHING = 3;
const DB_WHERE_KEYFIELDS = 1;
const DB_WHERE_MATCHING = 2;
const DB_CURSOR0 = 0;
const DB_CURSOR1 = 1;
const DB_CURSOR2 = 2;
//const DB_CURSOR3 = 3;
//const DB_CURSOR4 = 4;
//const DB_CURSOR5 = 5;
const DB_GRANT_SELECT = 1;
const DB_GRANT_INSERT = 2;
const DB_GRANT_UPDATE = 4;
const DB_GRANT_DELETE = 8;
const DB_GRANT_ALL = DB_GRANT_SELECT | DB_GRANT_INSERT | DB_GRANT_UPDATE | DB_GRANT_DELETE;
// ODBC Error codes (derived from ODBC SqlState codes)
enum ODBC_ERRORS
{
DB_FAILURE = 0,
DB_SUCCESS = 1,
DB_ERR_NOT_IN_USE,
DB_ERR_GENERAL_WARNING, // SqlState = '01000'
DB_ERR_DISCONNECT_ERROR, // SqlState = '01002'
DB_ERR_DATA_TRUNCATED, // SqlState = '01004'
DB_ERR_PRIV_NOT_REVOKED, // SqlState = '01006'
DB_ERR_INVALID_CONN_STR_ATTR, // SqlState = '01S00'
DB_ERR_ERROR_IN_ROW, // SqlState = '01S01'
DB_ERR_OPTION_VALUE_CHANGED, // SqlState = '01S02'
DB_ERR_NO_ROWS_UPD_OR_DEL, // SqlState = '01S03'
DB_ERR_MULTI_ROWS_UPD_OR_DEL, // SqlState = '01S04'
DB_ERR_WRONG_NO_OF_PARAMS, // SqlState = '07001'
DB_ERR_DATA_TYPE_ATTR_VIOL, // SqlState = '07006'
DB_ERR_UNABLE_TO_CONNECT, // SqlState = '08001'
DB_ERR_CONNECTION_IN_USE, // SqlState = '08002'
DB_ERR_CONNECTION_NOT_OPEN, // SqlState = '08003'
DB_ERR_REJECTED_CONNECTION, // SqlState = '08004'
DB_ERR_CONN_FAIL_IN_TRANS, // SqlState = '08007'
DB_ERR_COMM_LINK_FAILURE, // SqlState = '08S01'
DB_ERR_INSERT_VALUE_LIST_MISMATCH, // SqlState = '21S01'
DB_ERR_DERIVED_TABLE_MISMATCH, // SqlState = '21S02'
DB_ERR_STRING_RIGHT_TRUNC, // SqlState = '22001'
DB_ERR_NUMERIC_VALUE_OUT_OF_RNG, // SqlState = '22003'
DB_ERR_ERROR_IN_ASSIGNMENT, // SqlState = '22005'
DB_ERR_DATETIME_FLD_OVERFLOW, // SqlState = '22008'
DB_ERR_DIVIDE_BY_ZERO, // SqlState = '22012'
DB_ERR_STR_DATA_LENGTH_MISMATCH, // SqlState = '22026'
DB_ERR_INTEGRITY_CONSTRAINT_VIOL, // SqlState = '23000'
DB_ERR_INVALID_CURSOR_STATE, // SqlState = '24000'
DB_ERR_INVALID_TRANS_STATE, // SqlState = '25000'
DB_ERR_INVALID_AUTH_SPEC, // SqlState = '28000'
DB_ERR_INVALID_CURSOR_NAME, // SqlState = '34000'
DB_ERR_SYNTAX_ERROR_OR_ACCESS_VIOL, // SqlState = '37000'
DB_ERR_DUPLICATE_CURSOR_NAME, // SqlState = '3C000'
DB_ERR_SERIALIZATION_FAILURE, // SqlState = '40001'
DB_ERR_SYNTAX_ERROR_OR_ACCESS_VIOL2, // SqlState = '42000'
DB_ERR_OPERATION_ABORTED, // SqlState = '70100'
DB_ERR_UNSUPPORTED_FUNCTION, // SqlState = 'IM001'
DB_ERR_NO_DATA_SOURCE, // SqlState = 'IM002'
DB_ERR_DRIVER_LOAD_ERROR, // SqlState = 'IM003'
DB_ERR_SQLALLOCENV_FAILED, // SqlState = 'IM004'
DB_ERR_SQLALLOCCONNECT_FAILED, // SqlState = 'IM005'
DB_ERR_SQLSETCONNECTOPTION_FAILED, // SqlState = 'IM006'
DB_ERR_NO_DATA_SOURCE_DLG_PROHIB, // SqlState = 'IM007'
DB_ERR_DIALOG_FAILED, // SqlState = 'IM008'
DB_ERR_UNABLE_TO_LOAD_TRANSLATION_DLL, // SqlState = 'IM009'
DB_ERR_DATA_SOURCE_NAME_TOO_LONG, // SqlState = 'IM010'
DB_ERR_DRIVER_NAME_TOO_LONG, // SqlState = 'IM011'
DB_ERR_DRIVER_KEYWORD_SYNTAX_ERROR, // SqlState = 'IM012'
DB_ERR_TRACE_FILE_ERROR, // SqlState = 'IM013'
DB_ERR_TABLE_OR_VIEW_ALREADY_EXISTS, // SqlState = 'S0001'
DB_ERR_TABLE_NOT_FOUND, // SqlState = 'S0002'
DB_ERR_INDEX_ALREADY_EXISTS, // SqlState = 'S0011'
DB_ERR_INDEX_NOT_FOUND, // SqlState = 'S0012'
DB_ERR_COLUMN_ALREADY_EXISTS, // SqlState = 'S0021'
DB_ERR_COLUMN_NOT_FOUND, // SqlState = 'S0022'
DB_ERR_NO_DEFAULT_FOR_COLUMN, // SqlState = 'S0023'
DB_ERR_GENERAL_ERROR, // SqlState = 'S1000'
DB_ERR_MEMORY_ALLOCATION_FAILURE, // SqlState = 'S1001'
DB_ERR_INVALID_COLUMN_NUMBER, // SqlState = 'S1002'
DB_ERR_PROGRAM_TYPE_OUT_OF_RANGE, // SqlState = 'S1003'
DB_ERR_SQL_DATA_TYPE_OUT_OF_RANGE, // SqlState = 'S1004'
DB_ERR_OPERATION_CANCELLED, // SqlState = 'S1008'
DB_ERR_INVALID_ARGUMENT_VALUE, // SqlState = 'S1009'
DB_ERR_FUNCTION_SEQUENCE_ERROR, // SqlState = 'S1010'
DB_ERR_OPERATION_INVALID_AT_THIS_TIME, // SqlState = 'S1011'
DB_ERR_INVALID_TRANS_OPERATION_CODE, // SqlState = 'S1012'
DB_ERR_NO_CURSOR_NAME_AVAIL, // SqlState = 'S1015'
DB_ERR_INVALID_STR_OR_BUF_LEN, // SqlState = 'S1090'
DB_ERR_DESCRIPTOR_TYPE_OUT_OF_RANGE, // SqlState = 'S1091'
DB_ERR_OPTION_TYPE_OUT_OF_RANGE, // SqlState = 'S1092'
DB_ERR_INVALID_PARAM_NO, // SqlState = 'S1093'
DB_ERR_INVALID_SCALE_VALUE, // SqlState = 'S1094'
DB_ERR_FUNCTION_TYPE_OUT_OF_RANGE, // SqlState = 'S1095'
DB_ERR_INF_TYPE_OUT_OF_RANGE, // SqlState = 'S1096'
DB_ERR_COLUMN_TYPE_OUT_OF_RANGE, // SqlState = 'S1097'
DB_ERR_SCOPE_TYPE_OUT_OF_RANGE, // SqlState = 'S1098'
DB_ERR_NULLABLE_TYPE_OUT_OF_RANGE, // SqlState = 'S1099'
DB_ERR_UNIQUENESS_OPTION_TYPE_OUT_OF_RANGE, // SqlState = 'S1100'
DB_ERR_ACCURACY_OPTION_TYPE_OUT_OF_RANGE, // SqlState = 'S1101'
DB_ERR_DIRECTION_OPTION_OUT_OF_RANGE, // SqlState = 'S1103'
DB_ERR_INVALID_PRECISION_VALUE, // SqlState = 'S1104'
DB_ERR_INVALID_PARAM_TYPE, // SqlState = 'S1105'
DB_ERR_FETCH_TYPE_OUT_OF_RANGE, // SqlState = 'S1106'
DB_ERR_ROW_VALUE_OUT_OF_RANGE, // SqlState = 'S1107'
DB_ERR_CONCURRENCY_OPTION_OUT_OF_RANGE, // SqlState = 'S1108'
DB_ERR_INVALID_CURSOR_POSITION, // SqlState = 'S1109'
DB_ERR_INVALID_DRIVER_COMPLETION, // SqlState = 'S1110'
DB_ERR_INVALID_BOOKMARK_VALUE, // SqlState = 'S1111'
DB_ERR_DRIVER_NOT_CAPABLE, // SqlState = 'S1C00'
DB_ERR_TIMEOUT_EXPIRED // SqlState = 'S1T00'
};
struct DbStuff
{
HENV Henv;
char Dsn[SQL_MAX_DSN_LENGTH+1]; // Data Source Name
char Uid[20]; // User ID
char AuthStr[20]; // Authorization string (password)
};
typedef struct
{
char TypeName[DB_TYPE_NAME_LEN];
int FsqlType;
long Precision;
short CaseSensitive;
// short MinimumScale;
short MaximumScale;
} SqlTypeInfo;
class CcolInf
{
public:
char tableName[DB_MAX_TABLE_NAME_LEN+1];
char colName[DB_MAX_COLUMN_NAME_LEN+1];
int sqlDataType;
};
class wxDB
{
private:
// Private data
bool dbIsOpen;
char *dsn; // Data source name
char *uid; // User ID
char *authStr; // Authorization string (password)
// Private member functions
bool getDbInfo(void);
bool getDataTypeInfo(SWORD fSqlType, SqlTypeInfo &structSQLTypeInfo);
bool setConnectionOptions(void);
void logError(char *errMsg, char *SQLState);
public:
// The following structure contains database information gathered from the
// datasource when the datasource is first opened.
struct
{
char dbmsName[40]; // Name of the dbms product
char dbmsVer[20]; // Version # of the dbms product
char driverName[40]; // Driver name
char odbcVer[20]; // ODBC version of the driver
char drvMgrOdbcVer[20]; // ODBC version of the driver manager
char driverVer[40]; // Driver version
char serverName[40]; // Server Name, typically a connect string
char databaseName[128]; // Database filename
char outerJoins[2]; // Indicates whether the data source supports outer joins
char procedureSupport[2]; // Indicates whether the data source supports stored procedures
UWORD maxConnections; // Maximum # of connections the data source supports
UWORD maxStmts; // Maximum # of HSTMTs per HDBC
UWORD apiConfLvl; // ODBC API conformance level
UWORD cliConfLvl; // Indicates whether the data source is SAG compliant
UWORD sqlConfLvl; // SQL conformance level
UWORD cursorCommitBehavior; // Indicates how cursors are affected by a db commit
UWORD cursorRollbackBehavior; // Indicates how cursors are affected by a db rollback
UWORD supportNotNullClause; // Indicates if data source supports NOT NULL clause
char supportIEF[2]; // Integrity Enhancement Facility (Referential Integrity)
UDWORD txnIsolation; // Default transaction isolation level supported by the driver
UDWORD txnIsolationOptions; // Transaction isolation level options available
UDWORD fetchDirections; // Fetch directions supported
UDWORD lockTypes; // Lock types supported in SQLSetPos
UDWORD posOperations; // Position operations supported in SQLSetPos
UDWORD posStmts; // Position statements supported
UDWORD scrollConcurrency; // Concurrency control options supported for scrollable cursors
UDWORD scrollOptions; // Scroll Options supported for scrollable cursors
UDWORD staticSensitivity; // Indicates if additions, deletions and updates can be detected
UWORD txnCapable; // Indicates if the data source supports transactions
UDWORD loginTimeout; // Number seconds to wait for a login request
} dbInf;
// ODBC handles
HENV henv; // ODBC Environment handle
HDBC hdbc; // ODBC DB Connection handle
HSTMT hstmt; // ODBC Statement handle
// ODBC Error Inf.
char sqlState[20];
SDWORD nativeError;
char errorMsg[SQL_MAX_MESSAGE_LENGTH];
SWORD cbErrorMsg;
char errorList[DB_MAX_ERROR_HISTORY][DB_MAX_ERROR_MSG_LEN];
int DB_STATUS;
//Error reporting mode
bool silent;
// Inf. about logical data types VARCHAR, INTEGER, FLOAT and DATE.
// This inf. is obtained from the ODBC driver by use of the
// SQLGetTypeInfo() function. The key piece of inf. is the
// type name the data source uses for each logical data type.
// e.g. VARCHAR; Oracle calls it VARCHAR2.
SqlTypeInfo typeInfVarchar, typeInfInteger, typeInfFloat, typeInfDate;
// Public member functions
wxDB(HENV &aHenv);
bool Open(char *Dsn, char *Uid, char *AuthStr); // Data Source Name, User ID, Password
void Close(void);
bool CommitTrans(void);
bool RollbackTrans(void);
bool DispAllErrors(HENV aHenv, HDBC aHdbc = SQL_NULL_HDBC, HSTMT aHstmt = SQL_NULL_HSTMT);
bool GetNextError(HENV aHenv, HDBC aHdbc = SQL_NULL_HDBC, HSTMT aHstmt = SQL_NULL_HSTMT);
void DispNextError(void);
bool CreateView(char *viewName, char *colList, char *pSqlStmt);
bool ExecSql(char *pSqlStmt);
bool Grant(int privileges, char *tableName, char *userList = "PUBLIC");
int TranslateSqlState(char *SQLState);
CcolInf *GetColumns(char *tableName[]);
char *GetDatabaseName(void) {return dbInf.dbmsName;}
char *GetDataSource(void) {return dsn;}
char *GetUsername(void) {return uid;}
char *GetPassword(void) {return authStr;}
bool IsOpen(void) {return dbIsOpen;}
HENV GetHENV(void) {return henv;}
HDBC GetHDBC(void) {return hdbc;}
HSTMT GetHSTMT(void) {return hstmt;}
bool TableExists(char *tableName); // Table name can refer to a table, view, alias or synonym
void LogError(char *errMsg, char *SQLState = 0) {logError(errMsg, SQLState);}
}; // wxDB
// This structure forms a node in a linked list. The linked list of "DbList" objects
// keeps track of allocated database connections. This allows the application to
// open more than one database connection through ODBC for multiple transaction support
// or for multiple database support.
struct DbList
{
DbList *PtrPrev; // Pointer to previous item in the list
char Dsn[SQL_MAX_DSN_LENGTH+1]; // Data Source Name
wxDB *PtrDb; // Pointer to the wxDB object
bool Free; // Is item free or in use?
DbList *PtrNext; // Pointer to next item in the list
};
// The following routines allow a user to get new database connections, free them
// for other code segments to use, or close all of them when the application has
// completed.
wxDB *GetDbConnection(DbStuff *pDbStuff);
bool FreeDbConnection(wxDB *pDb);
void CloseDbConnections(void);
int NumberDbConnectionsInUse(void);
// This routine allows you to query a driver manager
// for a list of available datasources. Call this routine
// the first time using SQL_FETCH_FIRST. Continue to call it
// using SQL_FETCH_NEXT until you've exhausted the list.
bool GetDataSource(HENV henv, char *Dsn, SWORD DsnMax, char *DsDesc, SWORD DsDescMax,
UWORD direction = SQL_FETCH_NEXT);
#endif

165
include/wx/dbtable.h Normal file
View File

@@ -0,0 +1,165 @@
///////////////////////////////////////////////////////////////////////////////
// Name: table.h
// Purpose: Declaration of the wxTable class.
// Author: Doug Card
// Modified by:
// Created: 9.96
// RCS-ID: $Id$
// Copyright: (c) 1996 Remstar International, Inc.
// Licence: wxWindows licence, plus:
// Notice: This class library and its intellectual design are free of charge for use,
// modification, enhancement, debugging under the following conditions:
// 1) These classes may only be used as part of the implementation of a
// wxWindows-based application
// 2) All enhancements and bug fixes are to be submitted back to the wxWindows
// user groups free of all charges for use with the wxWindows library.
// 3) These classes may not be distributed as part of any other class library,
// DLL, text (written or electronic), other than a complete distribution of
// the wxWindows GUI development toolkit.
///////////////////////////////////////////////////////////////////////////////
/*
// SYNOPSIS START
// SYNOPSIS STOP
*/
#ifndef TABLE_DOT_H
#define TABLE_DOT_H
#ifdef __GNUG__
#pragma interface "dbtable.h"
#endif
#include "wx/db.h"
const ROWID_LEN = 24; // 18 is the max, 24 is in case it gets larger
// The following class is used to define a column of a table.
// The wxTable constructor will dynamically allocate as many of
// these as there are columns in the table. The class derived
// from wxTable must initialize these column definitions in it's
// constructor. These column definitions provide inf. to the
// wxTable class which allows it to create a table in the data
// source, exchange data between the data source and the C++
// object, and so on.
class CcolDef
{
public:
char ColName[DB_MAX_COLUMN_NAME_LEN+1]; // Column Name glt 4/19/97 added one for the null terminator
int DbDataType; // Logical Data Type; e.g. DB_DATA_TYPE_INTEGER
int SqlCtype; // C data type; e.g. SQL_C_LONG
void *PtrDataObj; // Address of the data object
int SzDataObj; // Size, in bytes, of the data object
bool KeyField; // TRUE if this column is part of the PRIMARY KEY to the table; Date fields should NOT be KeyFields.
bool Updateable; // Specifies whether this column is updateable
bool InsertAllowed; // Specifies whether this column should be included in an INSERT statement
bool DerivedCol; // Specifies whether this column is a derived value
SDWORD CbValue; // Internal use only!!!
}; // CcolDef
// This structure is used when creating secondary indexes.
class CidxDef
{
public:
char ColName[DB_MAX_COLUMN_NAME_LEN+1]; // Column Name glt 4/19/97 added one for the null terminator
bool Ascending;
}; // CidxDef
class wxTable
{
private:
// Private member variables
int currCursorNo;
// Private member functions
bool bindInsertParams(void);
bool bindUpdateParams(void);
bool bindCols(HSTMT cursor);
bool getRec(UWORD fetchType);
bool execDelete(char *pSqlStmt);
bool execUpdate(char *pSqlStmt);
bool query(int queryType, bool forUpdate, bool distinct, char *pSqlStmt = 0);
public:
// Pointer to the database object this table belongs to
wxDB *pDb;
// ODBC Handles
HENV henv; // ODBC Environment handle
HDBC hdbc; // ODBC DB Connection handle
HSTMT hstmt; // ODBC Statement handle
// HSTMT c0, c1, c2, c3, c4, c5; // Cursors 0 through 5
HSTMT c0, c1, c2; // Limited to Cursors 0 through 2 for now
HSTMT hstmtInsert; // ODBC Statement handle used specifically for inserts
HSTMT hstmtDelete; // ODBC Statement handle used specifically for deletes
HSTMT hstmtUpdate; // ODBC Statement handle used specifically for updates
HSTMT hstmtCount; // ODBC Statement handle used specifically for COUNT(*)
// Table Inf.
char tableName[DB_MAX_TABLE_NAME_LEN+1]; // Table name
char queryTableName[DB_MAX_TABLE_NAME_LEN+1]; // Query Table Name
int noCols; // # of columns in the table
// Column Definitions
CcolDef *colDefs; // Array of CcolDef structures
// Where and Order By clauses
char *where; // Standard SQL where clause, minus the word WHERE
char *orderBy; // Standard SQL order by clause, minus the ORDER BY
// Flags
bool selectForUpdate;
// Public member functions
wxTable(wxDB *pwxDB, const char *tblName, const int nCols, const char *qryTblName = 0);
~wxTable();
bool Open(void);
bool CreateTable(void);
bool CreateIndex(char * idxName, bool unique, int noIdxCols, CidxDef *pIdxDefs);
bool CloseCursor(HSTMT cursor);
int Insert(void);
bool Update(void);
bool Update(char *pSqlStmt);
bool UpdateWhere(char *pWhereClause);
bool Delete(void);
bool DeleteWhere(char *pWhereClause);
bool DeleteMatching(void);
bool Query(bool forUpdate = FALSE, bool distinct = FALSE);
bool QueryBySqlStmt(char *pSqlStmt);
bool QueryMatching(bool forUpdate = FALSE, bool distinct = FALSE);
bool QueryOnKeyFields(bool forUpdate = FALSE, bool distinct = FALSE);
bool GetNext(void) { return(getRec(SQL_FETCH_NEXT)); }
bool operator++(int) { return(getRec(SQL_FETCH_NEXT)); }
#ifndef FWD_ONLY_CURSORS
bool GetPrev(void) { return(getRec(SQL_FETCH_PRIOR)); }
bool operator--(int) { return(getRec(SQL_FETCH_PRIOR)); }
bool GetFirst(void) { return(getRec(SQL_FETCH_FIRST)); }
bool GetLast(void) { return(getRec(SQL_FETCH_LAST)); }
#endif
bool IsCursorClosedOnCommit(void);
bool IsColNull(int colNo);
UWORD GetRowNum(void);
void GetSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct);
void GetDeleteStmt(char *pSqlStmt, int typeOfDel, char *pWhereClause = 0);
void GetUpdateStmt(char *pSqlStmt, int typeOfUpd, char *pWhereClause = 0);
void GetWhereClause(char *pWhereClause, int typeOfWhere);
bool CanSelectForUpdate(void);
bool CanUpdByROWID(void);
void ClearMemberVars(void);
bool SetQueryTimeout(UDWORD nSeconds);
void SetColDefs (int index, char *fieldName, int dataType, void *pData, int cType,
int size, bool keyField = FALSE, bool upd = TRUE,
bool insAllow = TRUE, bool derivedCol = FALSE);
bool SetCursor(int cursorNo = DB_CURSOR0);
int GetCursor(void) { return(currCursorNo); }
ULONG Count(void);
int DB_STATUS(void) { return(pDb->DB_STATUS); }
bool Refresh(void);
}; // wxTable
#endif

View File

@@ -142,13 +142,6 @@
#define USE_ODBC 1 #define USE_ODBC 1
// Define 1 to use ODBC classes // Define 1 to use ODBC classes
#define USE_ODBC_IN_MSW_ONLY 1
#if USE_ODBC && USE_ODBC_IN_MSW_ONLY
#undef USE_ODBC
#define USE_ODBC 0
#endif
#define USE_IOSTREAMH 1 #define USE_IOSTREAMH 1
// VC++ 4.2 and above allows <iostream> and <iostream.h> // VC++ 4.2 and above allows <iostream> and <iostream.h>
// but you can't mix them. Set to 1 for <iostream.h>, // but you can't mix them. Set to 1 for <iostream.h>,

2041
samples/db/dbtest.cpp Normal file

File diff suppressed because it is too large Load Diff

8
samples/db/dbtest.def Normal file
View File

@@ -0,0 +1,8 @@
NAME DBTEST
DESCRIPTION 'Database wxWindows application'
EXETYPE WINDOWS
STUB 'WINSTUB.EXE'
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
HEAPSIZE 1024
STACKSIZE 8192

286
samples/db/dbtest.h Normal file
View File

@@ -0,0 +1,286 @@
///////////////////////////////////////////////////////////////////////////////
// Name: dbtest.h
// Purpose: wxWindows database demo app
// Author: George Tasker
// Modified by:
// Created: 1998
// RCS-ID: $Id$
// Copyright: (c) 1998 Remstar International, Inc.
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#pragma interface "dbtest.h"
#include <wx/string.h>
#include <wx/dbtable.h>
enum DialogModes {mView,mCreate,mEdit,mSearch};
// ID for the menu quit command
#define FILE_CREATE 100
#define FILE_EXIT 199
#define EDIT_PARAMETERS 200
#define ABOUT_DEMO 300
// Name of the table to be created/opened
const char CONTACT_TABLE_NAME[] = "CONTACTS";
// Nuber of columns in the above table
const int CONTACT_NO_COLS = 12; // 0-11
// Global structure for holding ODBC connection information
struct DbStuff DbConnectInf;
enum Language {langENGLISH, langFRENCH, langGERMAN, langSPANISH, langOTHER};
// Forward class declarations
class CeditorDlg;
class CparameterDlg;
const char paramFilename[] = "database.cfg";
/*
* This class contains the actual data members that are used for transferring
* data back and forth from the database to the program.
*
* NOTE: The object described in this class is just for example purposes, and has no
* real meaning other than to show each type of field being used by the database
*/
class CstructContact : public wxObject
{
public:
char Name[ 50+1 ]; // Contact's name
char Addr1[ 50+1 ];
char Addr2[ 50+1 ];
char City[ 25+1 ];
char State[ 25+1 ];
char PostalCode[ 15+1 ];
char Country[ 20+1 ];
TIMESTAMP_STRUCT JoinDate; // Date on which this person joined the wxWindows project
Language NativeLanguage; // Enumerated type indicating person's native language
bool IsDeveloper; // Is this person a developer for wxWindows, or just a subscriber
int Contributions; // Something to show off an integer field
ULONG LinesOfCode; // Something to show off a 'long' field
}; // CstructContact
//
// NOTE: Ccontact inherits wxTable, which gives access to all the database functionality
//
class Ccontact : public wxTable, public CstructContact
{
private:
bool freeDbConn;
void SetupColumns();
public:
wxString whereStr;
wxString qryWhereStr; // Where string returned from the query dialog
Ccontact(wxDB *pwxDB=NULL);
~Ccontact();
void Initialize();
bool CreateIndexes(void);
bool FetchByName(char *name);
}; // Ccontact class definition
typedef struct Cparameters
{
// The length of these strings were arbitrarily picked, and are
// dependent on the OS and database engine you will be using.
char ODBCSource[100+1];
char UserName[25+1];
char Password[25+1];
} Cparameters;
// Define a new application type
class DatabaseDemoApp: public wxApp
{
public:
Cparameters params;
wxFrame *OnInit(void);
}; // DatabaseDemoApp
DECLARE_APP(DatabaseDemoApp)
// Define a new frame type
class DatabaseDemoFrame: public wxFrame
{
private:
CeditorDlg *pEditorDlg;
CparameterDlg *pParamDlg;
public:
DatabaseDemoFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
void OnMenuCommand(int id);
bool OnClose(void);
void CreateDataTable();
void BuildEditorDialog();
void BuildParameterDialog(wxWindow *parent);
}; // DatabaseDemoFrame
// *************************** CeditorDlg ***************************
class CeditorDlg : public wxPanel
{
private:
bool widgetPtrsSet;
wxString saveName;
// Pointers to all widgets on the dialog
wxButton *pCreateBtn, *pEditBtn, *pDeleteBtn, *pCopyBtn, *pSaveBtn, *pCancelBtn;
wxButton *pPrevBtn, *pNextBtn, *pQueryBtn, *pResetBtn, *pDoneBtn, *pHelpBtn;
wxButton *pNameListBtn;
wxText *pNameTxt, *pAddress1Txt, *pAddress2Txt,*pCityTxt, *pStateTxt, *pCountryTxt,*pPostalCodeTxt;
wxMessage *pNameMsg, *pAddress1Msg, *pAddress2Msg,*pCityMsg, *pStateMsg, *pCountryMsg,*pPostalCodeMsg;
wxText *pJoinDateTxt,*pContribTxt, *pLinesTxt;
wxMessage *pJoinDateMsg,*pContribMsg, *pLinesMsg;
wxRadioBox *pDeveloperRadio;
wxChoice *pNativeLangChoice;
wxMessage *pNativeLangMsg;
public:
enum DialogModes mode;
Ccontact *Contact; // this is the table object that will be being manipulated
CeditorDlg(wxWindow *parent);
bool OnClose(void);
void OnCommand(wxWindow& win, wxCommandEvent& event);
void OnActivate(bool) {}; // necessary for hot keys
void FieldsEditable();
void SetMode(enum DialogModes m);
bool PutData();
bool GetData();
bool Save();
bool GetNextRec();
bool GetPrevRec();
bool GetRec(char *whereStr);
}; // CeditorDlg
// *************************** CparameterDlg ***************************
class CparameterDlg : public wxDialogBox
{
private:
bool widgetPtrsSet;
enum DialogModes mode;
bool saved;
Cparameters savedParamSettings;
// Pointers to all widgets on the dialog
wxMessage *pParamODBCSourceMsg;
wxListBox *pParamODBCSourceList;
wxMessage *pParamUserNameMsg, *pParamPasswordMsg;
wxText *pParamUserNameTxt, *pParamPasswordTxt;
wxButton *pParamSaveBtn, *pParamCancelBtn;
public:
CparameterDlg(wxWindow *parent);
bool OnClose(void);
void OnCommand(wxWindow& win, wxCommandEvent& event);
void OnActivate(bool) {}; // necessary for hot keys
bool PutData();
bool GetData();
bool Save();
void FillDataSourceList();
}; // CparameterDlg
// *************************** CqueryDlg ***************************
// QUERY DIALOG
enum qryOp
{
qryOpEQ,
qryOpLT,
qryOpGT,
qryOpLE,
qryOpGE,
qryOpBEGINS,
qryOpCONTAINS,
qryOpLIKE,
qryOpBETWEEN
};
// Query strings
char * const langQRY_EQ = "column = column | value";
char * const langQRY_LT = "column < column | value";
char * const langQRY_GT = "column > column | value";
char * const langQRY_LE = "column <= column | value";
char * const langQRY_GE = "column >= column | value";
char * const langQRY_BEGINS = "columns that BEGIN with the string entered";
char * const langQRY_CONTAINS = "columns that CONTAIN the string entered";
char * const langQRY_LIKE = "% matches 0 or more of any char; _ matches 1 char";
char * const langQRY_BETWEEN = "column BETWEEN value AND value";
class CqueryDlg : public wxDialogBox
{
private:
CcolInf *colInf; // Column inf. returned by db->GetColumns()
wxTable *dbTable;
char *masterTableName;
char *pWhere; // A pointer to the storage for the resulting where clause
wxDB *pDB;
public:
bool widgetPtrsSet;
// Widget pointers
wxMessage *pQueryCol1Msg;
wxChoice *pQueryCol1Choice;
wxMessage *pQueryNotMsg;
wxCheckBox *pQueryNotCheck;
wxMessage *pQueryOperatorMsg;
wxChoice *pQueryOperatorChoice;
wxMessage *pQueryCol2Msg;
wxChoice *pQueryCol2Choice;
wxMessage *pQueryValue1Msg;
wxText *pQueryValue1Txt;
wxMessage *pQueryValue2Msg;
wxText *pQueryValue2Txt;
wxMessage *pQuerySqlWhereMsg;
wxMultiText *pQuerySqlWhereMtxt;
wxButton *pQueryAddBtn;
wxButton *pQueryAndBtn;
wxButton *pQueryOrBtn;
wxButton *pQueryLParenBtn;
wxButton *pQueryRParenBtn;
wxButton *pQueryDoneBtn;
wxButton *pQueryClearBtn;
wxButton *pQueryCountBtn;
wxButton *pQueryHelpBtn;
wxGroupBox *pQueryHintGrp;
wxMessage *pQueryHintMsg;
wxText *pFocusTxt;
CqueryDlg(wxWindow *parent, wxDB *pDb, char *tblName[], char *pWhereArg);
void OnCommand(wxWindow& win, wxCommandEvent& event);
bool OnClose();
void OnActivate(bool) {}; // necessary for hot keys
// bool SetWidgetPtrs();
void AppendToWhere(char *s);
void ProcessAddBtn();
void ProcessCountBtn();
bool ValidateWhereClause();
}; // CqueryDlg

BIN
samples/db/dbtest.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

3
samples/db/dbtest.rc Normal file
View File

@@ -0,0 +1,3 @@
db_icon ICON "dbtest.ico"
#include "wx.rc"

412
samples/db/listdb.cpp Normal file
View File

@@ -0,0 +1,412 @@
///////////////////////////////////////////////////////////////////////////////
// Name: listdb.cpp
// Purpose: Data table lookup listbox code
// Author: George Tasker/Doug Card
// Modified by:
// Created: 1996
// RCS-ID: $Id$
// Copyright: (c) 1996 Remstar International, Inc.
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
/*
// SYNOPSIS START
Member functions for the classes defined in LISTDB.H
This class is used to present a generic ListBox lookup window for
use with any of the object creation/selection choice widgets. This
dialog window will present a (possibly) scrolling list of values
that come from a data table source. Based on the object type passed
in the constructor, a ListBox is built to present the user with a
single selection listbox.
The string selected from the list box is stored in the Global variable
"ListDB_Seclection", and will remain set until another interation of this
routine is called.
For each object (database) type that is to be used, an overridden
constructor should be written to appropriately link to the proper
data table/object for building the list.
The data table record access is all handled through the routines
in this module, interfacing with the methods defined in wxTable.
All objects which use data table access must be initialized and
have opened the table prior to passing them in the dialog
constructor, and the 'where' query should already have been set
and performed before creating this dialog instance.
// SYNOPSIS STOP
*/
#ifdef __GNUG__
#pragma implementation "listdb.h"
#endif
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif //__BORLANDC__
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif //WX_PRECOMP
#include <wx/dbtable.h>
#include "listdb.h"
// Global structure for holding ODBC connection information
extern DbStuff DbConnectInf;
// Global database connection
extern wxDB *READONLY_DB;
// Used for passing the selected listbox selection back to the calling
// routine. This variable must be declared as 'extern' in the calling
// source module
char ListDB_Selection[LOOKUP_COL_LEN+1];
// If the listbox contains two columns of data, the second column is
// returned in this variable.
char ListDB_Selection2[LOOKUP_COL_LEN+1];
// Constants
const LISTDB_NO_SPACES_BETWEEN_COLS = 3;
// Clookup constructor
Clookup::Clookup(char *tblName, char *colName) : wxTable(READONLY_DB, tblName, 1)
{
SetColDefs (0, colName, DB_DATA_TYPE_VARCHAR, lookupCol, SQL_C_CHAR, LOOKUP_COL_LEN+1, FALSE, FALSE);
} // Clookup()
// Clookup2 constructor
Clookup2::Clookup2(char *tblName, char *colName1, char *colName2, wxDB *pDb)
: wxTable(pDb, tblName, (1 + (strlen(colName2) > 0)))
{
int i = 0;
SetColDefs (i, colName1, DB_DATA_TYPE_VARCHAR, lookupCol1, SQL_C_CHAR, LOOKUP_COL_LEN+1, FALSE, FALSE);
if (strlen(colName2) > 0)
SetColDefs (++i, colName2, DB_DATA_TYPE_VARCHAR, lookupCol2, SQL_C_CHAR, LOOKUP_COL_LEN+1, FALSE, FALSE);
} // Clookup2()
// This is a generic lookup constructor that will work with any table and any column
ClookUpDlg::ClookUpDlg(wxWindow *parent, char *windowTitle, char *tableName, char *colName,
char *where, char *orderBy) : wxDialogBox (parent, "Select...", 1, -1, -1, 400, 290)
{
wxBeginBusyCursor();
strcpy(ListDB_Selection,"");
widgetPtrsSet = FALSE;
lookup = 0;
lookup2 = 0;
noDisplayCols = 1;
col1Len = 0;
// Build the dialog
SetLabelPosition(wxVERTICAL);
wxFont *ButtonFont = new wxFont(12,wxSWISS,wxNORMAL,wxBOLD);
wxFont *TextFont = new wxFont(12,wxSWISS,wxNORMAL,wxNORMAL);
SetButtonFont(ButtonFont);
SetLabelFont(TextFont);
SetLabelPosition(wxVERTICAL);
pLookUpSelectList = new wxListBox(this, NULL, "", wxSINGLE|wxALWAYS_SB, 5, 15, 384, 195, 0, 0, 0, "LookUpSelectList");
pLookUpOkBtn = new wxButton(this, NULL, "&Ok", 113, 222, 70, 35, 0, "LookUpOkBtn");
pLookUpCancelBtn = new wxButton(this, NULL, "C&ancel", 212, 222, 70, 35, 0, "LookUpCancelBtn");
widgetPtrsSet = TRUE;
// Query the lookup table and display the result set
if (!(lookup = new Clookup(tableName, colName)))
{
wxMessageBox("Error allocating memory for 'Clookup'object.","Error...");
Close();
return;
}
if (!lookup->Open())
{
wxString tStr;
tStr.sprintf("Unable to open the table '%s'.",tableName);
wxMessageBox(tStr.GetData(),"ODBC Error...");
Close();
return;
}
lookup->orderBy = orderBy;
lookup->where = where;
if (!lookup->Query())
{
wxMessageBox("ODBC error during Query()","ODBC Error...");
Close();
return;
}
// Fill in the list box from the query result set
while (lookup->GetNext())
pLookUpSelectList->Append(lookup->lookupCol);
// Highlight the first list item
pLookUpSelectList->SetSelection(0);
// Make the OK activate by pressing Enter
if (pLookUpSelectList->Number())
pLookUpOkBtn->SetDefault();
else
{
pLookUpCancelBtn->SetDefault();
pLookUpOkBtn->Enable(FALSE);
}
// Display the dialog window
SetTitle(windowTitle);
Centre(wxBOTH);
wxEndBusyCursor();
Show(TRUE);
} // Generic lookup constructor
//
// This is a generic lookup constructor that will work with any table and any column.
// It extends the capabilites of the lookup dialog in the following ways:
//
// 1) 2 columns rather than one
// 2) The ability to select DISTINCT column values
//
// Only set distinctValues equal to true if necessary. In many cases, the constraints
// of the index(es) will enforce this uniqueness. Selecting DISTINCT does require
// overhead by the database to ensure that all values returned are distinct. Therefore,
// use this ONLY when you need it.
//
// For complicated queries, you can pass in the sql select statement. This would be
// necessary if joins are involved since by default both columns must come from the
// same table.
//
// If you do query by sql statement, you must pass in the maximum lenght of column1,
// since it cannot be derived when you query using your own sql statement.
//
// The optional database connection can be used if you'd like the lookup class
// to use a database pointer other than the global READONLY_DB. This is necessary if
// records are being saved, but not committed to the db, yet should be included
// in the lookup window.
//
ClookUpDlg::ClookUpDlg(wxWindow *parent, char *windowTitle, char *tableName,
char *dispCol1, char *dispCol2, char *where, char *orderBy, bool distinctValues,
char *selectStmt, int maxLenCol1, wxDB *pDb, bool allowOk) : wxDialogBox (parent, "Select...", 1, -1, -1, 400, 290)
{
wxBeginBusyCursor();
strcpy(ListDB_Selection,"");
strcpy(ListDB_Selection2,"");
widgetPtrsSet = FALSE;
lookup = 0;
lookup2 = 0;
noDisplayCols = (strlen(dispCol2) ? 2 : 1);
col1Len = 0;
// Build the dialog
SetLabelPosition(wxVERTICAL);
wxFont *ButtonFont = new wxFont(12,wxSWISS,wxNORMAL,wxBOLD);
wxFont *TextFont = new wxFont(12,wxSWISS,wxNORMAL,wxNORMAL);
wxFont *FixedFont = new wxFont(12,wxMODERN,wxNORMAL,wxNORMAL);
SetButtonFont(ButtonFont);
SetLabelFont(TextFont);
SetLabelPosition(wxVERTICAL);
// this is done with fixed font so that the second column (if any) will be left
// justified in the second column
SetButtonFont(FixedFont);
pLookUpSelectList = new wxListBox(this, NULL, "", wxSINGLE|wxALWAYS_SB, 5, 15, 384, 195, 0, 0, 0, "LookUpSelectList");
SetButtonFont(ButtonFont);
pLookUpOkBtn = new wxButton(this, NULL, "&Ok", 113, 222, 70, 35, 0, "LookUpOkBtn");
pLookUpCancelBtn = new wxButton(this, NULL, "C&ancel", 212, 222, 70, 35, 0, "LookUpCancelBtn");
widgetPtrsSet = TRUE;
// Query the lookup table and display the result set
if (!(lookup2 = new Clookup2(tableName, dispCol1, dispCol2, pDb)))
{
wxMessageBox("Error allocating memory for 'Clookup2'object.","Error...");
Close();
return;
}
if (!lookup2->Open())
{
wxString tStr;
tStr.sprintf("Unable to open the table '%s'.",tableName);
wxMessageBox(tStr.GetData(),"ODBC Error...");
Close();
return;
}
// If displaying 2 columns, determine the maximum length of column1
int maxColLen;
if (maxLenCol1)
maxColLen = col1Len = maxLenCol1; // user passed in max col length for column 1
else
{
maxColLen = LOOKUP_COL_LEN;
if (strlen(dispCol2))
{
wxString q = "SELECT MAX({fn LENGTH(";
q += dispCol1;
q += ")}), NULL";
q += " FROM ";
q += tableName;
if (strlen(where))
{
q += " WHERE ";
q += where;
}
if (!lookup2->QueryBySqlStmt(q.GetData()))
{
wxMessageBox("ODBC error during QueryBySqlStmt()","ODBC Error...");
Close();
return;
}
if (lookup2->GetNext())
maxColLen = col1Len = atoi(lookup2->lookupCol1);
else
wxMessageBox("ODBC error during GetNext()","ODBC Error...");
}
}
// Query the actual record set
if (selectStmt && strlen(selectStmt)) // Query by sql stmt passed in
{
if (!lookup2->QueryBySqlStmt(selectStmt))
{
wxMessageBox("ODBC error during QueryBySqlStmt()","ODBC Error...");
Close();
return;
}
}
else // Query using where and order by clauses
{
lookup2->orderBy = orderBy;
lookup2->where = where;
if (!lookup2->Query(FALSE, distinctValues))
{
wxMessageBox("ODBC error during Query()","ODBC Error...");
Close();
return;
}
}
// Fill in the list box from the query result set
wxString s;
while (lookup2->GetNext())
{
s = lookup2->lookupCol1;
if (strlen(dispCol2)) // Append the optional column 2
{
s.Append(' ', (maxColLen + LISTDB_NO_SPACES_BETWEEN_COLS - strlen(lookup2->lookupCol1)));
s.Append(lookup2->lookupCol2);
}
pLookUpSelectList->Append(s.GetData());
}
// Highlight the first list item
pLookUpSelectList->SetSelection(0);
// Make the OK activate by pressing Enter
if (pLookUpSelectList->Number())
pLookUpOkBtn->SetDefault();
else
{
pLookUpCancelBtn->SetDefault();
pLookUpOkBtn->Enable(FALSE);
}
pLookUpOkBtn->Enable(allowOk);
// Display the dialog window
SetTitle(windowTitle);
Centre(wxBOTH);
wxEndBusyCursor();
Show(TRUE);
} // Generic lookup constructor 2
bool ClookUpDlg::OnClose(void)
{
widgetPtrsSet = FALSE;
GetParent()->Enable(TRUE);
if (lookup)
delete lookup;
if (lookup2)
delete lookup2;
wxEndBusyCursor();
return TRUE;
} // ClookUpDlg::OnClose
void ClookUpDlg::OnCommand(wxWindow& win, wxCommandEvent& event)
{
wxString widgetName = win.GetName();
if (widgetPtrsSet)
{
// OK Button
if (widgetName == pLookUpOkBtn->GetName())
{
if (pLookUpSelectList->GetSelection() != -1)
{
if (noDisplayCols == 1)
strcpy (ListDB_Selection, pLookUpSelectList->GetStringSelection());
else // 2 display columns
{
wxString s = pLookUpSelectList->GetStringSelection();
// Column 1
s = s.SubString(0, col1Len-1);
s = s.Strip();
strcpy(ListDB_Selection, s.GetData());
// Column 2
s = pLookUpSelectList->GetStringSelection();
s = s.From(col1Len + LISTDB_NO_SPACES_BETWEEN_COLS);
s = s.Strip();
strcpy(ListDB_Selection2, s.GetData());
}
}
else
{
strcpy(ListDB_Selection,"");
strcpy(ListDB_Selection2,"");
}
Close();
} // OK Button
// Cancel Button
if (widgetName == pLookUpCancelBtn->GetName())
{
strcpy (ListDB_Selection,"");
strcpy (ListDB_Selection2,"");
Close();
} // Cancel Button
}
}; // ClookUpDlg::OnCommand
// *********************************** listdb.cpp **********************************

125
samples/db/listdb.h Normal file
View File

@@ -0,0 +1,125 @@
///////////////////////////////////////////////////////////////////////////////
// Name: listdb.h
// Purpose: wxWindows database demo app
// Author: George Tasker
// Modified by:
// Created: 1996
// RCS-ID: $Id$
// Copyright: (c) 1996 Remstar International, Inc.
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#pragma interface "listdb.h"
/*
/*
// SYNOPSIS START
Contains dialog class for creating a data table lookup listbox
// SYNOPSIS STOP
*/
#ifndef LISTDB_DOT_H
#define LISTDB_DOT_H
#include <wx/dbtable.h>
const LOOKUP_COL_LEN = 250;
// Global database connection
extern wxDB *READONLY_DB;
// Clookup class
class Clookup : public wxTable
{
public:
char lookupCol[LOOKUP_COL_LEN+1];
Clookup(char *tblName, char *colName);
}; // Clookup
// Clookup2 class
class Clookup2 : public wxTable
{
public:
char lookupCol1[LOOKUP_COL_LEN+1];
char lookupCol2[LOOKUP_COL_LEN+1];
Clookup2(char *tblName, char *colName1, char *colName2, wxDB *pDb);
}; // Clookup2
class ClookUpDlg : public wxDialogBox
{
private:
bool widgetPtrsSet;
int currentCursor;
Clookup *lookup;
Clookup2 *lookup2;
int noDisplayCols;
int col1Len;
wxListBox *pLookUpSelectList;
wxButton *pLookUpOkBtn;
wxButton *pLookUpCancelBtn;
public:
// This is a generic lookup constructor that will work with any table and any column
ClookUpDlg(wxWindow *parent,
char *windowTitle,
char *tableName,
char *colName,
char *where,
char *orderBy);
//
// This is a generic lookup constructor that will work with any table and any column.
// It extends the capabilites of the lookup dialog in the following ways:
//
// 1) 2 columns rather than one
// 2) The ability to select DISTINCT column values
//
// Only set distinctValues equal to true if necessary. In many cases, the constraints
// of the index(es) will enforce this uniqueness. Selecting DISTINCT does require
// overhead by the database to ensure that all values returned are distinct. Therefore,
// use this ONLY when you need it.
//
// For complicated queries, you can pass in the sql select statement. This would be
// necessary if joins are involved since by default both columns must come from the
// same table.
//
// If you do query by sql statement, you must pass in the maximum length of column1,
// since it cannot be derived when you query using your own sql statement.
//
// The optional database connection can be used if you'd like the lookup class
// to use a database pointer other than the global READONLY_DB. This is necessary if
// records are being saved, but not committed to the db, yet should be included
// in the lookup window.
//
ClookUpDlg(wxWindow *parent,
char *windowTitle,
char *tableName,
char *dispCol1, // Must have at least 1 display column
char *dispCol2, // Optional
char *where,
char *orderBy,
bool distinctValues, // e.g. SELECT DISTINCT ...
char *selectStmt = 0, // If you wish to query by SQLstmt (complicated lookups)
int maxLenCol1 = 0, // Mandatory if querying by SQLstmt
wxDB *pDb = READONLY_DB, // Database connection pointer
bool allowOk = TRUE); // is the OK button enabled
void OnCommand(wxWindow& win, wxCommandEvent& event);
bool OnClose();
void OnActivate(bool) {}; // necessary for hot keys
};
#endif // LISTDB_DOT_H
// ************************************ listdb.h *********************************

97
samples/db/makefile.nt Normal file
View File

@@ -0,0 +1,97 @@
#
# File: makefile.nt
# Author: George Tasker
# Created: 1998
# Updated:
#
# "%W% %G%"
#
# Makefile : Builds database example (MS VC++).
!if "$(FINAL)" == ""
FINAL=0
!endif
!if "$(MSVCDIR)" == ""
MSVCDIR=c:\devstudio\vc
!endif
# Set WXDIR for your system
WXDIR = $(WXWIN)
THISDIR = $(WXDIR)\samples\database
WXODBCDIR = $(WXDIR)\utils\wxodbc
!if "$(MSVCDIR)" == ""
DBLIBS=$(MSDEVDIR)\lib\odbc32.lib
!else
DBLIBS=$(MSVCDIR)\lib\odbc32.lib
!endif
EXTRAINC = -I$(WXODBCDIR)\src
EXTRALIBS = $(DBLIBS) $(WXODBCDIR)\lib\wxodbc.lib
!include $(WXDIR)\src\ntwxwin.mak
PROGRAM=database
OBJECTS = $(PROGRAM).$(OBJSUFF) listdb.$(OBJSUFF)
all: wxodbc $(PROGRAM).exe
$(PROGRAM): $(PROGRAM).exe
gt:
cd $(CPPFLAGS)
wxodbc:
cd $(WXODBCDIR)\src
nmake -f makefile.nt FINAL=$(FINAL)
cd $(THISDIR)
wx:
cd $(WXDIR)\src\msw
nmake -f makefile.nt FINAL=$(FINAL)
cd $(THISDIR)
wxclean:
cd $(WXDIR)\src\msw
nmake -f makefile.nt clean
cd $(THISDIR)
cd $(WXODBCDIR)\src
nmake -f makefile.nt clean
cd $(THISDIR)
$(PROGRAM).exe: $(DUMMYOBJ) $(OBJECTS) $(PROGRAM).res
$(link) @<<
-out:$(PROGRAM).exe
$(LINKFLAGS)
$(DUMMYOBJ) $(OBJECTS) $(PROGRAM).res
$(LIBS)
<<
listdb.$(OBJSUFF): $(*B).$(SRCSUFF) $(*B).h
$(cc) @<<
$(CPPFLAGS) /c /Fo$(*B).$(OBJSUFF) /Tp $(*B).$(SRCSUFF)
<<
$(PROGRAM).$(OBJSUFF): $(PROGRAM).$(SRCSUFF) $(PROGRAM).h listdb.h
$(cc) @<<
$(CPPFLAGS) /c /Fo$(*B).$(OBJSUFF) /Tp $(*B).$(SRCSUFF)
<<
$(PROGRAM).res: $(PROGRAM).rc $(WXDIR)\include\wx\msw\wx.rc
$(rc) -r /i$(WXDIR)\include -fo$@ $(PROGRAM).rc
clean:
-erase *.obj
-erase *.exe
-erase *.res
-erase *.map
-erase *.sbr
-erase *.pdb

71
samples/db/makefile.unx Normal file
View File

@@ -0,0 +1,71 @@
#
# File: makefile.unx
# Author: Terry Tompkins
# Created: 1998
# Updated:
# Copyright: (c) 1998, Remstar International
#
# Makefile for wxDB (UNIX).
OBJDIR=database
OBJSUFF=.o
SRCSUFF=.cpp
WXDIR = $(WXWIN)
# All common UNIX compiler flags and options are now in
# this central makefile.
include $(WXDIR)/src/make.env
PROGRAM=database
OBJECTS = $(OBJDIR)/$(PROGRAM).$(OBJSUFF) $(OBJDIR)/table.$(OBJSUFF) $(OBJDIR)/db.$(OBJSUFF) $(OBJDIR)/listdb.$(OBJSUFF)
.SUFFIXES:
all: $(OBJDIR) $(PROGRAM)$(GUISUFFIX)
wx:
motif:
$(MAKE) -f makefile.unx GUISUFFIX=_motif GUI=-Dwx_motif GUISUFFIX=_motif OPT='$(OPT)' LDLIBS='$(MOTIFLDLIBS)' WXLIB=$(WXDIR)/lib/libwx_motif.a OPTIONS='$(OPTIONS)' DEBUG='$(DEBUG)' WARN='$(WARN)' XLIB='$(XLIB)' XINCLUDE='$(XINCLUDE)' XVIEW_LINK=
xview:
cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx xview
$(MAKE) -f makefile.unx GUI=-Dwx_xview GUISUFFIX=_ol CC=$(CC) OPTIONS='$(OPTIONS)' DEBUG='$(DEBUG)' WARN='$(WARN)' XLIB='$(XLIB)' XINCLUDE='$(XINCLUDE)'
hp:
cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx hp
$(MAKE) -f makefile.unx GUI=-Dwx_motif GUISUFFIX=_hp CC=CC DEBUG='$(DEBUG)' WARN='-w' \
XINCLUDE='$(HPXINCLUDE)' XLIB='$(HPXLIB)' XVIEW_LINK='' LDLIBS='$(HPLDLIBS)'
$(OBJDIR):
mkdir $(OBJDIR)
$(PROGRAM)$(GUISUFFIX): $(DUMMYOBJ) $(DBLIBS) $(OBJECTS) $(WXLIB)
$(CC) $(LDFLAGS) -o $(PROGRAM)$(GUISUFFIX) $(OBJECTS) $(XVIEW_LINK) $(LDLIBS)
$(OBJDIR)/$(PROGRAM).$(OBJSUFF): $(PROGRAM).$(SRCSUFF)
$(CC) -c $(CPPFLAGS) -o $@ $(PROGRAM).$(SRCSUFF)
$(OBJDIR)/table.$(OBJSUFF): table.$(SRCSUFF)
$(CC) -c $(CPPFLAGS) -o $@ table.$(SRCSUFF)
$(OBJDIR)/db.$(OBJSUFF): db.$(SRCSUFF)
$(CC) -c $(CPPFLAGS) -o $@ db.$(SRCSUFF)
$(OBJDIR)/listdb.$(OBJSUFF): listdb.$(SRCSUFF)
$(CC) -c $(CPPFLAGS) -o $@ listdb.$(SRCSUFF)
clean_motif:
$(MAKE) -f makefile.unx GUISUFFIX=_motif cleanany
clean_ol:
$(MAKE) -f makefile.unx GUISUFFIX=_ol cleanany
clean_hp:
$(MAKE) -f makefile.unx GUISUFFIX=_hp cleanany
cleanany:
rm -f $(OBJECTS) $(PROGRAM)$(GUISUFFIX) core

View File

@@ -59,8 +59,8 @@ PlayerSelectionDialog::PlayerSelectionDialog(
0, 0, 0, 0,
wxLB_SINGLE wxLB_SINGLE
); );
/* #if 1
Robert Roebling // Robert Roebling
int numPlayers = 0; int numPlayers = 0;
wxString* players = 0; wxString* players = 0;
@@ -70,7 +70,7 @@ PlayerSelectionDialog::PlayerSelectionDialog(
list->Append(players[i]); list->Append(players[i]);
} }
delete players; delete players;
*/ #endif
m_textField = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxDefaultSize, 0); m_textField = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxDefaultSize, 0);

1320
src/common/db.cpp Normal file

File diff suppressed because it is too large Load Diff

1445
src/common/dbtable.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -74,6 +74,8 @@ GENERICOBJS= \
COMMONOBJS = \ COMMONOBJS = \
$(COMMDIR)\cmndata.obj \ $(COMMDIR)\cmndata.obj \
$(COMMDIR)\config.obj \ $(COMMDIR)\config.obj \
$(COMMDIR)\db.obj \
$(COMMDIR)\dbtable.obj \
$(COMMDIR)\docview.obj \ $(COMMDIR)\docview.obj \
$(COMMDIR)\dynarray.obj \ $(COMMDIR)\dynarray.obj \
$(COMMDIR)\event.obj \ $(COMMDIR)\event.obj \
@@ -722,6 +724,18 @@ $(COMMDIR)/config.obj: $*.$(SRCSUFF)
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF) /Fo$@ $(CPPFLAGS) /c /Tp $*.$(SRCSUFF) /Fo$@
<< <<
$(COMMDIR)/db.obj: $*.$(SRCSUFF)
echo $(CPPFLAGS)
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF) /Fo$@
<<
$(COMMDIR)/dbtable.obj: $*.$(SRCSUFF)
echo $(CPPFLAGS)
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF) /Fo$@
<<
$(COMMDIR)/docview.obj: $*.$(SRCSUFF) $(COMMDIR)/docview.obj: $*.$(SRCSUFF)
cl @<< cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF) /Fo$@ $(CPPFLAGS) /c /Tp $*.$(SRCSUFF) /Fo$@