C Examples: DbiActivateFilter

<< Click to Display Table of Contents >>

Navigation:  »No topics above this level«

C Examples: DbiActivateFilter

Return to chapter overview

Limiting the records which are available in the table using a filter.

This example limits records to those with a CUST_NO field greater than 1500.

static const char szTblName[] = "cust";     // Name of the table
static const char szTblType[] = szDBASE;    // Type of table
static const char szField[]   = "CUST_NO";  // Name of the field for the
                                            //   third node of the tree.
static const DFLOAT fConst    = 1500.0;     // Value of the constant for
                                            //   the second node of the tree.
 
void
Filter (void)
{
    hDBIDb          hDb = 0;            // Handle to the database.
    hDBICur         hCur = 0;           // Handle to the table.
    DBIResult       rslt;               // Return value from IDAPI functions.
    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.
    UINT32          uSizeLiterals;      // Size of the literals.
    UINT32          uTotalSize;         // Total size of the filter expression.
    UINT32          uNumRecs = 10;      // Number of records to display.
    CANExpr         canExp;             // Contains the header information.
    struct {
        CANBinary BinaryNode;
        CANField  FieldNode;
        CANConst  ConstantNode;
    }
    Nodes = {                           // Nodes of the filter tree.
    {
        // Offset 0
        nodeBINARY,                     // canBinary.nodeClass
        canGT,                          // canBinary.canOp
        sizeof(Nodes.BinaryNode),       // canBinary.iOperand1
        sizeof(Nodes.BinaryNode) + sizeof(Nodes.FieldNode),
                                        // canBinary.iOperand2
                                        //   Offsets in the Nodes array
    },
    {
        // Offset sizeof(Nodes.BinaryNode)
        nodeFIELD,                      // canField.nodeClass
        canFIELD,                       // canField.canOp
        1,                              // canField.iFieldNum
        0,                              // canField.iNameOffset: szField is the
                                        //   literal at offset 0
    },
    {
        // Offset sizeof(Nodes.BinaryNode) + sizeof(Nodes.FieldNode)
        nodeCONST,                      // canConst.nodeClass
        canCONST,                       // canConst.canOp
        fldFLOAT,                       // canConst.iType
        sizeof(fConst),                 // canConst.iSize
        8,                              // canConst.iOffset: fconst is the
                                        // literal at offset strlen(szField) + 1
    }};
 
    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);
 
    uSizeNodes      = sizeof(Nodes);    // Size of the nodes.
    uSizeLiterals   = (UINT16)(strlen((pCHAR)szField) + 1 + sizeof(fConst));
                                        // Size of the literals.
    uSizeCanExpr    = sizeof(CANExpr);  // Size of the header information.
    uTotalSize      = (UINT16)(uSizeCanExpr + uSizeNodes + uSizeLiterals);
                                        // Total size of the filter.
 
    // Initialize the header information
    canExp.iVer = 1;                    // Version.
    canExp.iTotalSize = (UINT16)uTotalSize; // Total size of the filter.
    canExp.iNodes = 3;                      // Number of nodes.
    canExp.iNodeStart = uSizeCanExpr;   // The offset in the buffer where the
                                        //   expression nodes start.
    canExp.iLiteralStart = (UINT16)(uSizeCanExpr + uSizeNodes);
                                        // The offset in the buffer where the
                                        //   literals start.
 
    // Allocate contiguous memory space to hold
    // 1) Header information  i.e. the CANExpr structure
    // 2) Binary, field and constant nodes  i.e. the Nodes structure
    // 3) Literal and constant pool  i.e. field names and constant values
    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 by placing header, nodes and
    // pool into pcanexpr
 
    // Move header information into pcanexpr. pcanExpr will now look as follows:
    // **canExp**|                 |                        |
    // | CANExpr |    All Nodes    | Literal, Constant Pool |
    // |----------------------------------------------------|
    // 0                                                    sizeof(uTotalSize)
    memmove(pcanExpr, &canExp, uSizeCanExpr);
 
    // Move node structure into pcanexpr. pcanExpr will now look as follows:
    // |**canExp*|**Node Structure*|                        |
    // | CANExpr |    All Nodes    | Literal, Constant Pool |
    // |----------------------------------------------------|
    // 0                                                    sizeof(uTotalSize)
    memmove(&pcanExpr[uSizeCanExpr], &Nodes, uSizeNodes);
 
    // Move the literal into pcanexpr. pcanExpr will now look as follows:
    // |**canExp*|**Node Structure*|***szField              |
    // | CANExpr |    All Nodes    | Literal, Constant Pool |
    // |----------------------------------------------------|
    // 0                                                    sizeof(uTotalSize)
    memmove(&pcanExpr[uSizeCanExpr + uSizeNodes],
            szField, strlen(szField) + 1);  // First literal "CUST_NO"
 
    // Move the literal into pcanexpr. pcanExpr will now look as follows:
    // |**canExp*|**Node Structure*|***szField*****fConst***|
    // | CANExpr |    All Nodes    | Literal, Constant Pool |
    // |----------------------------------------------------|
    // 0                                                    sizeof(uTotalSize)
    memmove(&pcanExpr[uSizeCanExpr + uSizeNodes + strlen(szField) + 1],
            &fConst, sizeof(fConst));       // Second literal 1500.00
 
    rslt = DbiSetToBegin(hCur);
    ChkRslt(rslt, "SetToBegin");
 
    Screen("\r\n    Add a 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, szField, 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 ***");
}

