home *** CD-ROM | disk | FTP | other *** search
- // BDE32 3.x - (C) Copyright 1996 by Borland International
-
- // filter.c
- #include "snipit.h"
-
- //=====================================================================
- // Function:
- // Filter();
- //
- // Description:
- // This example shows how to use filters to limit the result
- // set of a table. Filters perform a similar function to
- // ranges, but more powerful operations are supported.
- //=====================================================================
- void
- Test(void)
- {
- hDBIDb hDb; // Handle to the database
- hDBICur hCur; // Handle to the Cursor
- hDBIFilter hFilter; // Handle to the Filter
-
- DBIResult iErr;
- int i;
-
-
- pCURProps pCProps; // Schema Descriptors Pointers
- pFLDDesc pFldDescs;
-
- pUINT32 pRecCnt;
-
-
- pCHAR pcanExpr; // Filter Pointers
- pCANExpr pTemp;
- pCANBinary pBinary;
- pCANField pField;
- pCANConst pConst;
- pCHAR pLiteral;
-
-
- INT16 iCanExprBlkSz, iNodeBlkSz, iLiteralBlkSz, iExprBlkSz;
- INT16 iCanBinary, iCanField, iCanConst;
-
-
- FLOAT iConstant = 1400;
-
-
- Screen("*** Test ***\r\n");
-
- BREAK_IN_DEBUGGER();
-
- Screen(" Initializing IDAPI...\r\n");
- if (ChkRslt(DbiInit(NULL), DBIERR_NONE, " Error - Init")
- != DBIERR_NONE) // Check if successfull
- {
- Screen("\r\n*** End of Example ***");
- return;
- }
-
- // Open the standard database. Notice that we are opening the
- // database in READWRITE mode and SHARED mode.
- Screen(" Opening Standard Database...");
- if (ChkRslt(DbiOpenDatabase("", 0, dbiREADWRITE, dbiOPENSHARED,
- NULL, NULL, NULL, NULL, &hDb),
- DBIERR_NONE, " Error - OpenDatabase.") != DBIERR_NONE)
- {
- // Clean up since an error occured
- Screen(" Exit IDAPI...");
- ChkRslt(DbiExit(), DBIERR_NONE, " Error - Exit.");
- Screen("\r\n*** End of Example ***");
- return;
- }
-
- // Need to set the directory which the database uses by default.
- // This way table names do not have to be queslified with a path....
- Screen(" Set the directory which is used by the database...");
- ChkRslt(DbiSetDirectory(hDb, (pCHAR)szTblDirectory), DBIERR_NONE,
- " Error - SetDirectory.");
-
-
- //
- // Open a Paradox table
- //
- ChkRslt( DbiOpenTable( hDb, "ORDERS.DB", szPARADOX, "", "", 0,
- dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE, NULL, &hCur ),
- DBIERR_NONE, " Error - Open Table");
-
-
- pCProps = (pCURProps) malloc( sizeof(CURProps) );
- for ( i = 0; i < sizeof(CURProps); i++) *((pCHAR)pCProps+i) = 0;
- ChkRslt(DbiGetCursorProps(hCur, pCProps), DBIERR_NONE, " Error - Get Props");
-
-
-
- pFldDescs = (pFLDDesc) malloc( sizeof(FLDDesc) * pCProps->iFields);
- for ( i = 0; i < sizeof(FLDDesc) * pCProps->iFields; i++) *((pCHAR)pFldDescs+i) = 0;
- ChkRslt(DbiGetFieldDescs(hCur, pFldDescs ), DBIERR_NONE, " Error - Get FldDescs");
-
-
-
- if( pFldDescs[0].iFldType == fldFLOAT )
- {
- //
- // Filter Expression: F1 > 1400
- // ------------------------------------------------------
- // Expression Nodes Tree:
- //
- // Root(>)
- // (canBINARY)
- // / \
- // / \
- // Opr2(F1) Opr1(1400)
- // (canFIELD) (canCONST)
- //
- //
- //
-
-
- iCanBinary = sizeof(CANBinary); // Alternative: use sizeof(CANNode)
- iCanField = sizeof(CANField); // in generic build function
- iCanConst = sizeof(CANConst); // to allow all Node Struct
-
-
- //
- // Compute Expression Block Size
- //
- iCanExprBlkSz = sizeof(CANExpr);
-
- iNodeBlkSz = iCanBinary + iCanField + iCanConst;
-
- iLiteralBlkSz = strlen(pFldDescs[0].szName) + 1 + pFldDescs[0].iLen;
-
- iExprBlkSz = iCanExprBlkSz + iNodeBlkSz + iLiteralBlkSz;
-
-
- pcanExpr = malloc(iExprBlkSz);
- for( i = 0; i < iExprBlkSz; i++ ) *(pcanExpr + i) = 0;
-
-
- //
- // Setup CANExpr Block
- //
- pTemp = (pCANExpr)pcanExpr;
- pTemp->iVer = CANEXPRVERSION;
- pTemp->iTotalSize = iExprBlkSz;
- pTemp->iNodes = 3;
- pTemp->iNodeStart = iCanExprBlkSz;
- pTemp->iLiteralStart = iCanExprBlkSz + iNodeBlkSz;
-
-
-
-
- // Setup nodes: BINARY GT
- pBinary = (pCANBinary) &pcanExpr[iCanExprBlkSz];
-
- pBinary->nodeClass = nodeBINARY;
- pBinary->canOp = canGT;
- // Operand Offset is computed by using address of iNodeStart
- pBinary->iOperand1 = iCanBinary; // iNodeStart +sizeof BINARY node is address of Operand 1
- pBinary->iOperand2 = iCanBinary + iCanField; // iNodeStart +sizeof BINARY node +sizeof FIELD node is address of Operand 2
-
-
- // FIELD 1,0
- pField = (pCANField) &pcanExpr[iCanExprBlkSz+iCanBinary];
-
- pField->nodeClass = nodeFIELD;
- pField->canOp = canFIELD;
- pField->iFieldNum = 1; // Field Name where filter is applied
- // FieldName string is computed by using address of iLiteralStart
- pField->iNameOffset = 0; // iLiteral is the address of Field Name String
-
-
- // CONSTANT FLOAT, +
- pConst = (pCANConst) &pcanExpr[iCanExprBlkSz+iCanBinary+iCanField];
-
- pConst->nodeClass = nodeCONST;
- pConst->canOp = canCONST;
- pConst->iType = pFldDescs[0].iFldType; // use idapi(logical) field type
- pConst->iSize = pFldDescs[0].iLen; // use length of idapi(logical) field type
- pConst->iOffset = strlen(pFldDescs[0].szName) + 1; // value of constant follow FieldName string
- // null terminator of string must be included
-
-
- // Set Literals:
- pLiteral = (pCHAR) &pcanExpr[iCanExprBlkSz + iNodeBlkSz];
-
- // Field Name for Field node
- strcpy( &pLiteral[0], pFldDescs[0].szName ); // move FieldName to Literal Pool
-
- // Constant FLOAT value for constant node
- memcpy( &pLiteral[strlen(pFldDescs[0].szName)+1],
- (pCHAR)&iConstant, pFldDescs[0].iLen); // move 1400 right after FieldName string
-
-
- // ------------------------------------------------------
- //
- // View a filtered cursor
-
- ChkRslt(DbiAddFilter( hCur, 0, 10, FALSE, (pCANExpr)pcanExpr, NULL, &hFilter ),
- DBIERR_NONE, " Error - Add Filter");
- ChkRslt(DbiActivateFilter( hCur, hFilter ), DBIERR_NONE, " Error - Activate Filter");
- ChkRslt(DbiSetToBegin( hCur ), DBIERR_NONE, " Error - Set BOF");
-
- pRecCnt = (pUINT32) malloc( sizeof(UINT32) );
- ChkRslt(DbiGetRecordCount(hCur, pRecCnt), DBIERR_NONE, " Error - Get Rec Cnt");
-
- DisplayTable(hCur, *pRecCnt);
-
- //
- // Completed
- //
- // ------------------------------------------------------
- // For a more complex filter Expression,
- // a more complex node tree is needed as illustrated in
- // in the following diagram:
- //
- // Filter Expression: F1 > 1400 AND 1500 > F1
- // ------------------------------------------------------
- // Expression Nodes Tree:
- //
- // Root(AND)
- // (canBINARY)
- // / \
- // / \
- // / \
- // Node(>) Node(>)
- // (canBINARY) (canBINARY)
- // / \ / \
- // / \ / \
- // Opr1(F1) Opr2(1400) Opr1(1500) Opr2(F1)
- // (canFIELD) (canCONST) (canCONST) (canFIELD)
- //
- //
- // ------------------------------------------------------
- //
- free((pBYTE)pcanExpr);
- free((pBYTE)pFldDescs);
- free((pBYTE)pCProps);
- free((pBYTE)pRecCnt);
- }
- else
- Screen( "\r\n Abort: Field 1 not numeric\r\n");
-
-
- // Close the Cursor
- DbiCloseCursor(&hCur);
-
-
- // Close the standard database
- Screen(" Close the standard database...");
- ChkRslt(DbiCloseDatabase(&hDb), DBIERR_NONE,
- " Error - CloseDatabase.");
-
-
- Screen(" Exit IDAPI...");
- ChkRslt(DbiExit(), DBIERR_NONE, " Error - Exit.");
-
- Screen("\r\n*** End of Example ***");
- }