// BDE - (C) Copyright 1995 by Borland International // FiltCont.c #include "snipit.h" static const char szTblName[] = "customer"; static const char szTblType[] = szPARADOX; //=============================================================== // Function: // FiltCont(); // // Description: // This example shows how to use filters to limit the // result set of a table. // // 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 this filter expression: // // AND // / \ // / \ // / \ // / \ // EQ Continue // / \ | // / \ | // / \ | // Field 2 szConst NE // (STATE/PROV) (HI) / \ // / \ // / \ // Field1 fConst // (CUSTOMER NO)(1624.0) // //============================================================== void FiltCont (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("*** Continue 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 filter to the %s table which will" " limit the records\r\n in the result set" " to those whose %s field is equal to '%s', until\r\n" " the first record where the %s field is equal to %.1lf...", szTblName, szField2, szConst, 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 ***"); }