home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR24
/
DRGRND.ZIP
/
DBACCESS.C
next >
Wrap
C/C++ Source or Header
|
1993-07-18
|
18KB
|
396 lines
/*********************************************************************
* *
* MODULE NAME : dbaccess.c AUTHOR: Rick Fishman *
* DATE WRITTEN: 07-16-93 *
* *
* MODULE DESCRIPTION: *
* *
* Part of the 'DRGRENDR' drag/drop sample program. *
* *
* Access module that provides functions to access the data in the *
* 'database'. *
* *
* NOTES: *
* *
* This 'database' is structured with multiple dbase_?.db files *
* that each have multiple database 'tables'. Each table is marked *
* by a TABLEKEY=> line that provides a table name. Following that *
* line are the rows of that table. The table is delimited by *
* the next TABLEKEY=> line. The file is delimited by this line: *
* *
* TABLEKEY=>end_of_database *
* *
* Yes, IBM has been after me to incorporate this amazing database *
* technology into their mainframe databases <g>.... NOT! *
* *
* Have a look at the dbase_?.db files that were supplied with this *
* sample for further clarification. *
* *
* FUNCTIONS AVALABLE TO OTHER MODULES: *
* *
* dbBeginEnumTables *
* dbGetNextTable *
* dbEndEnumTables *
* dbRenderToFile *
* *
* *
* HISTORY: *
* *
* 07-16-93 - Program coding started. *
* *
* Rick Fishman *
* Code Blazers, Inc. *
* 4113 Apricot *
* Irvine, CA. 92720 *
* CIS ID: 72251,750 *
* *
*********************************************************************/
#pragma strings(readonly) // used for debug version of memory mgmt routines
/*********************************************************************/
/*------- Include relevant sections of the OS/2 header files --------*/
/*********************************************************************/
#define INCL_DOSERRORS
#define INCL_DOSFILEMGR
#define INCL_WINSTDCNR
/**********************************************************************/
/*----------------------------- INCLUDES -----------------------------*/
/**********************************************************************/
#include <os2.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "drgrendr.h"
/*********************************************************************/
/*------------------- APPLICATION DEFINITIONS -----------------------*/
/*********************************************************************/
#define DATABASE_FILESPEC "dbase_?.db" // File spec for database files
#define TABLEKEY_LITERAL "TABLEKEY=>" // On first line of each table
#define DB_END_LITERAL "end_of_database" // Marks end of database file
/**********************************************************************/
/*---------------------------- STRUCTURES ----------------------------*/
/**********************************************************************/
/**********************************************************************/
/*----------------------- FUNCTION PROTOTYPES ------------------------*/
/**********************************************************************/
/**********************************************************************/
/*------------------------ GLOBAL VARIABLES --------------------------*/
/**********************************************************************/
/**********************************************************************/
/*------------------------ dbBeginEnumTables -------------------------*/
/* */
/* START AN ENUMERATON OF THE DATABASE TABLE NAMES. */
/* */
/* PARMS: nothing */
/* */
/* NOTES: We open the first 'database' file that we find in the */
/* current directory and fill in information into our */
/* ENUMSTRUCT structure. We will pass a pointer to this */
/* structure back to the caller. This pointer will be used */
/* as an 'enum handle' for further calls to the enumeration */
/* functions. */
/* */
/* RETURNS: HENUMTABLES handle for accessing the enumeration */
/* */
/*--------------------------------------------------------------------*/
/**********************************************************************/
HENUMTABLES dbBeginEnumTables()
{
HENUMTABLES henum = (HENUMTABLES) malloc( sizeof( ENUMSTRUCT ) );
if( henum )
{
FILEFINDBUF3 ffb;
APIRET rc;
ULONG cFiles = 1;
(void) memset( henum, 0, sizeof henum );
henum->hdir = HDIR_SYSTEM;
rc = DosFindFirst( DATABASE_FILESPEC, &henum->hdir, FILE_NORMAL,
&ffb, sizeof ffb, &cFiles, FIL_STANDARD );
if( rc )
{
free( henum );
henum = NULL;
}
else
{
henum->stream = fopen( ffb.achName, "r" );
if( henum->stream )
{
PCH pchDot = strchr( ffb.achName, '.' );
if( pchDot )
*pchDot = 0;
strcpy( henum->szFileName, ffb.achName );
}
else
{
(void) DosFindClose( henum->hdir );
free( henum );
henum = NULL;
}
}
}
else
Msg( "Out of memory in dbBeginEnumTables!" );
return henum;
}
/**********************************************************************/
/*------------------------- dbGetNextTable ---------------------------*/
/* */
/* GET THE NEXT TABLE NAME IN THE ENUMERATION. */
/* */
/* PARMS: HENUMTABLES handle of the enumeration, */
/* */
/* NOTES: Find the next 'table' in the enumerated databases. The */
/* beginning of a table is marked by a line in the file that */
/* has a table-key statement. */
/* */
/* RETURNS: TRUE if table name available, FALSE if not. FALSE is */
/* returned at end-of-database. */
/* */
/*--------------------------------------------------------------------*/
/**********************************************************************/
BOOL dbGetNextTable( HENUMTABLES henum, PSZ pszTableName, INT cbTableName )
{
BOOL fSuccess = FALSE;
(void) memset( pszTableName, 0, cbTableName );
if( henum )
{
while( !feof( henum->stream ) && !fSuccess )
{
// It is not valid to hit end-of-file since we have a file
// delimeter that we look for. If we hit end-of-file before hitting
// our delimiter then the database file got hosed somehow.
if( !fgets( pszTableName, cbTableName, henum->stream ) )
{
if( feof( henum->stream ) )
Msg( "No end_of_database statement in database file!\n" );
else
Msg( "fgets got a bad return code in dbGetNextTable!\n" );
break;
}
if( strstr( pszTableName, TABLEKEY_LITERAL ) )
{
PSZ pszTableFound = pszTableName + strlen( TABLEKEY_LITERAL );
// If we hit end-of-database, find the next database if there
// is one.
if( strstr( pszTableFound, DB_END_LITERAL ) )
{
FILEFINDBUF3 ffb;
ULONG cFiles = 1;
APIRET rc;
rc = DosFindNext( henum->hdir, &ffb, sizeof ffb, &cFiles );
if( rc )
{
if( rc != ERROR_NO_MORE_FILES )
Msg( "DosFindNext RC(%u)", rc );
break;
}
else
{
// We found the next database so close the current one
// and open the new one.
fclose( henum->stream );
henum->stream = fopen( ffb.achName, "r" );
if( henum->stream )
{
PCH pchDot = strchr( ffb.achName, '.' );
if( pchDot )
*pchDot = 0;
strcpy( henum->szFileName, ffb.achName );
}
else
break;
}
}
else
{
char szFullName[ CCHMAXPATH ];
// We found a record in the file that indicates the start
// of a new table. Piece together the full 'dbase:table'
// string and return to the caller.
strcpy( szFullName, henum->szFileName );
strcat( szFullName, ":" );
strcat( szFullName, pszTableFound );
strncpy( pszTableName, szFullName, cbTableName );
if( pszTableName[ strlen( pszTableName ) - 1 ] == '\n' )
pszTableName[ strlen( pszTableName ) - 1 ] = 0;
fSuccess = TRUE;
}
}
}
}
return fSuccess;
}
/**********************************************************************/
/*------------------------- dbEndEnumTables --------------------------*/
/* */
/* END AN ENUMERATON OF THE DATABASE TABLE NAMES. */
/* */
/* PARMS: HENUMTABLES handle from the enumeration */
/* */
/* NOTES: */
/* */
/* RETURNS: nothing */
/* */
/*--------------------------------------------------------------------*/
/**********************************************************************/
void dbEndEnumTables( HENUMTABLES henum )
{
if( henum )
{
if( henum->stream )
fclose( henum->stream );
if( henum->hdir )
DosFindClose( henum->hdir );
free( henum );
}
}
/**********************************************************************/
/*-------------------------- dbRenderToFile --------------------------*/
/* */
/* COPY THE ROWS IN A TABLE TO A FILE. */
/* */
/* PARMS: table name in 'dbase:table' format, */
/* file name to copy rows to */
/* */
/* NOTES: Given a 'dbase:table' key, open the 'dbase' file and */
/* search for the 'table' key. When we find it, read all the */
/* rows until we get to the next table and place the rows that*/
/* we read into the output file whose name was passed to us. */
/* */
/* RETURNS: TRUE if successful, FALSE if not */
/* */
/*--------------------------------------------------------------------*/
/**********************************************************************/
BOOL dbRenderToFile( PSZ pszTableName, PSZ pszFileName )
{
BOOL fTrue = TRUE;
BOOL fSuccess = TRUE;
FILE *fhDbase = NULL, *fhOutfile = NULL;
char szNames[ CCHMAXPATH ];
char szLine[ CCHMAXPATH ];
PSZ pszTable, pszDbase = szNames;
// Here's what we're doing here. Let's say the pszTableName passed to us is
// dbase_1:table_1. We are converting that to this:
// dbase_1.db table_1. The 'dbase_1.db' file will be opened and searched
// for a table key of 'table_1'.
strcpy( szNames, pszTableName );
pszTable = strchr( pszDbase, ':' );
*(pszTable++) = 0;
memmove( pszTable + 5, pszTable, strlen( pszTable ) + 1 );
pszTable += 5;
strcat( pszDbase, ".db" );
fhDbase = fopen( pszDbase, "r" );
if( fhDbase )
{
while( !feof( fhDbase ) )
{
if( !fgets( szLine, sizeof szLine, fhDbase ) )
{
if( feof( fhDbase ) )
Msg( "No end_of_database statement in database file!\n" );
else
Msg( "fgets got a bad return code in dbRenderToFile!\n" );
break;
}
if( strstr( szLine, TABLEKEY_LITERAL ) )
{
if( strstr( szLine, DB_END_LITERAL ) )
{
Msg( "Table %s not found in %s!", pszTable, pszDbase );
break;
}
else if( strstr( szLine, pszTable ) )
{
fhOutfile = fopen( pszFileName, "w" );
if( !fhOutfile )
{
Msg( "Could not open output file %s", pszFileName );
break;
}
while( fTrue )
{
if( !fgets( szLine, sizeof szLine, fhDbase ) )
{
if( feof( fhDbase ) )
Msg( "No end_of_database statement in database "
"file!\n" );
else
Msg( "fgets got a bad return code in"
"dbRenderToFile!\n" );
break;
}
if( strstr( szLine, TABLEKEY_LITERAL ) )
break;
else
if( fputs( szLine, fhOutfile ) == EOF )
{
Msg( "Out of disk space!" );
break;
}
}
fclose( fhOutfile );
break;
}
}
}
fclose( fhDbase );
}
return fSuccess;
}
/*************************************************************************
* E N D O F S O U R C E *
*************************************************************************/