home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Supreme Volume 6 #1
/
swsii.zip
/
swsii
/
215
/
DDJWIN.ZIP
/
SQL.ASC
< prev
next >
Wrap
Text File
|
1993-08-31
|
53KB
|
1,827 lines
_A GENERIC SQL CLASS LIBRARY_
by Ken North
[LISTING ONE]
///////////////////////////////////////////////////
// FILE NAME: dbObject.h TITLE: database class
// AUTHOR: Ken North Resource Group, Inc.
// 2604B El Camino Real, #351
// copyright(c)1992 Carlsbad, CA 92008
///////////////////////////////////////////////////
#ifndef __DBOBJECT_H
#define __DBOBJECT_H
class dbObject
{
int ReferenceTotal;
protected:
public:
dbObject();
virtual ~dbObject();
virtual void IncrementRefs();
virtual int DecrementRefs();
};
#endif
[LISTING TWO]
///////////////////////////////////////////////////
// FILE NAME: dbObject.cpp TITLE: base class
// AUTHOR: Ken North Resource Group, Inc.
// 2604B El Camino Real, #351
// copyright(c)1992 Carlsbad, CA 92008
///////////////////////////////////////////////////
// SYNOPSIS:
// implementation of dbObject class
///////////////////////////////////////////////////
#undef DEBUG
#undef DEBUG1
#include <windows.h>
#include <string.h>
#include "sql.h"
#include "sqlext.h"
#include "sqldefs.h"
#include "dbobject.h"
////////////////////////////////////////////////////
// FUNCTION NAME: dbObject
// SYNOPSIS:
// define dbObject, SQL base class constructor
////////////////////////////////////////////////////
dbObject :: dbObject()
{
ReferenceTotal = 1; // referenced by self
}
///////////////////////////////////////////////////
// FUNCTION NAME: ~dbObject
// define dbObject, SQL data base class destructor
///////////////////////////////////////////////////
dbObject :: ~dbObject()
{
// this is a point where error handler should be
// invoked if the reference total > 1 or < 0
// systemError();
}
////////////////////////////////////////////////////////////////////////
// FUNCTION NAME: IncrementRefs -- increment object reference total
////////////////////////////////////////////////////////////////////////
void dbObject :: IncrementRefs()
{
ReferenceTotal++;
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION NAME: IncrementRefs -- increment object reference total
//////////////////////////////////////////////////////////////////////////
int dbObject :: DecrementRefs()
{
// if the reference total < 0
// {
// systemError();
// }
return(--ReferenceTotal);
}
[LISTING THREE]
///////////////////////////////////////////////////
// FILE NAME: database.cpp TITLE: data base class
// AUTHOR: Ken North Resource Group, Inc.
// 2604B El Camino Real, #351
// copyright(c)1992 Carlsbad, CA 92008
// SYNOPSIS: implementation of database class
///////////////////////////////////////////////////
#undef DEBUG
#undef DEBUG1
#include <windows.h>
#include <string.h>
#include "sql.h"
#include "sqlext.h"
#include "gendefs.h"
#include "sqldefs.h"
#include "dbobject.h"
#include "sqldb.h"
#ifndef __RGSTRING_H
#include "rgstring.h"
#endif
HDBC dbDataBase::ODBCLinkHandle[]
= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int dbDataBase::nDefinedSources = 0;
int dbDataBase::ActiveLinks = 0;
char dbDataBase::DataSourceList[] = "None";
UCHAR dbDataBase::ODBCLinkList[] = "None";
/* standard return code for calls */
extern char ErrStat;
/* large / huge model */
extern char MemModel;
////////////////////////////////////////////////////
// FUNCTION NAME: dbDataBase
// SYNOPSIS: dbDataBase class constructor
////////////////////////////////////////////////////
dbDataBase::dbDataBase(HENV AppEnv)
: dbObject()
{
// save application environment handle
henv = AppEnv;
// initialize status and error info
StatusReturned = SQL_SUCCESS;
InitODBCErrorInfo();
}
///////////////////////////////////////////////////////////
// FUNCTION NAME: ~DataBase -- DataBase class destructor
//////////////////////////////////////////////////////////
dbDataBase :: ~dbDataBase()
{
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION NAME: InitODBCErrorInfo -- initialize ODBC error information
//////////////////////////////////////////////////////////////////////////
void dbDataBase::InitODBCErrorInfo()
{
err.ErrStatus = 0;
err.ErrorMsgLength = 0;
err.ErrorMsgMax = 0;
err.NativeError = 0;
memset(err.szSQLState,'\x0',
sizeof(err.szSQLState));
memset(err.ErrorMsg,'\x0',
sizeof(err.ErrorMsg));
}
/***************************************************
* FUNCTION NAME: MatchLinkName
* SYNOPSIS: scan the active link list (ODBCLinkList) to find
* the link that matches the selected link name
* (from disconnect dialog box)
*****************************************************/
int dbDataBase::MatchLinkName(UCHAR *LinkToDrop)
{
int tdx; /* link index */
int toff; /* link offset */
UCHAR NameToTest[LINK_NAME_LEN+1];
/* string position to begin search */
unsigned short StartPos=0;
/* position found: result of the search */
unsigned short SearchResult;
for (tdx=0;tdx < ActiveLinks;tdx++)
{
toff = tdx * LINK_NAME_LEN;
memset(NameToTest,'\x0',LINK_NAME_LEN+1);
substr_n((char *)ODBCLinkList,
(char *)NameToTest,
toff, LINK_NAME_LEN ) ;
SearchResult =
left_srch((char *)NameToTest,
(char *)LinkToDrop, StartPos);
if (ErrStat == SUCCESS)
{
return tdx;
}
}
return OOPS;
}
[LISTING FOUR]
////////////////////////////////////////////////////
// FILE NAME: connect.h TITLE: SQL connection
// AUTHOR: Ken North Resource Group, Inc.
// 2604B El Camino Real, #351
// copyright(c)1992 Carlsbad, CA 92008
////////////////////////////////////////////////////
#ifndef __CONNECT_H
#define __CONNECT_H
#ifndef __SQLDB_H
#include "sqldb.h"
#endif
#ifndef __DATASOUR_H
#include "datasour.h"
#endif
#ifndef __DBPROFIL_H
#include "dbprofil.h"
#endif
#ifndef __ODERROR_H
#include "oderror.h"
#endif
#ifndef __DSINFO_H
#include "DSInfo.h" /* data source information */
#endif
/* Connection is a child of data source */
class dbConnection : public dbDataSource
{
protected:
HENV henv;
POINTER cstr;
public:
RETCODE Status;
RETCODE ErrStatus;
HDBC hdbc;
UCHAR far *conec;
static UCHAR ConnectionString[CONECLEN];
static UCHAR szConnStrOut[CONECLEN];
/* the next two variables are used for situations */
/* where a connection's values are subsets of a */
/* data source's values */
SDWORD ConnTableCount; /* number of tables for this connection */
char ConnTableList[DS_TABLE_LIST_LEN];
dbConnection(HENV);
virtual ~dbConnection();
HDBC AllocateConnection(void);
POINTER BuildBrowseConnectString(char *);
virtual POINTER BuildConnectString(char *);
RETCODE BrowseConnect();
virtual RETCODE Connect(UCHAR *, UCHAR *);
virtual int Disconnect(UCHAR *);
RETCODE DriverConnect(UCHAR *);
void InitConnData(void);
void dbConnection::GetErrorInfo(void);
RETCODE PASCAL ProfileDataSource(DataSourceInfo *);
};
#endif
[LISTING FIVE]
///////////////////////////////////////////////////////////////////
// FILE NAME: connect.cpp TITLE: database connection
// AUTHOR: Ken North Resource Group, Inc.
// 2604B El Camino Real, #351
// copyright(c)1992 Carlsbad, CA 92008
///////////////////////////////////////////////////////////////////
// SYNOPSIS: implementation of SQL connection class
///////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <dos.h>
#include <malloc.h>
#include "sql.h"
#include "sqlext.h"
#include "sqldefs.h"
#include "gendefs.h"
#include "sqldb.h"
#include "dboption.h"
#include "oderror.h"
#ifndef __DATASOUR_H
#include "datasour.h"
#endif
#ifndef __DSINFO_H
#include "DSInfo.h" /* data source information */
#endif
#include "connect.h"
UCHAR dbConnection::ConnectionString[]="None";
UCHAR dbConnection::szConnStrOut[]="";
/* constructor for dbConnection class */
dbConnection::dbConnection(HENV AppEnv)
: dbDataSource(AppEnv)
{
henv = AppEnv; /* save environment handle */
InitODBCErrorInfo();
Status = SQL_SUCCESS;
}
///////////////////////////////////////////////////////////////////
// FUNCTION NAME: ~dbConnection
// SYNOPSIS: destructor for dbConnection
///////////////////////////////////////////////////////////////////
dbConnection::~dbConnection()
{
}
///////////////////////////////////////////////////////////////////
// FUNCTION NAME: AllocateConnection
// SYNOPSIS: allocates a connection handle
///////////////////////////////////////////////////////////////////
HDBC dbConnection::AllocateConnection()
{
/* get connection handle */
Status = SQLAllocConnect(henv, &hdbc);
if (Status != SQL_SUCCESS)
{
return NULL;
};
return hdbc;
}
///////////////////////////////////////////////////////////////////
// FUNCTION NAME: Connect
// SYNOPSIS: connect to SQL data source
///////////////////////////////////////////////////////////////////
RETCODE dbConnection::Connect(UCHAR *Userid, UCHAR *Password)
{
SWORD cbConnStrOut;
memset(ConnectionString,'\x0',sizeof(ConnectionString));
memset(szConnStrOut,'\x0',sizeof(szConnStrOut));
strcpy((char *)ConnectionString,"DSN=");
strncat((char *)ConnectionString,(char *)TrimmedDSName,
strlen((char *)TrimmedDSName));
/* ODBC driver connect */
Status = SQLDriverConnect (hdbc,
NULL,
ConnectionString,
SQL_NTS,
szConnStrOut,
CONECLEN,
&cbConnStrOut,
SQL_DRIVER_COMPLETE);
if (Status != SQL_SUCCESS)
{
/* ODBC connect */
Status = SQLConnect (hdbc,
DSName,
SQL_NTS,
Userid,
SQL_NTS,
Password,
SQL_NTS);
if (Status != SQL_SUCCESS)
{
err.ErrorMsgMax = SQL_MAX_MESSAGE_LENGTH - 1;
ErrStatus = SQLError(henv,
hdbc,
SQL_NULL_HSTMT,
&err.szSQLState[0],
&err.NativeError,
&err.ErrorMsg[0],
err.ErrorMsgMax,
&err.ErrorMsgLength);
}
}
ODBCLinkHandle[ActiveLinks] = hdbc; /* add handle to active list */
if (ActiveLinks < 1)
{
strncpy((char *)ODBCLinkList,(char *)DSName,
SQL_MAX_DSN_LENGTH);
}
else
{
strncat((char *)ODBCLinkList,(char *)DSName,sizeof(DSName));
}
ActiveLinks++;
return Status;
}
///////////////////////////////////////////////////////////////////
// FUNCTION NAME: BuildConnectString
// SYNOPSIS: build connection string for ODBC driver
// return far pointer to connection string
///////////////////////////////////////////////////////////////////
POINTER dbConnection::BuildConnectString(char *str)
{
UCHAR far *conec;
conec = (UCHAR far *) malloc(CONECLEN);
movedata(FP_SEG(str), FP_OFF(str),
FP_SEG(conec), FP_OFF(conec),
1+strlen(str));
return conec;
}
///////////////////////////////////////////////////////////////////
// FUNCTION NAME: Disconnect
// SYNOPSIS: terminate the SQL connection
///////////////////////////////////////////////////////////////////
int dbConnection::Disconnect(UCHAR *LinkToDrop)
{
int i;
int j;
int nLink; /* index to hdbc to drop */
int offset;
HDBC ConnHandle;
nLink = MatchLinkName(LinkToDrop);
if (nLink < 0)
{
return OOPS;
}
ConnHandle = ODBCLinkHandle[nLink];
/* ODBC disconnect */
Status = SQLDisconnect(ConnHandle);
if (Status)
return Status;
/* compress the list of active links and active handles */
for (i=nLink; i < ActiveLinks;i++)
{
ODBCLinkHandle[i] = ODBCLinkHandle[i+1];
}
offset = nLink * LINK_NAME_LEN;
j = offset;
while ( ODBCLinkList[j+LINK_NAME_LEN] != '\0')
{
ODBCLinkList[j] = ODBCLinkList[j+LINK_NAME_LEN];
j++;
}
ODBCLinkList[j] = '\0';
--ActiveLinks;
/* free conn handle */
Status = SQLFreeConnect(ConnHandle);
if (Status)
return Status;
return SQL_SUCCESS;
}
///////////////////////////////////////////////////////////////////
// FUNCTION NAME: ProfileDataSource
// SYNOPSIS: information about driver and data source
///////////////////////////////////////////////////////////////////
RETCODE PASCAL dbConnection::ProfileDataSource( DataSourceInfo *inf )
{
/* implementation of error handling is left to the user, since */
/* the user interface may vary. Using QuickWin or EasyWin, you can */
/* use printf statements. If you are writing a typical Windows app, */
/* you can use MessageBox or BWCCMessageBox to display errors */
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_DRIVER_NAME,
&inf->DriverName,
sizeof(inf->DriverName),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_ACTIVE_STATEMENTS,
(PTR)&inf->ActiveStatements,
sizeof(inf->ActiveStatements),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_ACTIVE_CONNECTIONS,
(PTR)&inf->ActiveConnections,
sizeof(inf->ActiveConnections),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_DRIVER_VER,
&inf->DriverVersion,
sizeof(inf->DriverVersion),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_SERVER_NAME,
&inf->ServerName,
sizeof(inf->ServerName),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_USER_NAME,
&inf->UserName,
sizeof(inf->UserName),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_ODBC_API_CONFORMANCE,
(PTR)&inf->ODBC_API_Level,
sizeof(inf->ODBC_API_Level),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_ODBC_SAG_CLI_CONFORMANCE,
(PTR)&inf->ODBC_SAG_Level,
sizeof(inf->ODBC_SAG_Level),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_ODBC_SQL_CONFORMANCE,
(PTR)&inf->ODBC_SQL_Level,
sizeof(inf->ODBC_SQL_Level),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_DATABASE_NAME,
&inf->DatabaseName,
sizeof(inf->DatabaseName),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_DBMS_NAME,
&inf->DBMSName,
sizeof(inf->DBMSName),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_DBMS_VER,
&inf->DBMSVersion,
sizeof(inf->DBMSVersion),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
/* IEF ? */
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_ODBC_SQL_OPT_IEF,
&inf->IEFSupport,
sizeof(inf->IEFSupport),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
/* Support Procedures ? */
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_PROCEDURES,
&inf->Procedures,
sizeof(inf->Procedures),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
/* detect changes in rows between fetches ? */
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_ROW_UPDATES,
&inf->RowUpdates,
sizeof(inf->RowUpdates),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
/* all tables accessible */
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_ACCESSIBLE_TABLES,
&inf->AccessibleTables,
sizeof(inf->AccessibleTables),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
if(inf->AccessibleProcedures[0] == 'Y')
{
/* all procedures accessible */
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_ACCESSIBLE_PROCEDURES,
&inf->AccessibleProcedures,
sizeof(inf->AccessibleProcedures),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_CONCAT_NULL_BEHAVIOR,
(PTR)&inf->ConcatNullBehavior,
sizeof(inf->ConcatNullBehavior),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_CURSOR_COMMIT_BEHAVIOR,
(PTR)&inf->CursorCommitBehavior,
sizeof(inf->CursorCommitBehavior),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_CURSOR_ROLLBACK_BEHAVIOR,
(PTR)&inf->CursorRollbackBehavior,
sizeof(inf->CursorRollbackBehavior),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_DATA_SOURCE_READ_ONLY,
&inf->DSReadOnly,
sizeof(inf->DSReadOnly),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_MAX_COLUMN_NAME_LEN,
(PTR)&inf->MaxColNameLen,
sizeof(inf->MaxColNameLen),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_MAX_CURSOR_NAME_LEN,
(PTR)&inf->MaxCursorNameLen,
sizeof(inf->MaxCursorNameLen),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_MAX_OWNER_NAME_LEN,
(PTR)&inf->MaxOwnerNameLen,
sizeof(inf->MaxOwnerNameLen),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_MAX_PROCEDURE_NAME_LEN,
(PTR)&inf->MaxProcedureNameLen,
sizeof(inf->MaxProcedureNameLen),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_MAX_QUALIFIER_NAME_LEN,
(PTR)&inf->MaxQualifierNameLen,
sizeof(inf->MaxQualifierNameLen),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_MAX_TABLE_NAME_LEN,
(PTR)&inf->MaxTableNameLen,
sizeof(inf->MaxTableNameLen),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_MULT_RESULT_SETS,
&inf->MultipleResultSets,
sizeof(inf->MultipleResultSets),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_MULTIPLE_ACTIVE_TXN,
&inf->MultipleActiveTransactions,
sizeof(inf->MultipleActiveTransactions),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_OUTER_JOINS,
&inf->OuterJoins,
sizeof(inf->OuterJoins),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_OWNER_TERM,
&inf->OwnerTerm,
sizeof(inf->OwnerTerm),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_PROCEDURE_TERM,
&inf->ProcTerm,
sizeof(inf->ProcTerm),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_QUALIFIER_TERM,
&inf->QualifierTerm,
sizeof(inf->QualifierTerm),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_EXPRESSIONS_IN_ORDERBY,
&inf->OrderBy,
sizeof(inf->OrderBy),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
Status = SQL_SUCCESS;
Status = SQLGetInfo(hdbc,
SQL_TXN_CAPABLE,
(PTR)&inf->TransCapable,
sizeof(inf->TransCapable),
NULL);
if (Status != SQL_SUCCESS)
{
GetErrorInfo();
}
if (Status != SQL_SUCCESS)
return Status;
return(SQL_SUCCESS);
}
///////////////////////////////////////////////////////////////////
// FUNCTION NAME: GetErrorInfo
// SYNOPSIS: check SQLError info
///////////////////////////////////////////////////////////////////
void dbConnection::GetErrorInfo()
{
/* implementation of error handling is left to the user, since */
/* the user interface may vary. Using QuickWin or EasyWin, you can */
/* use printf statements. If you are writing a typical Windows app, */
/* you can use MessageBox or BWCCMessageBox to display errors */
err.ErrorMsgMax = SQL_MAX_MESSAGE_LENGTH - 1;
ErrStatus = SQLError(henv,
hdbc,
SQL_NULL_HSTMT,
&err.szSQLState[0],
&err.NativeError,
&err.ErrorMsg[0],
err.ErrorMsgMax,
&err.ErrorMsgLength);
}
///////////////////////////////////////////////////
// FUNCTION NAME: InitConnData
// SYNOPSIS: initialize conn data
///////////////////////////////////////////////////
void dbConnection::InitConnData()
{
Status = 0;
ErrStatus = 0;
cstr = NULL;
ConnTableCount = 0;
memset(ConnectionString,'\x0',sizeof(ConnectionString));
memset(ConnTableList,'\x0',sizeof(ConnTableList));
}
[LISTING SIX]
///////////////////////////////////////////////////
// FILE NAME: request.h TITLE: SQL request
// AUTHOR: Ken North Resource Group, Inc.
// 2604B El Camino Real, #351
// copyright(c)1992 Carlsbad, CA 92008
///////////////////////////////////////////////////
#ifndef __REQUEST_H
#define __REQUEST_H
#ifndef __CONNECT_H
#include "connect.h"
#endif
#ifndef __DBOPTION_H
#include "dboption.h"
#endif
#ifndef __RQOPTION_H
#include "rqoption.h"
#endif
#ifndef __TABLESET_H
#include "tableset.h"
#endif
// dbRequest is a child of dbConnection
class dbRequest : public dbConnection {
protected:
UCHAR Statement[MAXSQL];
UCHAR *stmt;
RETCODE Status;
// exceeds max statement length for d.b. driver
BOOL ExceedsMax;
HENV henv;
HSTMT hAStmt;
CURNAME ACursor; /* for named cursors */
UCHAR CursorName[CURSOR_NAME_LEN];
public:
UCHAR far *stptr;
HSTMT hstmt;
DataBaseOptions *dbopt; // options for this database
RequestOptions OptionInfo; // options for this request
dbRequest(HENV, HDBC, DataBaseOptions *, UCHAR *);
virtual ~dbRequest();
virtual HSTMT AllocateStatement(HDBC);
virtual POINTER BuildRequest(BOOL);
virtual RETCODE ExecuteStatement(POINTER);
virtual SWORD FindNumberOfColumns(HSTMT);
virtual CURNAME GetCursorforRequest(HDBC);
SDWORD GetTableList(char *);
void InitTableResultSet(TableResultSet *);
virtual int TerminateStatement(HSTMT);
};
#endif
[LISTING SEVEN]
/////////////////////////////////////////////////////////////////////
// FILE NAME: request.cpp TITLE: SQL request
// AUTHOR: Ken North Resource Group, Inc.
// 2604B El Camino Real, #351
// copyright(c)1992 Carlsbad, CA 92008
/////////////////////////////////////////////////////////////////////
// SYNOPSIS: SQL request class
/////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "sql.h"
#include "sqlext.h"
#include "gendefs.h"
#include "sqldefs.h"
#include "sqldb.h"
#include "connect.h"
#include "dboption.h" /* database options */
#ifndef __ODERROR_H
#include "oderror.h"
#endif
#ifndef __RGSTRING_H
#include "rgstring.h"
#endif
#include "request.h"
extern char ErrStat; /* return code for string calls */
extern char MemModel; /* large / huge model */
/* Constructor for the 'Request' class: */
dbRequest :: dbRequest( HENV envhandle,
HDBC connhandle,
DataBaseOptions *opt,
UCHAR *SQLstring )
: dbConnection(envhandle)
{
// save SQL string and options
dbopt = opt;
strcpy((char *)Statement,(char *)SQLstring);
stmt = &Statement[0];
// set request environment handle
henv = envhandle;
// set request connection handle
hdbc = connhandle;
}
/////////////////////////////////////////////////////////////////////
// FUNCTION NAME: ~dbRequest
// SYNOPSIS: destructor
/////////////////////////////////////////////////////////////////////
dbRequest::~dbRequest()
{
free(stptr);
}
/////////////////////////////////////////////////////////////////////
// FUNCTION NAME: BuildRequest
// SYNOPSIS: prepare an SQL request
/////////////////////////////////////////////////////////////////////
POINTER dbRequest::BuildRequest( BOOL ExceedsMax )
{
if (dbopt->AllocStmtHandle)
{
hAStmt = AllocateStatement(hdbc);
}
if (OptionInfo.UseCursor)
{
ACursor = GetCursorforRequest(hdbc);
}
stptr = (UCHAR far *) malloc(MAXSQL);
movedata(FP_SEG(stmt), FP_OFF(stmt),
FP_SEG(stptr), FP_OFF(stptr),
1+strlen((char *)stmt));
return stptr;
}
/////////////////////////////////////////////////////////////////////
// FUNCTION NAME: ExecuteStatement
// SYNOPSIS: executes a direct or prepared request
/////////////////////////////////////////////////////////////////////
RETCODE dbRequest::ExecuteStatement( POINTER stptr )
{
Status = SQLExecDirect (hAStmt,
stptr,
SQL_NTS );
if (Status != SQL_SUCCESS)
{
return Status;
};
return SQL_SUCCESS;
}
/////////////////////////////////////////////////////////////////////
// FUNCTION NAME: FindNumberOfColumns
// SYNOPSIS: get the number of columns in the request
/////////////////////////////////////////////////////////////////////
SWORD dbRequest::FindNumberOfColumns( HSTMT hstmt )
{
SWORD n;
Status = SQLNumResultCols (hAStmt, &n);
if (Status != SQL_SUCCESS)
{
return Status;
};
return n;
}
/////////////////////////////////////////////////////////////////////
// FUNCTION NAME: GetTableList
// SYNOPSIS: get the tables for this SQL data source
/////////////////////////////////////////////////////////////////////
SDWORD dbRequest::GetTableList(char *TableList)
{
SDWORD nTables=0;
SDWORD QualifierLength;
SDWORD OwnerLength;
SDWORD NameLength;
SDWORD TypeLength;
SDWORD RemarksLength;
UCHAR FAR *szTableQualifier=NULL;
SWORD cbTableQualifier=0;
UCHAR FAR *szTableOwner=NULL;
SWORD cbTableOwner=0;
UCHAR FAR *szTableName=NULL;
SWORD cbTableName=0;
UCHAR FAR *szTableType=NULL;
SWORD cbTableType=0;
TableResultSet *rset;
char NameString[TABLE_NAME_LEN+1];
rset = new(TableResultSet);
if(!rset)
return NO_MEMORY;
InitTableResultSet(rset);
Status = SQL_SUCCESS;
ErrStatus = 0;
Status = SQLTables( hstmt,
szTableQualifier,
cbTableQualifier,
szTableOwner,
cbTableOwner,
szTableName,
cbTableName,
szTableType,
cbTableType);
if(Status == SQL_ERROR)
{
err.ErrorMsgMax = SQL_MAX_MESSAGE_LENGTH - 1;
ErrStatus = SQLError(henv,
hdbc,
SQL_NULL_HSTMT,
&err.szSQLState[0],
&err.NativeError,
&err.ErrorMsg[0],
err.ErrorMsgMax,
&err.ErrorMsgLength);
if (ErrStatus < 1)
return Status;
}
Status = SQL_SUCCESS;
Status=SQLBindCol(hstmt, 1, SQL_C_CHAR,
&rset->TABLE_QUALIFIER,
sizeof(rset->TABLE_QUALIFIER), &QualifierLength);
if(Status == SQL_ERROR)
{
err.ErrorMsgMax = SQL_MAX_MESSAGE_LENGTH - 1;
ErrStatus = SQLError(henv,
hdbc,
SQL_NULL_HSTMT,
&err.szSQLState[0],
&err.NativeError,
&err.ErrorMsg[0],
err.ErrorMsgMax,
&err.ErrorMsgLength);
if (ErrStatus < 1)
return Status;
}
Status = SQL_SUCCESS;
ErrStatus = 0;
Status=SQLBindCol(hstmt, 2, SQL_C_CHAR,
&rset->TABLE_OWNER,
sizeof(rset->TABLE_OWNER), &OwnerLength);
if(Status == SQL_ERROR)
{
err.ErrorMsgMax = SQL_MAX_MESSAGE_LENGTH - 1;
ErrStatus = SQLError(henv,
hdbc,
SQL_NULL_HSTMT,
&err.szSQLState[0],
&err.NativeError,
&err.ErrorMsg[0],
err.ErrorMsgMax,
&err.ErrorMsgLength);
if (ErrStatus < 1)
return Status;
}
Status = SQL_SUCCESS;
ErrStatus = 0;
Status=SQLBindCol(hstmt, 3, SQL_C_CHAR,
&rset->TABLE_NAME,
sizeof(rset->TABLE_NAME), &NameLength);
if(Status == SQL_ERROR)
{
err.ErrorMsgMax = SQL_MAX_MESSAGE_LENGTH - 1;
ErrStatus = SQLError(henv,
hdbc,
SQL_NULL_HSTMT,
&err.szSQLState[0],
&err.NativeError,
&err.ErrorMsg[0],
err.ErrorMsgMax,
&err.ErrorMsgLength);
if (ErrStatus < 1)
return Status;
}
Status = SQL_SUCCESS;
ErrStatus = 0;
Status=SQLBindCol(hstmt, 4, SQL_C_CHAR,
&rset->TABLE_TYPE,
sizeof(rset->TABLE_TYPE), &TypeLength);
if(Status == SQL_ERROR)
{
err.ErrorMsgMax = SQL_MAX_MESSAGE_LENGTH - 1;
ErrStatus = SQLError(henv,
hdbc,
SQL_NULL_HSTMT,
&err.szSQLState[0],
&err.NativeError,
&err.ErrorMsg[0],
err.ErrorMsgMax,
&err.ErrorMsgLength);
if (ErrStatus < 1)
return Status;
}
Status = SQL_SUCCESS;
ErrStatus = 0;
Status=SQLBindCol(hstmt, 5, SQL_C_CHAR,
&rset->REMARKS,
sizeof(rset->REMARKS), &RemarksLength);
if(Status == SQL_ERROR)
{
err.ErrorMsgMax = SQL_MAX_MESSAGE_LENGTH - 1;
ErrStatus = SQLError(henv,
hdbc,
SQL_NULL_HSTMT,
&err.szSQLState[0],
&err.NativeError,
&err.ErrorMsg[0],
err.ErrorMsgMax,
&err.ErrorMsgLength);
if (ErrStatus < 1)
return Status;
}
/* Loop to fetch data for SQLTables */
while (Status != SQL_NO_DATA_FOUND)
{
InitTableResultSet(rset);
Status = SQL_SUCCESS;
ErrStatus = 0;
Status = SQLFetch(hstmt);
if(Status == SQL_ERROR)
{
err.ErrorMsgMax = SQL_MAX_MESSAGE_LENGTH - 1;
ErrStatus = SQLError(henv,
hdbc,
SQL_NULL_HSTMT,
&err.szSQLState[0],
&err.NativeError,
&err.ErrorMsg[0],
err.ErrorMsgMax,
&err.ErrorMsgLength);
if (ErrStatus < 1)
return Status;
}
strcpy(NameString,(char *)rset->TABLE_NAME);
right_fill(NameString,SPACE,TABLE_NAME_LEN);
strncat(TableList,NameString,TABLE_NAME_LEN);
nTables++;
}
return nTables;
}
/////////////////////////////////////////////////////////////////////
// FUNCTION NAME: InitTableResultSet
// SYNOPSIS: initialize result set for GetTables
/////////////////////////////////////////////////////////////////////
void dbRequest::InitTableResultSet(TableResultSet *rs)
{
memset(rs->TABLE_QUALIFIER,'\x0',sizeof(rs->TABLE_QUALIFIER));
memset(rs->TABLE_OWNER,'\x0',sizeof(rs->TABLE_OWNER));
memset(rs->TABLE_NAME,'\x0',sizeof(rs->TABLE_NAME));
memset(rs->TABLE_TYPE,'\x0',sizeof(rs->TABLE_TYPE));
memset(rs->REMARKS,'\x0',sizeof(rs->REMARKS));
}
/////////////////////////////////////////////////////////////////////
// FUNCTION NAME: TerminateStatement
// SYNOPSIS: terminate the statement
/////////////////////////////////////////////////////////////////////
RETCODE dbRequest::TerminateStatement(HSTMT hstmt)
{
Status = SQLFreeStmt(hstmt, SQL_DROP);
if (Status)
return Status;
else
return SQL_SUCCESS;
}
/////////////////////////////////////////////////////////////////////
// FUNCTION NAME: AllocateStatement
// SYNOPSIS: allocates a statement handle
/////////////////////////////////////////////////////////////////////
HSTMT dbRequest::AllocateStatement(HDBC hdbc)
{
Status = SQLAllocStmt(hdbc, &hstmt);
if (Status != SQL_SUCCESS)
{
return NULL;
};
return hstmt;
}
/////////////////////////////////////////////////////////////////////
// FUNCTION NAME: GetCursorforRequest
// SYNOPSIS: gets a cursor for this request
/////////////////////////////////////////////////////////////////////
CURNAME dbRequest::GetCursorforRequest(HDBC hdbc)
{
return NULL;
}
[LISTING EIGHT]
/////////////////////////////////////////////////////////////////////
// FILE NAME: column.h TITLE: SQL column class
// AUTHOR: Ken North Resource Group, Inc.
// 2604B El Camino Real, #351
// copyright(c)1992 Carlsbad, CA 92008
/////////////////////////////////////////////////////////////////////
#ifndef __COLUMN_H
#define __COLUMN_H
#ifndef __DBOPTION_H
#include "dboption.h"
#endif
#ifndef __REQUEST_H
#include "request.h"
#endif
#ifndef __COLDESC_H
#include "coldesc.h"
#endif
/* 'dbColumn' is a child of 'dbRequest' */
class dbColumn : public dbRequest {
protected:
HSTMT hstmt;
public:
RETCODE Status;
/* column info for this request */
ColumnDesc ColumnInfo[MAXFIELD];
dbColumn(HENV, HDBC, DataBaseOptions *, HSTMT, UCHAR *, UWORD);
virtual ~dbColumn();
virtual int Describe(UWORD, ColumnDesc *);
virtual char * DecodeODBCDataType(SWORD);
};
#endif
[LISTING NINE]
/////////////////////////////////////////////////////////////////////
// FILE NAME: column.cpp TITLE: database column
// AUTHOR: Ken North Resource Group, Inc.
// 2604B El Camino Real, #351
// copyright(c)1992 Carlsbad, CA 92008
//
/////////////////////////////////////////////////////////////////////
// SYNOPSIS: implementation of SQL column class
/////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "sql.h"
#include "sqlext.h"
#include "sqldefs.h"
#include "sqldb.h"
#include "connect.h"
#include "dboption.h"
#include "rqoption.h"
#include "request.h"
#include "column.h"
/* Constructor for the 'dbColumn' class: */
dbColumn :: dbColumn( HENV envhandle,
HDBC connhandle,
DataBaseOptions *opt,
HSTMT hStatement,
UCHAR *SQLstring,
UWORD ColumnPosition )
: dbRequest( envhandle, connhandle, opt, SQLstring)
{
hstmt = hStatement;
}
/////////////////////////////////////////////////////////////////////
// FUNCTION NAME: ~dbColumn
// SYNOPSIS: destructor for dbColumn
/////////////////////////////////////////////////////////////////////
dbColumn::~dbColumn()
{
}
/////////////////////////////////////////////////////////////////////
// FUNCTION NAME: Describe
// SYNOPSIS: get a column description
/////////////////////////////////////////////////////////////////////
RETCODE dbColumn::Describe( UWORD ColumnPosition, ColumnDesc *fi)
{
UCHAR FAR *col;
SWORD NameBufLen=NAMELENGTH;
SWORD ncount;
/* get the column name, type, width, etc. */
Status = SQLDescribeCol ( hstmt,
ColumnPosition,
&fi->Name[0],
NameBufLen,
&ncount,
&fi->DataType,
&fi->Precision,
&fi->Scale,
&fi->Nullable);
if (Status != SQL_SUCCESS)
{
return Status;
}
return SQL_SUCCESS;
}
/////////////////////////////////////////////////////////////////////
// FUNCTION NAME: DecodeODBCDataType
// SYNOPSIS: return description of data type
/////////////////////////////////////////////////////////////////////
char *dbColumn::DecodeODBCDataType(SWORD DataType)
{
static char Type[20];
strcpy((char *)Type,"Unknown");
if (DataType == SQL_CHAR)
strcpy((char *)Type,"character");
if (DataType == SQL_VARCHAR)
strcpy((char *)Type,"variable len char");
if (DataType == SQL_LONGVARCHAR)
strcpy((char *)Type,"long variable char");
if (DataType == SQL_DECIMAL)
strcpy((char *)Type,"decimal");
if (DataType == SQL_NUMERIC)
strcpy((char *)Type,"numeric");
if (DataType == SQL_BIT)
strcpy((char *)Type,"bit");
if (DataType == SQL_TINYINT)
strcpy((char *)Type,"tiny integer");
if (DataType == SQL_SMALLINT)
strcpy((char *)Type,"small integer");
if (DataType == SQL_INTEGER)
strcpy((char *)Type,"integer");
if (DataType == SQL_BIGINT)
strcpy((char *)Type,"big integer");
if (DataType == SQL_REAL)
strcpy((char *)Type,"real");
if (DataType == SQL_FLOAT)
strcpy((char *)Type,"float");
if (DataType == SQL_DOUBLE)
strcpy((char *)Type,"double");
if (DataType == SQL_BINARY)
strcpy((char *)Type,"binary");
if (DataType == SQL_VARBINARY)
strcpy((char *)Type,"variable binary");
if (DataType == SQL_LONGVARBINARY)
strcpy((char *)Type,"long variable binary");
if (DataType == SQL_DATE)
strcpy((char *)Type,"date");
if (DataType == SQL_TIME)
strcpy((char *)Type,"time");
if (DataType == SQL_TIMESTAMP)
strcpy((char *)Type,"timestamp");
return Type;
}
[LISTING TEN]
///////////////////////////////////////////////////
// FILE NAME: blob.h TITLE: SQL blob class
// AUTHOR: Ken North Resource Group, Inc.
// 2604B El Camino Real, #351
// copyright(c)1992 Carlsbad, CA 92008
///////////////////////////////////////////////////
#ifndef __BLOB_H
#define __BLOB_H
#ifndef __DBOPTION_H
#include "dboption.h"
#endif
#ifndef __REQUEST_H
#include "request.h"
#endif
/* 'dbBlob' is a child of 'dbRequest' */
class dbBlob : public dbRequest {
protected:
HSTMT hstmt;
public:
RETCODE Status;
dbBlob(HENV, HDBC, DataBaseOptions *, HSTMT, UCHAR *);
virtual ~dbBlob();
};
#endif
[LISTING ELEVEN]
///////////////////////////////////////////////////
// FILE NAME: blob.cpp TITLE: database blob
// AUTHOR: Ken North Resource Group, Inc.
// 2604B El Camino Real, #351
// copyright(c)1992 Carlsbad, CA 92008
// SYNOPSIS: implementation of SQL blob class
///////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "sql.h"
#include "sqlext.h"
#include "sqldefs.h"
#include "sqldb.h"
#include "connect.h"
#include "dboption.h"
#include "rqoption.h"
#include "request.h"
#include "blob.h"
/* Constructor for the 'dbBLOB' class: */
dbBlob :: dbBlob( HENV envhandle,
HDBC connhandle,
DataBaseOptions *opt,
HSTMT hStatement,
UCHAR *SQLstring)
: dbRequest( envhandle, connhandle, opt, SQLstring)
{
hstmt = hStatement;
}
///////////////////////////////////////////////////
// FUNCTION NAME: ~dbBLOB
// SYNOPSIS: destructor for dbBLOB
///////////////////////////////////////////////////
dbBlob::~dbBlob()
{
}
[LISTING TWELVE]
///////////////////////////////////////////////////////////////////
// FILE NAME: SQLstruc.cpp TITLE: SQL data dictionary
// AUTHOR: Ken North Resource Group, Inc., 2604B El Camino Real, #351
// copyright(c)1992 Carlsbad, CA 92008
// SYNOPSIS: display dictionary (structure) info for SQL table
///////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <windows.h>
#include "qeapi.h"
#ifndef __QEDEFS_H
#include "qedefs.h" /* QELIB definitions */
#endif
#ifndef __SQLDB_H
#include "sqldb.h" /* database class */
#endif
#ifndef __CONNECT_H
#include "connect.h"
#endif
#ifndef __RQOPTION_H
#include "rqoption.h" /* request options */
#endif
#ifndef __DATASRC_H
#include "datasrc.h" /* data source */
#endif
#ifndef __REQUEST_H
#include "request.h"
#endif
#ifndef __COLUMN_H
#include "column.h"
#endif
#ifndef __BLOB_H
#include "blob.h"
#endif
#ifndef __COLDESC_H
#include "coldesc.h" /* column or field description */
#endif
#include "sqlstruc.h"
static char DBDriver [9];
static char DBDictPath[80];
static char DBTable[31];
static char DBUserid[31];
static char DBPassword[PASSWORDLEN];
static char SQLString[MAXSQL];
static char FldName[DISPLAYLEN+1];
char *driver;
char *table;
char *dict;
char *userid;
char *password;
ColumnDesc *fi;
void main (int argc, char *argv[])
{
dbDataBase *db;
dbConnection *connection;
dbRequest *request;
dbColumn *column;
dbBlob *BLOB;
HSTMT hstmt;
POINTER statement;
// exceeds max SQL stmt. length
BOOL ExceedsMax=FALSE;
int nColumns; /* number of columns */
int ColumnPosition;
int ColumnCount;
int flen; /* string length of field name */
int i; /* blank fill loop index */
int TotalLength; /* sum of field lengths */
char *ColumnDataType;
memset(DBDriver,'\x0',sizeof(DBDriver));
memset(DBDictPath,'\x0',sizeof(DBDictPath));
memset(DBTable,'\x0',sizeof(DBTable));
memset(DBUserid,'\x0',sizeof(DBUserid));
memset(DBPassword,'\x0',sizeof(DBPassword));
memset(SQLString,'\x0',sizeof(SQLString));
/* point to strings */
table = &DBTable[0];
dict = &DBDictPath[0];
driver = &DBDriver[0];
userid = &DBUserid[0];
password = &DBPassword[0];
/* data source includes a driver and path */
/* Using ODBC, data source info is in a file */
/* For this example, prompt for relevant info */
DataSource source;
memset(source.DBDictPath,'\x0',sizeof(source.DBDictPath));
memset(source.DBDataPath,'\x0',sizeof(source.DBDataPath));
memset(source.DBDriver,'\x0',sizeof(source.DBDriver));
memset(source.DBUserid,'\x0',sizeof(source.DBUserid));
memset(source.DBDataBase,'\x0',sizeof(source.DBDataBase));
memset(source.DBServer,'\x0',sizeof(source.DBServer));
db = new(dbDataBase);
db->StatusReturned = SQL_SUCCESS;
/* define options for this database */
db->Options.AllocConnHandle = FALSE;
db->Options.AllocEnvHandle = FALSE;
db->Options.AllocStmtHandle = FALSE;
db->Options.UseCursor = FALSE;
db->opt = &db->Options; /* point to database options */
GetArgs(argc,argv[1],argv[2],argv[3],
table,dict,driver);
/* make selection of database type */
strcpy (source.DBDriver, driver);
/* for dBASE and Paradox databases, the table structure */
/* or dictionary info is in the same directory as data */
strcpy (source.DBDictPath, DBDictPath);
strcpy (source.DBDataPath, DBDictPath);
/*****************************/
/* connect to datasource */
/*****************************/
connection = new(dbConnection);
connection->hdbc = connection->Connect( source, password );
if ((connection->hdbc == NOHANDLE))
{
printf ("\n<SQLStruc> ERROR %d: Unable to connect to %s",
connection->hdbc, source.DBDriver);
exit (1);
}
/*****************************/
/* statement / request */
/*****************************/
strcpy(SQLString,"SELECT * FROM ");
strcat(SQLString,source.DBDataPath);
/* terminate the SQL string */
SQLString[strlen(SQLString)] = '\x5c';
strcat(SQLString,DBTable);
request = new dbRequest(connection->hdbc, db->opt, SQLString);
/* define options for this request */
request->OptionInfo.UseDirectExec = TRUE;
request->OptionInfo.UseNamedCursor = FALSE;
request->OptionInfo.UseTransaction = FALSE;
/* build a valid SQL request/statement string */
/* Note: statement length may be an issue in some */
/* SQL libraries */
statement =
request->BuildRequest(ExceedsMax);
request->hstmt = request->ExecuteStatement(statement);
nColumns = request->FindNumberOfColumns(request->hstmt);
ColumnPosition = 0;
ColumnCount = 0;
TotalLength = 0;
column = new dbColumn( connection->hdbc, db->opt,
request->hstmt, SQLString, ColumnPosition);
/************************/
/* get description */
/************************/
printf ("\nStructure for table: %s\n", DBTable);
printf ("Field Field Name Type Width Dec\n");
db->StatusReturned = SQL_SUCCESS;
do
{
/* point to column descriptor */
fi = &column->ColumnInfo[ColumnPosition];
db->StatusReturned = SQL_SUCCESS;
db->StatusReturned =
column->Describe(ColumnPosition+1, fi);
if ((db->StatusReturned != SQL_SUCCESS))
{
if (db->StatusReturned == ENDFILE)
{
break;
}
else
{
printf
("\n<SQLStruc> ERROR: getting column data for
%s\n", SQLString);
exit (1);
}
};
ColumnCount++; /* update field count */
TotalLength +=
column->ColumnInfo[ColumnPosition].Length;
/* data type is specific to the SQL library */
ColumnDataType = column->DecodeQEDataType(fi->DataType);
strcpy(FldName,fi->Name);
flen = strlen(fi->Name);
for ( i=flen; i < DISPLAYLEN; i++ );
{
FldName[i]='\x20';
}
FldName[DISPLAYLEN]='\x0';
printf ("\n %3d %20.20s %12.12s %5d %2d", ColumnCount,
FldName, ColumnDataType,
fi->Length, fi->Scale);
ColumnPosition++;
}
while (ColumnPosition < nColumns);
printf ("\nTotal: %d\n",TotalLength);
// terminate request
db->StatusReturned =
request->TerminateStatement(request->hstmt);
/************************/
/* disconnect */
/************************/
db->StatusReturned = connection->Disconnect();
if ((db->StatusReturned != SQL_SUCCESS))
{
printf ("\n<SQLStruc> ERROR %d: Disconnecting from %s",
db->StatusReturned, source.DBDriver);
exit (1);
}
}
/**************************************************
* FUNCTION NAME: GetArgs
* AUTHOR: Ken North
* SYNOPSIS: get table name and dictionary path from command line or user
***************************************************/
void GetArgs(int argc, char *arg1, char *arg2,
char *arg3, char *table, char *dict, char *driver)
{
static char name [80];
if (argc > 1)
{
memset(name,'\x0',sizeof(name));
if (*arg1 == '?')
{
printf("\n Usage: SQLSTRUC table \
dictionarypath\n");
printf ("\n SQLSTRUC SQL \
data definitions\n");
printf(" (Requires QELIB DLL\
or QExxx.DLL)\n\n");
printf
(" To display a data dictionary screen, \
type:\n");
printf
(" SQLSTRUC table dictpath driver| \
MORE\n\n");
printf
(" To list to a file, type:\n");
printf
(" SQLSTRUC table dictpath driver> \
listfile\n\n\n");
exit(1);
}
strcpy (name, arg1);
strupr (name); /* translate to upper case */
strcpy(table,name) ; /* copy name to table */
memset(name,'\x0',sizeof(name));
}
if (argc > 2)
{
strcpy (name, arg2);
strupr (name); /* translate to upper case */
strcpy(dict,name) ;
memset(name,'\x0',sizeof(name));
}
if (argc > 3)
{
strcpy (name, arg3);
strupr (name); /* translate to upper case */
strcpy(driver,name) ;
}
if (argc < 2)
{
printf ("Table name ? ");
gets (name);
strupr (name); /* translate to upper case */
strcpy(table,name) ;
memset(name,'\x0',sizeof(name)); /* zero name */
printf ("Dictionary pathname ? ");
gets (name);
strupr (name);
strcpy(dict,name) ;
memset(name,'\x0',sizeof(name)); /* zero name */
printf ("Database driver ? ");
gets (name);
strupr (name);
strcpy(driver,name) ;
}
}