Limiting the records which are available in the table using a comparison filter.

This example shows how to use filters to limit the result set of a table. This example does a comparison of the first N digits of a character field.

static const char szTblName[] = "cust";     // Name of the table
static const char szTblType[] = szDBASE;    // Type of table
static const char szField[]   = "CUST_NO";  // Name of the field for the
                                            //   third node of the tree.
static const DFLOAT fConst    = 1500.0;     // Value of the constant for
                                            //   the second node of the tree.
 
void
Filter (void)
{
    hDBIDb          hDb = 0;            // Handle to the database.
    hDBICur         hCur = 0;           // Handle to the table.
    DBIResult       rslt;               // Return value from IDAPI functions.
    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.
    UINT32          uSizeLiterals;      // Size of the literals.
    UINT32          uTotalSize;         // Total size of the filter expression.
    UINT32          uNumRecs = 10;      // Number of records to display.
    CANExpr         canExp;             // Contains the header information.
    struct {
        CANBinary BinaryNode;
        CANField  FieldNode;
        CANConst  ConstantNode;
    }
    Nodes = {                           // Nodes of the filter tree.
    {
        // Offset 0
        nodeBINARY,                     // canBinary.nodeClass
        canGT,                          // canBinary.canOp
        sizeof(Nodes.BinaryNode),       // canBinary.iOperand1
        sizeof(Nodes.BinaryNode) + sizeof(Nodes.FieldNode),
                                        // canBinary.iOperand2
                                        //   Offsets in the Nodes array
    },
    {
        // Offset sizeof(Nodes.BinaryNode)
        nodeFIELD,                      // canField.nodeClass
        canFIELD,                       // canField.canOp
        1,                              // canField.iFieldNum
        0,                              // canField.iNameOffset: szField is the
                                        //   literal at offset 0
    },
    {
        // Offset sizeof(Nodes.BinaryNode) + sizeof(Nodes.FieldNode)
        nodeCONST,                      // canConst.nodeClass
        canCONST,                       // canConst.canOp
        fldFLOAT,                       // canConst.iType
        sizeof(fConst),                 // canConst.iSize
        8,                              // canConst.iOffset: fconst is the
                                        // literal at offset strlen(szField) + 1
    }};
 
    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);
 
    uSizeNodes      = sizeof(Nodes);    // Size of the nodes.
    uSizeLiterals   = (UINT16)(strlen((pCHAR)szField) + 1 + sizeof(fConst));
                                        // Size of the literals.
    uSizeCanExpr    = sizeof(CANExpr);  // Size of the header information.
    uTotalSize      = (UINT16)(uSizeCanExpr + uSizeNodes + uSizeLiterals);
                                        // Total size of the filter.
 
    // Initialize the header information
    canExp.iVer = 1;                    // Version.
    canExp.iTotalSize = (UINT16)uTotalSize; // Total size of the filter.
    canExp.iNodes = 3;                      // Number of nodes.
    canExp.iNodeStart = uSizeCanExpr;   // The offset in the buffer where the
                                        //   expression nodes start.
    canExp.iLiteralStart = (UINT16)(uSizeCanExpr + uSizeNodes);
                                        // The offset in the buffer where the
                                        //   literals start.
 
    // Allocate contiguous memory space to hold
    // 1) Header information  i.e. the CANExpr structure
    // 2) Binary, field and constant nodes  i.e. the Nodes structure
    // 3) Literal and constant pool  i.e. field names and constant values
    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 by placing header, nodes and
    // pool into pcanexpr
 
    // Move header information into pcanexpr. pcanExpr will now look as follows:
    // **canExp**|                 |                        |
    // | CANExpr |    All Nodes    | Literal, Constant Pool |
    // |----------------------------------------------------|
    // 0                                                    sizeof(uTotalSize)
    memmove(pcanExpr, &canExp, uSizeCanExpr);
 
    // Move node structure into pcanexpr. pcanExpr will now look as follows:
    // |**canExp*|**Node Structure*|                        |
    // | CANExpr |    All Nodes    | Literal, Constant Pool |
    // |----------------------------------------------------|
    // 0                                                    sizeof(uTotalSize)
    memmove(&pcanExpr[uSizeCanExpr], &Nodes, uSizeNodes);
 
    // Move the literal into pcanexpr. pcanExpr will now look as follows:
    // |**canExp*|**Node Structure*|***szField              |
    // | CANExpr |    All Nodes    | Literal, Constant Pool |
    // |----------------------------------------------------|
    // 0                                                    sizeof(uTotalSize)
    memmove(&pcanExpr[uSizeCanExpr + uSizeNodes],
            szField, strlen(szField) + 1);  // First literal "CUST_NO"
 
    // Move the literal into pcanexpr. pcanExpr will now look as follows:
    // |**canExp*|**Node Structure*|***szField*****fConst***|
    // | CANExpr |    All Nodes    | Literal, Constant Pool |
    // |----------------------------------------------------|
    // 0                                                    sizeof(uTotalSize)
    memmove(&pcanExpr[uSizeCanExpr + uSizeNodes + strlen(szField) + 1],
            &fConst, sizeof(fConst));       // Second literal 1500.00
 
    rslt = DbiSetToBegin(hCur);
    ChkRslt(rslt, "SetToBegin");
 
    Screen("\r\n    Add a 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, szField, 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 ***");
}

