home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C Programming Starter Kit 2.0
/
SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso
/
bde
/
snipit.pak
/
VALCHECK.C
< prev
Wrap
C/C++ Source or Header
|
1997-07-23
|
26KB
|
671 lines
// BDE - (C) Copyright 1995 by Borland International
// valcheck.c
#include "snipit.h"
#include <dos.h>
// Set the length of the Cube Number field.
#define CUBELEN 10
static const char szTblName[] = "personel";
static const char szTblType[] = szPARADOX;
// Lookup table name.
static const char szTblLookup[] = "CubeNum";
// Field descriptor used in creating the main table.
static SNIPFAR FLDDesc fldDesc[] = {
{ // Field 1 - Full Name
1, // Field number
"Full Name", // Field name
fldZSTRING, // Field type
fldUNKNOWN, // Field subtype
40, // Field size (1 or 0, except
// BLOB or CHAR field)
0, // Decimal places ( 0 )
// computed
0, // Offset in record ( 0 )
0, // Length in bytes ( 0 )
0, // For Null bits ( 0 )
fldvHASCHECKS,// This field has validity checking
fldrREADWRITE // Rights
},
{ // Field 2 - Employee Number
2, "Employee Number", fldINT16, fldUNKNOWN,
0, 0, 0, 0, 0,
fldvHASCHECKS, fldrREADWRITE
},
{ // Field 3 - Department Number
3, "Department Number", fldINT16, fldUNKNOWN,
0, 0, 0, 0, 0,
fldvHASCHECKS, fldrREADWRITE
},
{ // Field 4 - Building Number
4, "Building Number", fldINT16, fldUNKNOWN,
0, 0, 0, 0, 0,
fldvHASCHECKS, fldrREADWRITE
},
{ // Field 5 - Social Security Number
5, "SS Number", fldZSTRING, fldUNKNOWN,
11, 0, 0, 0, 0,
fldvHASCHECKS, fldrREADWRITE
},
{ // Field 6 - Cube Number
6, "Cube Number", fldZSTRING, fldUNKNOWN,
CUBELEN, 0, 0, 0, 0,
fldvHASCHECKS, fldrREADWRITE
}
}; // Array of field descriptors.
// Field descriptor used to create the lookup table.
static SNIPFAR FLDDesc lkfldDesc[] = {
{ // Field 1 - Full Name
1, // Field number
"Cube Number",// Field name
fldZSTRING, // Field type
fldUNKNOWN, // Field subtype
CUBELEN, // Field size (1 or 0, except
// BLOB or CHAR field)
0, // Decimal places ( 0 )
// computed
0, // Offset in record ( 0 )
0, // Length in bytes ( 0 )
0, // For Null bits ( 0 )
fldvNOCHECKS, // This field has validity checking
fldrREADWRITE // Rights
}
}; // Array of field descriptors
// Validity check descriptor - Describes the validity checks. This validity
// check will be added to the table when the table is created.
// Note: The min val, max val, and default val validity checks are set
// within the CreateValCheck function, because the validity check
// needs to store data in the same format as the field. In this case
// the fields are fldINT16. This requires that a memset be done to
// copy the value into the validity check.
static SNIPFAR VCHKDesc VchkDesc[] = {
{ // First field validity check - Required field.
1, // Field number this belongs to
TRUE, // Is a required field
FALSE, // If True, has min value
FALSE, // If True, has max value
FALSE, // If True, has default value
{ NULL }, // Min value
{ NULL }, // Max value
{ NULL }, // Default value
{ NULL }, // Picture string
lkupNONE, // Lookup/Fill type
{ NULL }, // Lookup table name
},
{ // Second field validity check - min value - see note above.
2, FALSE, TRUE, FALSE, FALSE, {"15"}, { NULL },
{ NULL }, { NULL }, lkupNONE, { NULL }
},
{ // Third field validity check - max value - see note above.
3, FALSE, FALSE, TRUE, FALSE, { NULL }, {"3000"},
{ NULL }, { NULL }, lkupNONE, { NULL }
},
{ // Fourth field validity check - default value - see note
// above.
4, FALSE, FALSE, FALSE, TRUE, { NULL }, { NULL },
{"8"}, { NULL }, lkupNONE, { NULL }
},
{ // Fifth field validity check - picture of a SS number.
5, FALSE, FALSE, FALSE, FALSE, { NULL }, { NULL },
{ NULL }, { "###-##-####" }, lkupNONE, { NULL }
},
{ // Sixth field validity check - lookup table.
6, FALSE, FALSE, FALSE, FALSE, { NULL }, { NULL },
{ NULL }, { NULL }, lkupPRIVATE, "cubenum.db"
}
};
// Index descriptor.
static SNIPFAR IDXDesc idxDesc[] = {
{ // Primary Index - Full Name
"Employee Name", // Name
1, // Number
{ NULL }, // Tag name ( for dBase )
{ NULL }, // Optional format ( BTREE,
// HASH, etc )
TRUE, // Primary?
TRUE, // Unique?
FALSE, // Descending?
TRUE, // Maintained?
FALSE, // Subset?
FALSE, // Expression index?
NULL, // For QBE only
1, // Fields in key
1, // Length in bytes
FALSE, // Index out of date?
0, // Key type of expression
{ 1 }, // Array of field numbers
{ 0 }, // Key expression
{ 0 }, // Key condition
FALSE, // Case insensitive
0, // Block size in bytes
0 // Restructure number
}
};
// Index descriptor. This index array will be used to create the lookup table's
// primary index.
static SNIPFAR IDXDesc lkidxDesc[] = {
{ // Primary Index - Full name
"Cube_Number",// Name
1, // Number
{ NULL }, // Tag name ( for dBase )
{ NULL }, // Optional format ( BTREE,
// HASH, etc )
TRUE, // Primary?
TRUE, // Unique?
FALSE, // Descending?
TRUE, // Maintained?
FALSE, // Subset?
FALSE, // Expression index?
NULL, // For QBE only
1, // Fields in key
1, // Length in bytes
FALSE, // Index out of date?
0, // Key type of expression
{ 1 }, // Array of field numbers
{ 0 }, // Key expression
{ 0 }, // Key condition
FALSE, // Case insensitive
0, // Block size in bytes
0 // Restructure number
}
};
// The number of fields in the table.
static const unsigned uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]);
// Number of indexes to be created when the table is created.
static const unsigned uNumIndexes = sizeof(idxDesc) / sizeof(idxDesc[0]);
// The number of fields in the lookup table.
static const unsigned ulkNumFields = sizeof(lkfldDesc) /
sizeof (lkfldDesc[0]);
// Number of indexes to be created when the lookup table is created.
static const UINT16 ulkNumIndexes = sizeof(lkidxDesc) / sizeof(lkidxDesc[0]);
// Number of validity checks to be created.
static const UINT16 uNumVchks = sizeof(VchkDesc) / sizeof(VchkDesc[0]);
static DBIResult CreateVCHKTable(phDBIDb phDb);
static DBIResult InitLKTable(phDBIDb phDb);
static DBIResult AddRecord(hDBICur hCur, pCHAR pszName, INT16 lEmpNum,
INT16 lDeptNum, INT16 lBuildNum, pCHAR pszSSNum,
pCHAR pszCube);
static DBIResult AddLKRecord(hDBICur hCur, pCHAR pszCube);
static DBIResult FindRecord(pCHAR pszString, hDBICur hCur);
static void FormatPic(pCHAR pszDest, pCHAR pszPicture, pCHAR pszData);
//=====================================================================
// Function:
// ValCheck();
//
// Description:
// This function shows how validity checks are used on a Paradox
// table. This example will create a table to which the validity
// checks are added, as well as a lookup table which is used as
// part of the validity checks. All tables are deleted at the end
// of this example.
//
// This example places the following validity checks on the table:
// Required on the "Full Name" field.
// Minimum value of "15" on the "Employee Number" field.
// Maximum value of "3000" on the "Department Number" field.
// Default value of "8" on the "Building Number" field.
// Picture on the "SS Number" field.
// Lookup table for the "Cube Number" field.
//=====================================================================
void
ValCheck (void)
{
DBIResult rslt; // Return value from IDAPI functions
hDBIDb hDb; // Database handle
hDBICur hCur; // Cursor handle
CURProps TblProps; // Table properties
CHAR SSNumber[12]; // SS number string used for VC pictures
Screen("*** Validity Check Example ***\r\n");
BREAK_IN_DEBUGGER();
Screen(" Initializing IDAPI...");
if (InitAndConnect(&hDb) != DBIERR_NONE)
{
Screen("\r\n*** End of Example ***");
return;
}
Screen(" Setting the database directory...");
rslt = DbiSetDirectory(hDb, (pCHAR) szTblDirectory);
ChkRslt(rslt, "SetDirectory");
// Create the lookup table and fill with data.
if (InitLKTable(&hDb))
{
CloseDbAndExit(&hDb);
Screen("\r\n*** End of Example ***");
return;
}
// Create the table and attach the validity checks.
if (CreateVCHKTable(&hDb))
{
CloseDbAndExit(&hDb);
Screen("\r\n*** End of Example ***");
return;
}
Screen(" Open the %s table...", szTblName);
rslt = DbiOpenTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType,
NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
xltFIELD, FALSE, NULL, &hCur);
if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
{
CloseDbAndExit(&hDb);
Screen("\r\n*** End of Example ***");
return;
}
Screen(" Get the number of validity checks on the %s table...",
szTblName);
rslt = DbiGetCursorProps(hCur, &TblProps);
ChkRslt(rslt, "GetCursorProps");
Screen(" There are %d validity checks on the table",
TblProps.iValChecks);
// Add a record without the required field (field #1).
Screen("\r\n Adding the first record...");
// IDAPI does not format the data to match the picture. It only stores
// the picture.
FormatPic(SSNumber, "###-##-####", "111223333");
Screen(" Error expected - adding a record that does not have data"
"\r\n in the first field (Full Name),"
"\r\n which is a required field...");
AddRecord(hCur, "", 20, 2809, NULL, SSNumber, "2001");
Screen("\r\n Adding a record which satisfies the following"
" validity checks:\r\n\r\n\t"
" Required field for the first field - Full Name\r\n\t"
" Minimum Value of 15 for the second field - Employee Number"
"\r\n\t"
" Maximum value of 3000 for the third field - Department Number"
"\r\n\t"
" Default value of 8 for the fourth field - Building Number"
"\r\n\t"
" Picture of ###-##-#### for the fifth field - SS Number"
"\r\n\t"
" Lookup table for the sixth field - Cube Number\r\n");
// We are passing in NULL to the AddRecord function so that IDAPI will
// fill in the default value of 8 for the Building Number field.
AddRecord(hCur, "Goliath Mager", 24, 2806, NULL, SSNumber, "2004");
// Find the newly added record so we can display it.
FindRecord("Goliath Mager", hCur);
Screen(" Displaying the record...");
DisplayNextRecord(hCur);
Screen("\r\n Close the table...");
rslt = DbiCloseCursor(&hCur);
ChkRslt(rslt, "CloseCursor");
Screen(" Delete the table...");
rslt = DbiDeleteTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType);
ChkRslt(rslt, "DeleteTable");
Screen(" Delete the lookup table and indexes...");
rslt = DbiDeleteTable(hDb, (pCHAR) szTblLookup, (pCHAR) szTblType);
ChkRslt(rslt, "DeleteTable");
Screen(" Close the database and exit IDAPI...");
CloseDbAndExit(&hDb);
Screen("\r\n*** End of Example ***");
}
//=====================================================================
// Function:
// CreateVCHKTable(phDb);
//
// Input: phDb - Pointer to the database handle
//
// Return: Result of the table initialization
//
// Description:
// This function will create a table with the validity
// checks that are in the array called VchkDesc.
//=====================================================================
DBIResult
CreateVCHKTable (phDBIDb phDb)
{
DBIResult rslt; // Value returned from IDAPI functions
CRTblDesc crTblDsc; // Table descriptor
BOOL bOverWrite = TRUE; // Overwrite, yes/no flag
INT16 iDefVal = 8; // Default value for the "Building Number"
// Field
INT16 iMinVal = 15; // Min Value for the "Employee Number"
// field
INT16 iMaxVal = 3000; // Max value for the "Department Number"
// field
// Need to have actual integer values for the validity check.
memcpy(&(VchkDesc[1].aMinVal), &iMinVal, sizeof(INT16));
memcpy(&(VchkDesc[2].aMaxVal), &iMaxVal, sizeof(INT16));
memcpy(&(VchkDesc[3].aDefVal), &iDefVal, sizeof(INT16));
// Initialize the table create descriptor.
memset(&crTblDsc, 0, sizeof(CRTblDesc));
strcpy(crTblDsc.szTblName, szTblName);
strcpy(crTblDsc.szTblType, szTblType);
crTblDsc.iFldCount = uNumFields;
crTblDsc.pfldDesc = fldDesc;
crTblDsc.iIdxCount = uNumIndexes;
crTblDsc.pidxDesc = idxDesc;
crTblDsc.iValChkCount = uNumVchks;
crTblDsc.pvchkDesc = VchkDesc;
Screen(" Creating the %s table...", szTblName);
rslt = DbiCreateTable(*phDb, bOverWrite, &crTblDsc);
if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
{
return rslt;
}
return rslt;
}
//=====================================================================
// Function:
// InitLKTable(phDb);
//
// Input: phDb - Pointer to the database handle
//
// Return: Result of the table initialization
//
// Description:
// This function will create the lookup table that is used
// by the validity checks.
//=====================================================================
DBIResult
InitLKTable (phDBIDb phDb)
{
DBIResult rslt; // Value returned from IDAPI functions
hDBICur hCur; // Cursor handle for the table that is
// created
CRTblDesc crTblDsc; // Table descriptor
BOOL bOverWrite = TRUE; // Overwrite, yes/no flag
// Initialize the Table Create Descriptor.
memset(&crTblDsc, 0, sizeof(CRTblDesc));
strcpy(crTblDsc.szTblName, szTblLookup);
strcpy(crTblDsc.szTblType, szTblType);
crTblDsc.iFldCount = ulkNumFields;
crTblDsc.pfldDesc = lkfldDesc;
crTblDsc.iIdxCount = ulkNumIndexes;
crTblDsc.pidxDesc = lkidxDesc;
Screen(" Creating lookup table and indexes...");
rslt = DbiCreateTable(*phDb, bOverWrite, &crTblDsc);
if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
{
return rslt;
}
rslt = DbiOpenTable(*phDb, (pCHAR) szTblLookup, (pCHAR) szTblType,
NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
xltFIELD, FALSE, NULL, &hCur);
if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
{
return rslt;
}
// Add some records into the lookup table.
AddLKRecord(hCur, "2001");
AddLKRecord(hCur, "2002");
AddLKRecord(hCur, "2003");
AddLKRecord(hCur, "2004");
AddLKRecord(hCur, "2005");
AddLKRecord(hCur, "2006");
AddLKRecord(hCur, "2007");
// Close the table so it can be reopened from the calling function.
rslt = DbiCloseCursor(&hCur);
ChkRslt(rslt, "CloseCursor");
return rslt;
}
//=====================================================================
// Function:
// AddRecord(hCur, pszName, lEmpNum, lDeptNum, lBuildNum,
// pszSSNum, pszCube);
//
// Input: hCur - Pointer to the cursor handle
// pszName - Name
// lEmpNum - Employee number
// lDeptNum - Dept number
// lBuildNum - Building number
// pszSSNum - SS number
// pszCube - Cube number
//
// Return: Result of adding the record to the table
//
// Description:
// This function will add a record to the given table.
//=====================================================================
DBIResult
AddRecord (hDBICur hCur, pCHAR pszName, INT16 lEmpNum, INT16 lDeptNum,
INT16 lBuildNum, pCHAR pszSSNum, pCHAR pszCube)
{
DBIResult rslt; // Value returned from IDAPI functions
CURProps TblProps; // Table properties
pBYTE pRecBuf; // Record buffer
// Allocate a record buffer.
rslt = DbiGetCursorProps(hCur, &TblProps);
ChkRslt(rslt, "GetCursorProps");
pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE));
if (pRecBuf == NULL)
{
return DBIERR_NOMEMORY;
}
// Initialize record buffer.
rslt = DbiInitRecord(hCur, pRecBuf);
ChkRslt(rslt, "InitRecord");
// First name.
rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) pszName);
ChkRslt(rslt, "PutField");
// Employee number.
rslt = DbiPutField(hCur, 2, pRecBuf, (pBYTE) &lEmpNum);
ChkRslt(rslt, "PutField");
// Department number.
rslt = DbiPutField(hCur, 3, pRecBuf, (pBYTE) &lDeptNum);
ChkRslt(rslt, "PutField");
// Building number. If NULL, allow the default value to be used.
if (lBuildNum != NULL)
{
rslt = DbiPutField(hCur, 4, pRecBuf, (pBYTE) &lBuildNum);
ChkRslt(rslt, "PutField");
}
// SS number.
rslt = DbiPutField(hCur, 5, pRecBuf, (pBYTE) pszSSNum);
ChkRslt(rslt, "PutField");
// Place of birth.
rslt = DbiPutField(hCur, 6, pRecBuf, (pBYTE) pszCube);
ChkRslt(rslt, "PutField");
// Write the record to disk.
rslt = DbiInsertRecord(hCur, dbiNOLOCK, pRecBuf);
ChkRslt(rslt, "InsertRecord");
free(pRecBuf);
return rslt;
}
//=====================================================================
// Function:
// AddLKRecord(hCur, pszCube);
//
// Input: hCur - Pointer to the cursor handle
// pszCube - Cube name
//
// Return: Result of adding the record to the table
//
// Description:
// This function will add a record to the given table.
//=====================================================================
DBIResult
AddLKRecord (hDBICur hCur, pCHAR pszCube)
{
DBIResult rslt; // Value returned from IDAPI functions
CURProps TblProps; // Table properties
pBYTE pRecBuf; // Record buffer
// Allocate a record buffer.
rslt = DbiGetCursorProps(hCur, &TblProps);
ChkRslt(rslt, "GetCursorProps");
pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE));
if (pRecBuf == NULL)
{
return DBIERR_NOMEMORY;
}
// Initialize the record buffer.
rslt = DbiInitRecord(hCur, pRecBuf);
ChkRslt(rslt, "InitRecord");
// Cube number.
rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) pszCube);
ChkRslt(rslt, "PutField");
// Write the record to disk..
rslt = DbiInsertRecord(hCur, dbiNOLOCK, pRecBuf);
ChkRslt(rslt, "InsertRecord");
free(pRecBuf);
return rslt;
}
//=====================================================================
// Function:
// FindRecord(pszString, hCur);
//
// Input: pszString - String to find in the first field
// hCur - Cursor handle
//
// Return: Result of the search
//
// Description:
// This function will search the given table for the string
// passed to it in the first parameter. It will place this
// string into the first field of the record buffer and search
// for the string using the record buffer.
//=====================================================================
DBIResult
FindRecord (pCHAR pszString, hDBICur hCur)
{
CURProps TblProps; // Table properties
pBYTE pBuf = NULL; // Pointer to the record buffer
DBIResult rslt; // Return value from IDAPI functions
// Create the key buffer. The size comes from the property iRecBufSize.
rslt = DbiGetCursorProps(hCur,&TblProps);
ChkRslt(rslt, "GetCursorProps");
pBuf = (pBYTE) malloc(TblProps.iRecBufSize);
if (pBuf == NULL)
{
Screen(" Error - Out of memory");
return DBIERR_NOMEMORY;
}
// Search the "First Name" field for the pszString value.
rslt = DbiPutField(hCur, 1, pBuf, (pBYTE) pszString);
ChkRslt(rslt, "PutField");
rslt = DbiSetToKey(hCur, keySEARCHEQ, FALSE, 0, 0, pBuf);
ChkRslt(rslt, "SetToKey");
free(pBuf);
return rslt;
}
//=====================================================================
// Function:
// FormatPic(pszDest, pszPicture, pszData);
//
// Input: pszDest - Pointer to buffer that will receive the formatted
// string
// pszPicture - Pointer to buffer that holds the picture the data.
// pszData - Pointer to buffer that holds the data to be
// converted
//
// Return: A string in pszDest that matches the picture
//
// Description:
// This function only works for pictures that have a '#' symbol
// in them. This function can be expanded to work with all of
// the pictures that IDAPI provides. IDAPI does not actually
// format the string itself. This function expects that the
// pszDest variable will be large enough to hold the string after
// conversion. Therefore, the length of the pszDest variable must
// be the length of the picture plus 1 for the NULL terminating
// character.
//=====================================================================
void
FormatPic (pCHAR pszDest, pCHAR pszPicture, pCHAR pszData)
{
UINT16 iDest = 0;
UINT16 iPic = 0;
UINT16 iData = 0;
// Loop through the whole picture string and convert the data string to
// conform to it.
while (pszPicture[iPic] != NULL)
{
// If the character is a number put the number from the pszData string
// into the StrDest string.
if (pszPicture[iPic] == '#')
{
// Clean up the string one character at a time.
pszDest[iDest] = pszData[iData];
iDest++;
iPic++;
iData++;
}
// Otherwise the character is a constant to be placed within
// the string.
else
{
// Clean up the string one character at a time.
pszDest[iDest] = pszPicture[iPic];
iDest++;
iPic++;
}
}
pszDest[iDest] = 0;
}