community.borland.com

Article #15194: Using a continue node in a filter.

 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