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

  1. // BDE32 3.x - (C) Copyright 1996 by Borland International
  2.  
  3. // filter.c
  4. #include "snipit.h"
  5.  
  6. //=====================================================================
  7. //  Function:
  8. //          Filter();
  9. //
  10. //  Description:
  11. //          This example shows how to use filters to limit the result
  12. //          set of a table. Filters perform a similar function to
  13. //          ranges, but more powerful operations are supported.
  14. //=====================================================================
  15. void
  16. Test(void)
  17. {
  18.     hDBIDb     hDb;        // Handle to the database
  19.     hDBICur    hCur;       // Handle to the Cursor
  20.     hDBIFilter hFilter;    // Handle to the Filter
  21.  
  22.     DBIResult  iErr;
  23.     int        i;
  24.  
  25.  
  26.     pCURProps  pCProps;    // Schema Descriptors Pointers
  27.     pFLDDesc   pFldDescs;
  28.  
  29.     pUINT32    pRecCnt;
  30.  
  31.  
  32.     pCHAR      pcanExpr;   // Filter Pointers
  33.     pCANExpr   pTemp;
  34.     pCANBinary pBinary;
  35.     pCANField  pField;
  36.     pCANConst  pConst;
  37.     pCHAR      pLiteral;
  38.  
  39.  
  40.     INT16      iCanExprBlkSz, iNodeBlkSz, iLiteralBlkSz, iExprBlkSz;
  41.     INT16      iCanBinary, iCanField, iCanConst;
  42.  
  43.  
  44.     FLOAT      iConstant = 1400;
  45.  
  46.  
  47.     Screen("*** Test ***\r\n");
  48.  
  49.     BREAK_IN_DEBUGGER();
  50.  
  51.     Screen("    Initializing IDAPI...\r\n");
  52.     if (ChkRslt(DbiInit(NULL), DBIERR_NONE, "    Error - Init")
  53.         != DBIERR_NONE) // Check if successfull
  54.     {
  55.         Screen("\r\n*** End of Example ***");
  56.         return;
  57.     }
  58.  
  59.     // Open the standard database. Notice that we are opening the
  60.     // database in READWRITE mode and SHARED mode.
  61.     Screen("    Opening Standard Database...");
  62.     if (ChkRslt(DbiOpenDatabase("", 0, dbiREADWRITE, dbiOPENSHARED,
  63.                                 NULL, NULL, NULL, NULL, &hDb),
  64.         DBIERR_NONE, "    Error - OpenDatabase.") != DBIERR_NONE)
  65.     {
  66.         // Clean up since an error occured
  67.         Screen("    Exit IDAPI...");
  68.         ChkRslt(DbiExit(), DBIERR_NONE, "    Error - Exit.");
  69.         Screen("\r\n*** End of Example ***");
  70.         return;
  71.     }
  72.  
  73.     // Need to set the directory which the database uses by default.
  74.     // This way table names do not have to be queslified with a path....
  75.     Screen("    Set the directory which is used by the database...");
  76.     ChkRslt(DbiSetDirectory(hDb, (pCHAR)szTblDirectory), DBIERR_NONE,
  77.             "    Error - SetDirectory.");
  78.  
  79.  
  80.     //
  81.     // Open a Paradox table
  82.     // 
  83.     ChkRslt( DbiOpenTable( hDb, "ORDERS.DB", szPARADOX, "", "", 0,
  84.         dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE, NULL, &hCur ),
  85.         DBIERR_NONE, "    Error - Open Table");
  86.  
  87.  
  88.     pCProps   = (pCURProps) malloc( sizeof(CURProps) );
  89.     for ( i = 0; i < sizeof(CURProps); i++) *((pCHAR)pCProps+i) = 0;
  90.     ChkRslt(DbiGetCursorProps(hCur, pCProps), DBIERR_NONE, "    Error - Get Props");
  91.  
  92.  
  93.  
  94.     pFldDescs = (pFLDDesc) malloc( sizeof(FLDDesc) * pCProps->iFields);
  95.     for ( i = 0; i < sizeof(FLDDesc) * pCProps->iFields; i++) *((pCHAR)pFldDescs+i) = 0;
  96.     ChkRslt(DbiGetFieldDescs(hCur, pFldDescs ), DBIERR_NONE, "    Error - Get FldDescs");
  97.  
  98.  
  99.  
  100.     if( pFldDescs[0].iFldType == fldFLOAT )
  101.     {
  102.       //
  103.       // Filter Expression: F1 > 1400
  104.       // ------------------------------------------------------
  105.       // Expression Nodes Tree:
  106.       // 
  107.       //      Root(>)
  108.       //      (canBINARY) 
  109.       //     /      \
  110.       //    /        \
  111.       //   Opr2(F1)   Opr1(1400)
  112.       //  (canFIELD) (canCONST) 
  113.       //           
  114.       // 
  115.       // 
  116.  
  117.  
  118.       iCanBinary    = sizeof(CANBinary);   // Alternative: use sizeof(CANNode)
  119.       iCanField     = sizeof(CANField);    //        in generic build function
  120.       iCanConst     = sizeof(CANConst);    //        to allow all Node Struct
  121.  
  122.  
  123.       //
  124.       // Compute Expression Block Size
  125.       // 
  126.       iCanExprBlkSz = sizeof(CANExpr);
  127.  
  128.       iNodeBlkSz    = iCanBinary + iCanField + iCanConst;
  129.  
  130.       iLiteralBlkSz = strlen(pFldDescs[0].szName) + 1 + pFldDescs[0].iLen;
  131.  
  132.       iExprBlkSz    = iCanExprBlkSz + iNodeBlkSz + iLiteralBlkSz;
  133.  
  134.  
  135.       pcanExpr = malloc(iExprBlkSz);
  136.       for( i = 0; i < iExprBlkSz; i++ ) *(pcanExpr + i) = 0;
  137.  
  138.    
  139.       //
  140.       // Setup CANExpr Block
  141.       //
  142.       pTemp = (pCANExpr)pcanExpr;
  143.       pTemp->iVer          = CANEXPRVERSION;
  144.       pTemp->iTotalSize    = iExprBlkSz;
  145.       pTemp->iNodes        = 3;
  146.       pTemp->iNodeStart    = iCanExprBlkSz;
  147.       pTemp->iLiteralStart = iCanExprBlkSz + iNodeBlkSz;
  148.  
  149.  
  150.  
  151.  
  152.       // Setup nodes: BINARY GT
  153.       pBinary = (pCANBinary) &pcanExpr[iCanExprBlkSz];
  154.  
  155.       pBinary->nodeClass     = nodeBINARY;
  156.       pBinary->canOp         = canGT;
  157.                                                         // Operand Offset is computed by using address of iNodeStart
  158.       pBinary->iOperand1     = iCanBinary;              // iNodeStart +sizeof BINARY node is address of Operand 1
  159.       pBinary->iOperand2     = iCanBinary + iCanField;  // iNodeStart +sizeof BINARY node +sizeof FIELD node is address of Operand 2
  160.  
  161.  
  162.       // FIELD 1,0
  163.       pField = (pCANField) &pcanExpr[iCanExprBlkSz+iCanBinary];
  164.  
  165.       pField->nodeClass      = nodeFIELD;
  166.       pField->canOp          = canFIELD;
  167.       pField->iFieldNum      = 1;                       // Field Name where filter is applied
  168.                                                         // FieldName string is computed by using address of iLiteralStart
  169.       pField->iNameOffset    = 0;                       // iLiteral is the address of Field Name String
  170.  
  171.  
  172.       // CONSTANT FLOAT, +
  173.       pConst = (pCANConst) &pcanExpr[iCanExprBlkSz+iCanBinary+iCanField];
  174.  
  175.       pConst->nodeClass      = nodeCONST;
  176.       pConst->canOp          = canCONST;                 
  177.       pConst->iType          = pFldDescs[0].iFldType;   // use idapi(logical) field type
  178.       pConst->iSize          = pFldDescs[0].iLen;       // use length of idapi(logical) field type
  179.       pConst->iOffset        = strlen(pFldDescs[0].szName) + 1;  // value of constant follow FieldName string
  180.                                                                  // null terminator of string must be included
  181.  
  182.  
  183.       // Set Literals:
  184.       pLiteral = (pCHAR) &pcanExpr[iCanExprBlkSz + iNodeBlkSz];
  185.  
  186.       // Field Name for Field node
  187.       strcpy( &pLiteral[0], pFldDescs[0].szName );      // move FieldName to Literal Pool 
  188.  
  189.       // Constant FLOAT value for constant node
  190.       memcpy( &pLiteral[strlen(pFldDescs[0].szName)+1],
  191.               (pCHAR)&iConstant, pFldDescs[0].iLen);    // move 1400 right after FieldName string
  192.  
  193.  
  194.       // ------------------------------------------------------
  195.       //
  196.       // View a filtered cursor
  197.  
  198.       ChkRslt(DbiAddFilter( hCur, 0, 10, FALSE, (pCANExpr)pcanExpr, NULL, &hFilter ),
  199.               DBIERR_NONE, "     Error - Add Filter");
  200.       ChkRslt(DbiActivateFilter( hCur, hFilter ), DBIERR_NONE, "    Error - Activate Filter");
  201.       ChkRslt(DbiSetToBegin( hCur ), DBIERR_NONE, "    Error - Set BOF");
  202.  
  203.       pRecCnt = (pUINT32) malloc( sizeof(UINT32) );
  204.       ChkRslt(DbiGetRecordCount(hCur, pRecCnt), DBIERR_NONE, "     Error - Get Rec Cnt");
  205.  
  206.       DisplayTable(hCur, *pRecCnt);
  207.  
  208.       //
  209.       // Completed
  210.       //
  211.       // ------------------------------------------------------
  212.       // For a more complex filter Expression,
  213.       // a more complex node tree is needed as illustrated in
  214.       // in the following diagram:
  215.       //
  216.       // Filter Expression: F1 > 1400 AND 1500 > F1
  217.       // ------------------------------------------------------
  218.       // Expression Nodes Tree:
  219.       // 
  220.       //             Root(AND)
  221.       //            (canBINARY)  
  222.       //           /           \
  223.       //          /             \
  224.       //         /               \
  225.       //      Node(>)             Node(>)
  226.       //      (canBINARY)         (canBINARY) 
  227.       //     /      \               /       \
  228.       //    /        \             /         \
  229.       //  Opr1(F1)   Opr2(1400) Opr1(1500)    Opr2(F1)
  230.       // (canFIELD) (canCONST)  (canCONST)   (canFIELD)
  231.       //           
  232.       // 
  233.       // ------------------------------------------------------
  234.       // 
  235.       free((pBYTE)pcanExpr);
  236.       free((pBYTE)pFldDescs);
  237.       free((pBYTE)pCProps);
  238.       free((pBYTE)pRecCnt);
  239.     }
  240.     else
  241.       Screen( "\r\n   Abort: Field 1 not numeric\r\n");
  242.  
  243.  
  244.     // Close the Cursor 
  245.     DbiCloseCursor(&hCur);
  246.  
  247.  
  248.     // Close the standard database
  249.     Screen("    Close the standard database...");
  250.     ChkRslt(DbiCloseDatabase(&hDb), DBIERR_NONE,
  251.             "    Error - CloseDatabase.");
  252.  
  253.  
  254.     Screen("    Exit IDAPI...");
  255.     ChkRslt(DbiExit(), DBIERR_NONE, "    Error - Exit.");
  256.  
  257.     Screen("\r\n*** End of Example ***");
  258. }
  259.