Technical Information Database
TI194B.txt Using a continue node in a filter.
Category :General Programming
Platform :All
Product :BDE All
Description:
/*
This example shows the use of a canContinue node. A
Continue node is used to stop evaluating when a certain
condition is false for the first time.
This filter will limit the result set to those customers
living in Hawaii, you are listed in the table before the
customer with ID 1624.
Picture of the filter expression:
AND
/ \
/ \
/ \
/ \
EQ Continue
/ \ |
/ \ |
/ \ |
Field 2 szConst NE
(STATE/PROV) (HI) / \
/ \
/ \
Field1 fConst
(CUSTOMER NO)(1624.0)
*/
// BDE - (C) Copyright 1994 by Borland International
// Filter.c
#include "snipit.h"
static const char szTblName[] = "customer";
static const char szTblType[] = szPARADOX;
//===============================================================
// Function:
// Filter();
//
// Description:
// This example shows how to use filters to limit the
// result set of a table. Filters perform a function
// similar to that of ranges, but more powerful
// operations are supported.
//==============================================================
void
Filter (void)
{
hDBIDb hDb; // Handle to the database.
hDBICur hCur; // Handle to the table.
pBYTE pcanExpr; // Structure containing
// filter info.
hDBIFilter hFilter; // Filter handle.
UINT16 uSizeNodes; // Size of the nodes in the
// tree.
UINT16 uSizeCanExpr; // Size of the header
// information.
UINT16 uSizeLiterals; // Size of the literals.
UINT16 uTotalSize; // Total size of the filter
// expression.
UINT32 uNumRecs = 10; // Number of records to
// display.
CANExpr canExp; // Contains the header
// information.
UINT16 Nodes[] = // Nodes of the filter tree.
{
// Offset 0. Node 1.
nodeBINARY, // canBinary.nodeClass
canAND, // canBinary.canOp
8, // canBinary.iOperand1 - node 2
34, // canBinary.iOperand2 - node 5
// Offsets in the Nodes array
// Offset 8. Node 2.
nodeBINARY, // canBinary.nodeClass
canEQ , // canBinary.canOp
16, // canBinary.iOperand1 - node 3
24, // canBinary.iOperand2 - node 4
// Offsets in the Nodes array
// Offset 16. Node 3.
nodeFIELD, // canField.nodeClass
canFIELD, // canField.canOp
5, // canField.iFieldNum
11, // canField.iNameOffset: szField2
// is the literal at offset
// strlen(szField1) + 1
// Offset 24. Node 4.
nodeCONST, // canConst.nodeClass
canCONST, // canConst.canOp
fldZSTRING, // canConst.iType
3, // canConst.iSize
31, // canConst.iOffset: fconst is
// the literal at offset
// strlen(szField1) + 1 +
// sizeof(fConst) +
// strlen(szField2) + 1
// Offset 34. Node 5.
nodeUNARY, // canBinary.nodeClass
canCONTINUE, // canBinary.canOp
40, // canBinary.iOperand1 - node 6
// Offsets in the Nodes array
// Offset 40. Node 6.
nodeBINARY, // canBinary.nodeClass
canNE , // canBinary.canOp
48, // canBinary.iOperand1 - node 7
56, // canBinary.iOperand2 - node 8
// Offsets in the Nodes array
// Offset 48. Node 7.
nodeFIELD, // canField.nodeClass
canFIELD, // canField.canOp
1, // canField.iFieldNum
0, // canField.iNameOffset:
// szField1 is the literal at
// offset 0.
// Offset 56. Node 1.
nodeCONST, // canConst.nodeClass
canCONST, // canConst.canOp
fldFLOAT, // canConst.iType
8, // canConst.iSize
23, // canConst.iOffset: fconst is
// the literal at offset
// strlen(szField1) + 1 +
// strlen(szField2) + 1
};
// Name of the field for the third node of the tree.
CHAR szField1[] = "CUSTOMER NO";
// Name of the field for the third node of the tree.
CHAR szField2[] = "STATE/PROV";
// Value of the constant for the second node of the tree.
FLOAT fConst = 1624.0;
// Value of the constant for the second node of the tree.
// Field #7
CHAR szConst[] = "HI";
DBIResult rslt; // Return value from IDAPI functions.
Screen("*** Filter 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");
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;
}
// Go to the beginning of the table
rslt = DbiSetToBegin(hCur);
ChkRslt(rslt, "SetToBegin");
Screen("\r\n Display the %s table...", szTblName);
DisplayTable(hCur, uNumRecs);
// Size of the nodes.
uSizeNodes = sizeof(Nodes);
// Size of the literals.
uSizeLiterals = strlen(szField1) + 1 + sizeof(fConst) +
strlen(szField2) + 1 + strlen(szConst)
+ 1;
// Size of the header information.
uSizeCanExpr = sizeof(CANExpr);
// Total size of the filter.
uTotalSize = uSizeCanExpr + uSizeNodes + uSizeLiterals;
// Initialize the header information
canExp.iVer = 1; // Version.
canExp.iTotalSize = uTotalSize; // Total size of the filter.
canExp.iNodes = 8; // Number of nodes.
canExp.iNodeStart = uSizeCanExpr; // The offset in the
// buffer where the
// expression nodes
// start.
// The offset in the buffer where the literals start.
canExp.iLiteralStart = uSizeCanExpr + uSizeNodes;
// Allocate space for the filter expression.
pcanExpr = (pBYTE)malloc(uTotalSize * sizeof(BYTE));
if (pcanExpr == NULL)
{
Screen(" Could not allocate memory...");
DbiCloseCursor(&hCur);
CloseDbAndExit(&hDb);
Screen("\r\n*** End of Example ***");
return;
}
// Initialize the filter expression.
memmove(pcanExpr, &canExp, uSizeCanExpr);
memmove(&pcanExpr[uSizeCanExpr], Nodes, uSizeNodes);
memmove(&pcanExpr[uSizeCanExpr + uSizeNodes],
szField1, strlen(szField1) + 1); // First litteral
memmove(&pcanExpr[(uSizeCanExpr + uSizeNodes +
strlen(szField1) + 1)],
szField2, strlen(szField2) + 1); // First litteral
memmove(&pcanExpr[(uSizeCanExpr + uSizeNodes +
strlen(szField1) + 1 +
strlen(szField2) + 1)],
&fConst, sizeof(fConst)); // Second litteral
memmove(&pcanExpr[(uSizeCanExpr + uSizeNodes +
strlen(szField1) + 1 +
strlen(szField2) + 1 + sizeof(fConst))],
szConst, strlen(szConst) + 1); // First litteral
rslt = DbiSetToBegin(hCur);
ChkRslt(rslt, "SetToBegin");
Screen("\r\n Add a bug filter to the %s table which will"
" limit the records\r\n which are displayed"
" to those whose %s field is greater than %.1lf...",
szTblName, szField1, fConst);
rslt = DbiAddFilter(hCur, 0L, 1, FALSE, (pCANExpr)pcanExpr,
NULL, &hFilter);
if (ChkRslt(rslt, "AddFilter") != DBIERR_NONE)
{
rslt = DbiCloseCursor(&hCur);
ChkRslt(rslt, "CloseCursor");
free(pcanExpr);
CloseDbAndExit(&hDb);
Screen("\r\n*** End of Example ***");
return;
}
// Activate the filter.
Screen(" Activate the filter on the %s table...",
szTblName);
rslt = DbiActivateFilter(hCur, hFilter);
ChkRslt(rslt, "ActivateFilter");
rslt = DbiSetToBegin(hCur);
ChkRslt(rslt, "SetToBegin");
Screen("\r\n Display the %s table with the filter"
" set...", szTblName);
DisplayTable(hCur, uNumRecs);
Screen("\r\n Deactivate the filter...");
rslt = DbiDeactivateFilter(hCur, hFilter);
ChkRslt(rslt, "DeactivateFilter");
Screen("\r\n Drop the filter...");
rslt = DbiDropFilter(hCur, hFilter);
ChkRslt(rslt, "DropFilter");
rslt = DbiCloseCursor(&hCur);
ChkRslt(rslt, "CloseCursor");
free(pcanExpr);
Screen(" Close the database and exit IDAPI...");
CloseDbAndExit(&hDb);
Screen("\r\n*** End of Example ***");
}
Reference:
7/15/98 3:24:22 PM
Last Modified: 01-SEP-99