home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / 32SNIPIT.PAK / FILTCONT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  14.2 KB  |  334 lines

  1. // BDE32 3.x - (C) Copyright 1996 by Borland International
  2.  
  3. // FiltCont.c
  4. #include "snipit.h"
  5.  
  6. static const char szTblName[] = "customer";
  7. static const char szTblType[] = szPARADOX;
  8. static const CHAR szField1[] = "Customer No";
  9. static const CHAR szField2[] = "State/Prov";
  10. static const CHAR szConst[]  = "HI";
  11. static const DFLOAT fConst = 1624.0;
  12.  
  13. //===============================================================
  14. //  Function:
  15. //          FiltCont();
  16. //
  17. //  Description:
  18. //          This example shows how to use filters to limit the
  19. //          result set of a table.
  20. //
  21. //          This example shows the use of a canContinue node. A
  22. //          Continue node is used to stop evaluating when a certain
  23. //          condition is false for the first time.
  24. //
  25. //          This filter will limit the result set to those
  26. //          customers living in Hawaii, you are listed in the
  27. //          table before the customer with ID 1624.
  28. //
  29. //          Picture of this filter expression:
  30. /*
  31.                                 AND
  32.                               /     \
  33.                              /       \
  34.                             /         \
  35.                            /           \
  36.                         EQ           Continue
  37.                       /    \            |
  38.                      /      \           |
  39.                     /        \          |
  40.                  Field 2    szConst    NE
  41.               (STATE/PROV)   (HI)     /  \
  42.                                      /    \
  43.                                     /      \
  44.                                 Field1     fConst
  45.                              (CUSTOMER NO)(1624.0)
  46. */
  47. //
  48. //==============================================================
  49. void
  50. FiltCont (void)
  51. {
  52.     hDBIDb          hDb = 0;        // Handle to the database.
  53.     hDBICur         hCur = 0;       // Handle to the table.
  54.     DBIResult       rslt;           // Return value from IDAPI functions.
  55.     pBYTE           pcanExpr;       // Structure containing
  56.                                     //   filter info.
  57.     hDBIFilter      hFilter;        // Filter handle.
  58.     UINT16          uSizeNodes;     // Size of the nodes in the
  59.                                     //   tree.
  60.     UINT16          uSizeCanExpr;   // Size of the header
  61.                                     //   information.
  62.     UINT32          uSizeLiterals;  // Size of the literals.
  63.     UINT32          uTotalSize;     // Total size of the filter
  64.                                     //   expression.
  65.     UINT32          uNumRecs  = 10; // Number of records to
  66.                                     //   display.
  67.     CANExpr         canExp;         // Contains the header
  68.                                     //   information.
  69.  
  70.     struct {
  71.        CANBinary BinaryNode1;
  72.        CANBinary  BinaryNode2;
  73.        CANField  FieldNode1;
  74.        CANConst  ConstantNode1;
  75.        CANUnary UnaryNode1;
  76.        CANBinary  BinaryNode3;
  77.        CANField  FieldNode2;
  78.        CANConst  ConstantNode2;
  79.     } Nodes = {                     // Nodes of the filter tree.
  80.     {
  81.         // Offset 0. Node 1.  sizeof(Nodes.BinaryNode1)
  82.         nodeBINARY,                 // canBinary.nodeClass
  83.         canAND,                     // canBinary.canOp
  84.         sizeof(Nodes.BinaryNode1),  // canBinary.iOperand1 - node 2
  85.  
  86.         sizeof(Nodes.BinaryNode1) + sizeof(Nodes.BinaryNode2) +
  87.         sizeof(Nodes.FieldNode1) + sizeof(Nodes.ConstantNode1),
  88.                                     // canBinary.iOperand2 - node 5
  89.     },
  90.     {
  91.         // Offset 8. Node 2.  sizeof(Nodes.BinaryNode2)
  92.         nodeBINARY,                 // canBinary.nodeClass
  93.         canEQ ,                     // canBinary.canOp
  94.         sizeof(Nodes.BinaryNode1) + sizeof(Nodes.BinaryNode2),
  95.                                     // canBinary.iOperand1 - node 3
  96.  
  97.         sizeof(Nodes.BinaryNode1) + sizeof(Nodes.BinaryNode2) +
  98.         sizeof(Nodes.FieldNode1),   // canBinary.iOperand2 - node 4
  99.     },
  100.     {
  101.         // Offset 16. Node 3. sizeof(Nodes.FieldNode1)
  102.         nodeFIELD,                  // canField.nodeClass
  103.         canFIELD,                   // canField.canOp
  104.         5,                          // canField.iFieldNum
  105.         12,                         // canField.iNameOffset: szField2
  106.     },                              //   is the literal at offset
  107.     {                               //   strlen(szField1) + 1
  108.  
  109.         // Offset 24. Node 4. sizeof(Nodes.ConstantNode1)
  110.         nodeCONST,                  // canConst.nodeClass
  111.         canCONST,                   // canConst.canOp
  112.         fldZSTRING,                 // canConst.iType
  113.         3,                          // canConst.iSize
  114.         31,                         // canConst.iOffset: fconst is
  115.     },                              //   the literal at offset
  116.     {                               //   strlen(szField1) + 1 +
  117.                                     //   sizeof(fConst) +
  118.                                     //   strlen(szField2) + 1
  119.  
  120.         // Offset 34. Node 5. sizeof(Nodes.UnaryNode1)
  121.         nodeUNARY,      // canBinary.nodeClass
  122.         canCONTINUE,    // canBinary.canOp
  123.         sizeof(Nodes.BinaryNode1) + sizeof(Nodes.BinaryNode2) +
  124.  
  125.         sizeof(Nodes.FieldNode1) + sizeof(Nodes.ConstantNode1) +
  126.         sizeof(Nodes.UnaryNode1),   // canBinary.iOperand1 - node 6
  127.     },                              //   Offsets in the Nodes array
  128.     {
  129.         // Offset 40. Node 6. sizeof(Nodes.BinaryNode3)
  130.         nodeBINARY,     // canBinary.nodeClass
  131.         canNE ,         // canBinary.canOp
  132.         sizeof(Nodes.BinaryNode1) + sizeof(Nodes.BinaryNode2) +
  133.         sizeof(Nodes.FieldNode1) + sizeof(Nodes.ConstantNode1) +
  134.         sizeof(Nodes.UnaryNode1) + sizeof(Nodes.BinaryNode3),
  135.                                     // canBinary.iOperand1 - node 7
  136.  
  137.         sizeof(Nodes.BinaryNode1) + sizeof(Nodes.BinaryNode2) +
  138.         sizeof(Nodes.FieldNode1) + sizeof(Nodes.ConstantNode1) +
  139.         sizeof(Nodes.UnaryNode1) + sizeof(Nodes.BinaryNode3) +
  140.         sizeof(Nodes.FieldNode2),   // canBinary.iOperand2 - node 8
  141.     },
  142.     {
  143.         // Offset 48. Node 7. sizeof(Nodes.FieldNode2)
  144.         nodeFIELD,                  // canField.nodeClass
  145.         canFIELD,                   // canField.canOp
  146.         1,                          // canField.iFieldNum
  147.         0,                          // canField.iNameOffset:
  148.     },                              //   szField1 is the literal at
  149.     {                               //   offset 0.
  150.  
  151.         // Offset 56. Node 8. Size 14 Bytes
  152.         nodeCONST,                  // canConst.nodeClass
  153.         canCONST,                   // canConst.canOp
  154.         fldFLOAT,                   // canConst.iType
  155.         sizeof(fConst),             // canConst.iSize
  156.         23,                         // canConst.iOffset: fconst is
  157.     }};                             //   the literal at offset
  158.                                     //   strlen(szField1) + 1 +
  159.                                     //   strlen(szField2) + 1
  160.  
  161.     Screen("*** Continue Filter Example ***\r\n");
  162.  
  163.     BREAK_IN_DEBUGGER();
  164.  
  165.     Screen("    Initializing IDAPI...");
  166.     if (InitAndConnect(&hDb) != DBIERR_NONE)
  167.     {
  168.         Screen("\r\n*** End of Example ***");
  169.         return;
  170.     }
  171.  
  172.     Screen("    Setting the database directory...");
  173.     rslt = DbiSetDirectory(hDb, (pCHAR)szTblDirectory);
  174.     ChkRslt(rslt, "SetDirectory");
  175.  
  176.     Screen("    Open the %s table...", szTblName);
  177.     rslt = DbiOpenTable(hDb, (pCHAR)szTblName, (pCHAR)szTblType, NULL, NULL, 0,
  178.                         dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE, NULL,
  179.                         &hCur);
  180.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  181.     {
  182.         CloseDbAndExit(&hDb);
  183.         Screen("\r\n*** End of Example ***");
  184.         return;
  185.     }
  186.  
  187.     // Go to the beginning of the table
  188.     rslt = DbiSetToBegin(hCur);
  189.     ChkRslt(rslt, "SetToBegin");
  190.  
  191.     Screen("\r\n    Display the %s table...", szTblName);
  192.     DisplayTable(hCur, uNumRecs);
  193.  
  194.     // Size of the nodes.
  195.     uSizeNodes      = sizeof(Nodes);
  196.     // Size of the literals.
  197.     uSizeLiterals   = strlen(szField1) + 1 + sizeof(fConst) +
  198.                       strlen(szField2) + 1 + strlen(szConst)
  199.                       + 1;
  200.     // Size of the header information.
  201.     uSizeCanExpr    = sizeof(CANExpr);
  202.     // Total size of the filter.
  203.     uTotalSize      = uSizeCanExpr + uSizeNodes + uSizeLiterals;
  204.     // Initialize the header information
  205.     canExp.iVer = 1; // Version.
  206.     canExp.iTotalSize = (UINT16)uTotalSize; // Total size of the filter.
  207.     canExp.iNodes = 8; // Number of nodes.
  208.     canExp.iNodeStart = uSizeCanExpr; // The offset in the
  209.                                       //   buffer where the
  210.                                       //   expression nodes
  211.                                       //   start.
  212.     // The offset in the buffer where the literals start.
  213.     canExp.iLiteralStart = (UINT16)(uSizeCanExpr + uSizeNodes);
  214.  
  215.     // Allocate contiguous memory space to hold
  216.     // 1) Header information  i.e. the CANExpr structure
  217.     // 2) Compare, field and constant nodes  i.e. the Nodes structure
  218.     // 3) Literal and constant pool  i.e. field names and constant values
  219.     pcanExpr = (pBYTE)malloc(uTotalSize * sizeof(BYTE));
  220.     if (pcanExpr == NULL)
  221.     {
  222.         Screen("    Could not allocate memory...");
  223.         DbiCloseCursor(&hCur);
  224.         CloseDbAndExit(&hDb);
  225.         Screen("\r\n*** End of Example ***");
  226.         return;
  227.     }
  228.  
  229.     // Initialize the filter expression by placing header, nodes and
  230.     // pool into pcanexpr
  231.  
  232.     // Move the literal into pcanexpr.  pcanExpr will now look as follows:
  233.     // |**canExp*|                 |                                  |
  234.     // | CANExpr |    All Nodes    |      Literal, Constant Pool      |
  235.     // |--------------------------------------------------------------|
  236.     // 0                                                      sizeof(uTotalSize)
  237.     memmove(pcanExpr, &canExp, uSizeCanExpr); // Insert Header Information
  238.  
  239.     // Move the literal into pcanexpr.  pcanExpr will now look as follows:
  240.     // |**canExp*|**Node Structure*|                                  |
  241.     // | CANExpr |    All Nodes    |      Literal, Constant Pool      |
  242.     // |--------------------------------------------------------------|
  243.     // 0                                                      sizeof(uTotalSize)
  244.     memmove(&pcanExpr[uSizeCanExpr], &Nodes, uSizeNodes); // Insert Nodes
  245.  
  246.     // Move the literal into pcanexpr.  pcanExpr will now look as follows:
  247.     // |**canExp*|**Node Structure*|*szField1*                        |
  248.     // | CANExpr |    All Nodes    |      Literal, Constant Pool      |
  249.     // |--------------------------------------------------------------|
  250.     // 0                                                      sizeof(uTotalSize)
  251.     memmove(&pcanExpr[uSizeCanExpr + uSizeNodes],
  252.             szField1, strlen(szField1) + 1); // First litteral
  253.  
  254.     // Move the literal into pcanexpr.  pcanExpr will now look as follows:
  255.     // |**canExp*|**Node Structure*|*szField1*szField2*               |
  256.     // | CANExpr |    All Nodes    |      Literal, Constant Pool      |
  257.     // |--------------------------------------------------------------|
  258.     // 0                                                      sizeof(uTotalSize)
  259.     memmove(&pcanExpr[(uSizeCanExpr + uSizeNodes +
  260.                       strlen(szField1) + 1)],
  261.             szField2, strlen(szField2) + 1); // Second litteral
  262.  
  263.     // Move the literal into pcanexpr.  pcanExpr will now look as follows:
  264.     // |**canExp*|**Node Structure*|*szField1*szField2*fConst*        |
  265.     // | CANExpr |    All Nodes    |      Literal, Constant Pool      |
  266.     // |--------------------------------------------------------------|
  267.     // 0                                                      sizeof(uTotalSize)
  268.     memmove(&pcanExpr[(uSizeCanExpr + uSizeNodes +
  269.                       strlen(szField1) + 1 +
  270.                       strlen(szField2) + 1)],
  271.             &fConst, sizeof(fConst)); // First Constant
  272.  
  273.     // Move the literal into pcanexpr.  pcanExpr will now look as follows:
  274.     // |**canExp*|**Node Structure*|*szField1*szField2*fConst*szConst*|
  275.     // | CANExpr |    All Nodes    |      Literal, Constant Pool      |
  276.     // |--------------------------------------------------------------|
  277.     // 0                                                      sizeof(uTotalSize)
  278.     memmove(&pcanExpr[(uSizeCanExpr + uSizeNodes +
  279.                       strlen(szField1) + 1 +
  280.                       strlen(szField2) + 1 + sizeof(fConst))],
  281.             szConst, strlen(szConst) + 1); // Second Constant
  282.  
  283.     rslt = DbiSetToBegin(hCur);
  284.     ChkRslt(rslt, "SetToBegin");
  285.  
  286.     Screen("\r\n    Add a filter to the %s table which will"
  287.            " limit the records\r\n        in the result set"
  288.            " to those whose %s field is equal to '%s', until\r\n"
  289.            "        the first record where the %s field is equal to %.1lf...",
  290.            szTblName, szField2, szConst, szField1, fConst);
  291.     rslt = DbiAddFilter(hCur, 0L, 1, FALSE, (pCANExpr)pcanExpr,
  292.                         NULL, &hFilter);
  293.     if (ChkRslt(rslt, "AddFilter") != DBIERR_NONE)
  294.     {
  295.         rslt = DbiCloseCursor(&hCur);
  296.         ChkRslt(rslt, "CloseCursor");
  297.         free(pcanExpr);
  298.         CloseDbAndExit(&hDb);
  299.         Screen("\r\n*** End of Example ***");
  300.         return;
  301.     }
  302.  
  303.     // Activate the filter.
  304.     Screen("    Activate the filter on the %s table...",
  305.            szTblName);
  306.     rslt = DbiActivateFilter(hCur, hFilter);
  307.     ChkRslt(rslt, "ActivateFilter");
  308.  
  309.     rslt = DbiSetToBegin(hCur);
  310.     ChkRslt(rslt, "SetToBegin");
  311.  
  312.     Screen("\r\n    Display the %s table with the filter"
  313.            " set...", szTblName);
  314.     DisplayTable(hCur, uNumRecs);
  315.  
  316.     Screen("\r\n    Deactivate the filter...");
  317.     rslt = DbiDeactivateFilter(hCur, hFilter);
  318.     ChkRslt(rslt, "DeactivateFilter");
  319.  
  320.     Screen("\r\n    Drop the filter...");
  321.     rslt = DbiDropFilter(hCur, hFilter);
  322.     ChkRslt(rslt, "DropFilter");
  323.  
  324.     rslt = DbiCloseCursor(&hCur);
  325.     ChkRslt(rslt, "CloseCursor");
  326.  
  327.     free(pcanExpr);
  328.  
  329.     Screen("    Close the database and exit IDAPI...");
  330.     CloseDbAndExit(&hDb);
  331.  
  332.     Screen("\r\n*** End of Example ***");
  333. }
  334.