Limiting the records which are available in the table using a continue filter.

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.

 

static const char szTblName[] = "customer";
static const char szTblType[] = szPARADOX;
static const CHAR szField1[] = "Customer No";
static const CHAR szField2[] = "State/Prov";
static const CHAR szConst[]  = "HI";
static const DFLOAT fConst = 1624.0;
 
void
FiltCont (void)
{
    hDBIDb          hDb = 0;        // Handle to the database.
    hDBICur         hCur = 0;       // Handle to the table.
    DBIResult       rslt;           // Return value from IDAPI functions.
    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.
    UINT32          uSizeLiterals;  // Size of the literals.
    UINT32          uTotalSize;     // Total size of the filter
                                    //   expression.
    UINT32          uNumRecs  = 10; // Number of records to
                                    //   display.
    CANExpr         canExp;         // Contains the header
                                    //   information.
 
    struct {
       CANBinary BinaryNode1;
       CANBinary  BinaryNode2;
       CANField  FieldNode1;
       CANConst  ConstantNode1;
       CANUnary UnaryNode1;
       CANBinary  BinaryNode3;
       CANField  FieldNode2;
       CANConst  ConstantNode2;
    } Nodes = {                     // Nodes of the filter tree.
    {
        // Offset 0. Node 1. sizeof(Nodes.BinaryNode1)
        nodeBINARY,                 // canBinary.nodeClass
        canAND,                     // canBinary.canOp
        sizeof(Nodes.BinaryNode1),  // canBinary.iOperand1 - node 2
 
        sizeof(Nodes.BinaryNode1) + sizeof(Nodes.BinaryNode2) +
        sizeof(Nodes.FieldNode1) + sizeof(Nodes.ConstantNode1),
                                    // canBinary.iOperand2 - node 5
    },
    {
        // Offset 8. Node 2. sizeof(Nodes.BinaryNode2)
        nodeBINARY,                 // canBinary.nodeClass
        canEQ ,                     // canBinary.canOp
        sizeof(Nodes.BinaryNode1) + sizeof(Nodes.BinaryNode2),
                                    // canBinary.iOperand1 - node 3
 
        sizeof(Nodes.BinaryNode1) + sizeof(Nodes.BinaryNode2) +
        sizeof(Nodes.FieldNode1),   // canBinary.iOperand2 - node 4
    },
    {
        // Offset 16. Node 3. sizeof(Nodes.FieldNode1)
        nodeFIELD,                  // canField.nodeClass
        canFIELD,                   // canField.canOp
        5,                          // canField.iFieldNum
        12,                         // canField.iNameOffset: szField2
    },                              //   is the literal at offset
    {                               //   strlen(szField1) + 1
 
        // Offset 24. Node 4. sizeof(Nodes.ConstantNode1)
        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. sizeof(Nodes.UnaryNode1)
        nodeUNARY,      // canBinary.nodeClass
        canCONTINUE,    // canBinary.canOp
        sizeof(Nodes.BinaryNode1) + sizeof(Nodes.BinaryNode2) +
 
        sizeof(Nodes.FieldNode1) + sizeof(Nodes.ConstantNode1) +
        sizeof(Nodes.UnaryNode1),   // canBinary.iOperand1 - node 6
    },                              //   Offsets in the Nodes array
    {
        // Offset 40. Node 6. sizeof(Nodes.BinaryNode3)
        nodeBINARY,     // canBinary.nodeClass
        canNE ,         // canBinary.canOp
        sizeof(Nodes.BinaryNode1) + sizeof(Nodes.BinaryNode2) +
        sizeof(Nodes.FieldNode1) + sizeof(Nodes.ConstantNode1) +
        sizeof(Nodes.UnaryNode1) + sizeof(Nodes.BinaryNode3),
                                    // canBinary.iOperand1 - node 7
 
        sizeof(Nodes.BinaryNode1) + sizeof(Nodes.BinaryNode2) +
        sizeof(Nodes.FieldNode1) + sizeof(Nodes.ConstantNode1) +
        sizeof(Nodes.UnaryNode1) + sizeof(Nodes.BinaryNode3) +
        sizeof(Nodes.FieldNode2),   // canBinary.iOperand2 - node 8
    },
    {
        // Offset 48. Node 7. sizeof(Nodes.FieldNode2)
        nodeFIELD,                  // canField.nodeClass
        canFIELD,                   // canField.canOp
        1,                          // canField.iFieldNum
        0,                          // canField.iNameOffset:
    },                              //   szField1 is the literal at
    {                               //   offset 0.
 
        // Offset 56. Node 8. Size 14 Bytes
        nodeCONST,                  // canConst.nodeClass
        canCONST,                   // canConst.canOp
        fldFLOAT,                   // canConst.iType
        sizeof(fConst),             // canConst.iSize
        23,                         // canConst.iOffset: fconst is
    }};                             //   the literal at offset
                                    //   strlen(szField1) + 1 +
                                    //   strlen(szField2) + 1
 
    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 = (UINT16)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 = (UINT16)(uSizeCanExpr + uSizeNodes);
 
    // Allocate contiguous memory space to hold
    // 1) Header information  i.e. the CANExpr structure
    // 2) Compare, field and constant nodes  i.e. the Nodes structure
    // 3) Literal and constant pool  i.e. field names and constant values
    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 by placing header, nodes and
    // pool into pcanexpr
 
    // Move the literal into pcanexpr. pcanExpr will now look as follows:
    // |**canExp*|                 |                                  |
    // | CANExpr |    All Nodes    |      Literal, Constant Pool      |
    // |--------------------------------------------------------------|
    // 0                                                      sizeof(uTotalSize)
    memmove(pcanExpr, &canExp, uSizeCanExpr); // Insert Header Information
 
    // Move the literal into pcanexpr. pcanExpr will now look as follows:
    // |**canExp*|**Node Structure*|                                  |
    // | CANExpr |    All Nodes    |      Literal, Constant Pool      |
    // |--------------------------------------------------------------|
    // 0                                                      sizeof(uTotalSize)
    memmove(&pcanExpr[uSizeCanExpr], &Nodes, uSizeNodes); // Insert Nodes
 
    // Move the literal into pcanexpr. pcanExpr will now look as follows:
    // |**canExp*|**Node Structure*|*szField1*                        |
    // | CANExpr |    All Nodes    |      Literal, Constant Pool      |
    // |--------------------------------------------------------------|
    // 0                                                      sizeof(uTotalSize)
    memmove(&pcanExpr[uSizeCanExpr + uSizeNodes],
            szField1, strlen(szField1) + 1); // First litteral
 
    // Move the literal into pcanexpr. pcanExpr will now look as follows:
    // |**canExp*|**Node Structure*|*szField1*szField2*               |
    // | CANExpr |    All Nodes    |      Literal, Constant Pool      |
    // |--------------------------------------------------------------|
    // 0                                                      sizeof(uTotalSize)
    memmove(&pcanExpr[(uSizeCanExpr + uSizeNodes +
                      strlen(szField1) + 1)],
            szField2, strlen(szField2) + 1); // Second litteral
 
    // Move the literal into pcanexpr. pcanExpr will now look as follows:
    // |**canExp*|**Node Structure*|*szField1*szField2*fConst*        |
    // | CANExpr |    All Nodes    |      Literal, Constant Pool      |
    // |--------------------------------------------------------------|
    // 0                                                      sizeof(uTotalSize)
    memmove(&pcanExpr[(uSizeCanExpr + uSizeNodes +
                      strlen(szField1) + 1 +
                      strlen(szField2) + 1)],
            &fConst, sizeof(fConst)); // First Constant
 
    // Move the literal into pcanexpr. pcanExpr will now look as follows:
    // |**canExp*|**Node Structure*|*szField1*szField2*fConst*szConst*|
    // | CANExpr |    All Nodes    |      Literal, Constant Pool      |
    // |--------------------------------------------------------------|
    // 0                                                      sizeof(uTotalSize)
    memmove(&pcanExpr[(uSizeCanExpr + uSizeNodes +
                      strlen(szField1) + 1 +
                      strlen(szField2) + 1 + sizeof(fConst))],
            szConst, strlen(szConst) + 1); // Second Constant
 
    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 ***");
}