home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bde / snipit.pak / IDXEXPR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-24  |  12.2 KB  |  329 lines

  1. // BDE - (C) Copyright 1995 by Borland International
  2.  
  3. // idxexpr.c
  4. #include "snipit.h"
  5.  
  6. #define NAMELEN  30 // Length of the name field.
  7.  
  8. static const char szTblName[] = "order";
  9. static const char szMasterTblName[] = "cust";
  10.  
  11. static const char szTblType[] = szDBASE;
  12.  
  13. // Key expression used to link the detail table.
  14. static SNIPFAR char szMstrExp[] = "TRIM(CITY) + \", \" + STATE_PROV";
  15.  
  16. // Field descriptor used in creating a table.
  17. static SNIPFAR FLDDesc fldDesc[] = {
  18.                           { // Field 1 - Customer Number
  19.                             1,            // Field number
  20.                             "CITY_STATE", // Field name
  21.                             fldZSTRING,   // Field type
  22.                             fldUNKNOWN,   // Field subtype
  23.                             35,           // Field size ( 1 or 0, except
  24.                                           //   BLOB or CHAR field )
  25.                             0,            // Decimal places   ( 0 )
  26.                                           //   computed
  27.                             0,            // Offset in record ( 0 )
  28.                             0,            // Length in bytes  ( 0 )
  29.                             0,            // For NULL bits    ( 0 )
  30.                             fldvNOCHECKS, // Validity checks  ( 0 )
  31.                             fldrREADWRITE // Rights
  32.                           },
  33.                           { // Field 2 - Name
  34.                             2, "NAME", fldZSTRING, fldUNKNOWN,
  35.                             NAMELEN, 0, 0, 0, 0,
  36.                             fldvNOCHECKS, fldrREADWRITE
  37.                           },
  38.                           { // Field 3 - Phone
  39.                             3, "Phone", fldZSTRING, fldUNKNOWN,
  40.                             15, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE
  41.                           }
  42.                      };  // Array of field descriptors.
  43.  
  44. // Index descriptor - describes the Index associated with the
  45. // detail table.
  46. static SNIPFAR IDXDesc idxDesc[] = {
  47.                     {  // Production Index - expression index.
  48.                        "order.mdx",     // Name
  49.                        NULL,            // Number
  50.                        {"CITY_STATE"},  // Tag name ( for dBASE )
  51.                        { NULL },        // Optional format ( BTREE,
  52.                                         //   HASH, etc )
  53.                        FALSE,           // Primary?
  54.                        FALSE,           // Unique?
  55.                        FALSE,           // Descending?
  56.                        TRUE,            // Maintained?
  57.                        FALSE,           // Subset?
  58.                        FALSE,           // Expression index?
  59.                        NULL,            // For QBE only
  60.                        1,               // Fields in key
  61.                        1,               // Length in bytes
  62.                        FALSE,           // Index out of date?
  63.                        0,               // Key type of expression
  64.                        { 1 },           // Array of field numbers
  65.                        { NULL},         // Key expression
  66.                        { NULL },        // Key condition
  67.                        FALSE,           // Case insensitive
  68.                        0,               // Block size in bytes
  69.                        0                // Restructure number
  70.                     }
  71.                 };
  72.  
  73. static DBIResult InitTable(phDBIDb phDb);
  74. static DBIResult AddRecord(phDBICur phCur, pCHAR pszCityState, pCHAR pszName,
  75.                            pCHAR pszPhone);
  76.  
  77. //=====================================================================
  78. //  Function:
  79. //          IndexExpr();
  80. //
  81. //  Description:  
  82. //          This example shows how to create expression indexes and
  83. //          link two tables together based upon the expression index 
  84. //          (which is similar to Set Relation to... in the dBASE language).
  85. //          When the link is established, you will only be able to see a
  86. //          subset of the records in the Detail table which correspond
  87. //          to the current record of the Master table.
  88. //=====================================================================
  89. void
  90. IndexExpr (void)
  91. {
  92.     hDBIDb      hDb;            // Database handle
  93.     hDBICur     hCur;           // Cursor handle to the detail table
  94.     hDBICur     hMCur;          // Cursor handle to the master table
  95.     UINT16      i;              // For looping.
  96.     DBIResult   rslt;           // Return value from IDAPI functions
  97.  
  98.     Screen("*** dBASE Expression Index Example ***\r\n");
  99.  
  100.     BREAK_IN_DEBUGGER();
  101.  
  102.     Screen("    Initializing IDAPI...");
  103.     if (InitAndConnect(&hDb) != DBIERR_NONE)
  104.     {
  105.  
  106.         Screen("\r\n*** End of Example ***");
  107.         return;
  108.     }
  109.  
  110.     Screen("    Setting the database directory...");
  111.     rslt = DbiSetDirectory(hDb, (pCHAR) szTblDirectory);
  112.     ChkRslt(rslt, "SetDirectory");
  113.  
  114.     // Create the table and insert four records.
  115.     if (InitTable(&hDb))
  116.     {
  117.         CloseDbAndExit(&hDb);
  118.         Screen("\r\n*** End of Example ***");
  119.         return;
  120.     }
  121.  
  122.     Screen("    Open the %s table as the detail table (must be opened in"
  123.            " shared mode)...", szTblName);
  124.     rslt = DbiOpenTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType,
  125.                         idxDesc[0].szName, idxDesc[0].szTagName, NULL,
  126.                         dbiREADWRITE, dbiOPENSHARED,
  127.                         xltFIELD, FALSE, NULL, &hCur);
  128.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  129.     {
  130.         CloseDbAndExit(&hDb);
  131.         Screen("\r\n*** End of Example ***");
  132.         return;
  133.     }
  134.  
  135.     Screen("    Open the %s table, which is used as the master table...",
  136.            szMasterTblName);
  137.     rslt = DbiOpenTable(hDb, (pCHAR) szMasterTblName, (pCHAR) szTblType,
  138.                         NULL, NULL, NULL,  dbiREADWRITE, dbiOPENSHARED,
  139.                         xltFIELD, FALSE, NULL, &hMCur);
  140.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  141.     {
  142.         CloseDbAndExit(&hDb);
  143.         Screen("\r\n*** End of Example ***");
  144.         return;
  145.     }
  146.  
  147.     // Go to the top of the master table which is ordered by cust_no.
  148.     rslt = DbiSetToBegin(hMCur);
  149.     ChkRslt(rslt, "SetToBegin");
  150.  
  151.     // Put the Cust table into link mode.
  152.     rslt = DbiBeginLinkMode(&hMCur);
  153.     ChkRslt(rslt, "BeginLinkMode");
  154.  
  155.     // Put the Orders table into link mode.
  156.     rslt = DbiBeginLinkMode(&hCur);
  157.     ChkRslt(rslt, "BeginLinkMode");
  158.  
  159.     // Now link the two cursors/tables together.
  160.     Screen("    Link the two tables togther");
  161.  
  162.     rslt = DbiLinkDetailToExp(hMCur, hCur, 0, (pCHAR) szMstrExp);
  163.     ChkRslt(rslt, "LinkDetailToExp");
  164.  
  165.     // The detail table has matching data only for the first two records 
  166.     //   of the master table.  
  167.     for (i = 0; i < 3; i++)
  168.     {
  169.         // Display the master record.
  170.         Screen("\r\n        This is the master record");
  171.         DisplayTable(hMCur, 1);
  172.  
  173.         // Display all the detail records.
  174.         Screen("\r\n        This is the detail record(s)");
  175.         DisplayTable(hCur, 0);
  176.     }
  177.  
  178.     Screen("\r\n        There are no records in the detail table for the"
  179.            "\r\n        third record in the master table.  Therefore, it"
  180.            "\r\n        should come up blank.");
  181.  
  182.     Screen("\r\n    End the link...");
  183.     rslt = DbiUnlinkDetail(hCur);
  184.     ChkRslt(rslt, "EndLinkMode");
  185.  
  186.     // Take the Customer table out of link mode.
  187.     rslt = DbiEndLinkMode(&hMCur);
  188.     ChkRslt(rslt, "EndLinkMode");
  189.  
  190.     // Take the Orders table out of link mode.
  191.     rslt = DbiEndLinkMode(&hCur);
  192.     ChkRslt(rslt, "EndLinkMode");
  193.  
  194.     Screen("    Close the %s table...", szMasterTblName);
  195.     rslt = DbiCloseCursor(&hMCur);
  196.     ChkRslt(rslt, "CloseCursor");
  197.  
  198.     Screen("    Close the %s table...", szTblName);
  199.     rslt = DbiCloseCursor(&hCur);
  200.     ChkRslt(rslt, "CloseCursor");
  201.  
  202.     Screen("    Delete the %s table...", szTblName);
  203.     rslt = DbiDeleteTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType);
  204.     ChkRslt(rslt, "DeleteTable");
  205.  
  206.     Screen("    Close the database and exit IDAPI...");
  207.     CloseDbAndExit(&hDb);
  208.  
  209.     Screen("\r\n*** End of Example ***");
  210. }
  211.  
  212. //=====================================================================
  213. //  Function:
  214. //          InitTable(phDb);
  215. //
  216. //  Input:  phDb    - Pointer to the database handle
  217. //
  218. //  Return: Result of the table initialization
  219. //
  220. //  Desc:   This function will create a table and fill the table
  221. //          with a number of records.  The function uses
  222. //          another function called AddRecord which adds records to
  223. //          the table.
  224. //=====================================================================
  225. DBIResult
  226. InitTable (phDBIDb phDb)
  227. {
  228.     DBIResult   rslt;               // Value returned from IDAPI functions
  229.     hDBICur     hCur;               // Cursor handle for the table that is
  230.                                     //   created
  231.     CRTblDesc   crTblDsc;           // Table descriptor
  232.     BOOL        bOverWrite = TRUE;  // Overwrite, yes/no flag
  233.  
  234.     // The number of fields in the table.
  235.     const unsigned uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]);
  236.  
  237.     // Number of indexes to be created when the table is created.
  238.     const unsigned uNumIndexes = sizeof(idxDesc) / sizeof(idxDesc[0]);
  239.  
  240.     // Initialize the Table Create descriptor.
  241.     memset(&crTblDsc, 0, sizeof(CRTblDesc));
  242.     strcpy(crTblDsc.szTblName, szTblName);
  243.     strcpy(crTblDsc.szTblType, szTblType);
  244.     crTblDsc.iFldCount     = uNumFields;
  245.     crTblDsc.pfldDesc      = fldDesc;
  246.     crTblDsc.iIdxCount     = uNumIndexes;
  247.     crTblDsc.pidxDesc      = idxDesc;
  248.  
  249.     Screen("    Creating the table and indexes...");
  250.     rslt = DbiCreateTable(*phDb, bOverWrite, &crTblDsc);
  251.     if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
  252.     {
  253.         return rslt;
  254.     }
  255.  
  256.     rslt = DbiOpenTable(*phDb, (pCHAR) szTblName, (pCHAR) szTblType,
  257.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
  258.                         xltFIELD, FALSE, NULL, &hCur);
  259.     ChkRslt(rslt, "OpenTable");
  260.  
  261.     Screen("    Adding records to the table...");
  262.     rslt = AddRecord(&hCur, "Kapaa Kauai, HI", "Kapaa Dive Shoppe",
  263.                      "(408)-321-1729");
  264.     rslt = AddRecord(&hCur, "Kapaa Kauai, HI", "Kapaa Dive Shoppe",
  265.                      "(408)-321-1729");
  266.     rslt = AddRecord(&hCur, "Freeport, ", "Unisco", "(415)-567-1799");
  267.     rslt = AddRecord(&hCur, "Freeport, ", "Divers", "(415)-365-6159");
  268.  
  269.     rslt = DbiCloseCursor(&hCur);
  270.     ChkRslt(rslt, "CloseCursor");
  271.  
  272.     return rslt;
  273. }
  274.  
  275. //=====================================================================
  276. //  Function:
  277. //          AddRecord(phCur, pszCityState, pszName, pszPhone);
  278. //
  279. //  Input:  phCur           - Pointer to the cursor handle
  280. //          pszCityState    - City and state
  281. //          pszName         - Customer name
  282. //          pszPhone        - Customer phone number
  283. //
  284. //  Return: Result of adding the record to the table
  285. //
  286. //  Desc:   This function will add a record to the given table.
  287. //=====================================================================
  288. DBIResult
  289. AddRecord (phDBICur hCur, pCHAR pszCityState, pCHAR pszName, pCHAR pszPhone)
  290. {
  291.     DBIResult   rslt;           // Value returned from IDAPI functions
  292.     CURProps    TblProps;       // Table Properties
  293.     pBYTE       pRecBuf;        // Record Buffer
  294.  
  295.     //  Allocate a record buffer.
  296.     rslt = DbiGetCursorProps(*hCur, &TblProps);
  297.     ChkRslt(rslt, "GetCursorProps");
  298.  
  299.     pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE));
  300.     if (pRecBuf == NULL)
  301.     {
  302.         return DBIERR_NOMEMORY;
  303.     }
  304.  
  305.     // Start with a clean record buffer.
  306.     rslt = DbiInitRecord(*hCur, pRecBuf);
  307.     ChkRslt(rslt, "InitRecord");
  308.  
  309.     // City_state.
  310.     rslt = DbiPutField(*hCur, 1, pRecBuf, (pBYTE)pszCityState);
  311.     ChkRslt(rslt, "PutField");
  312.  
  313.     // Customer name.
  314.     rslt = DbiPutField(*hCur, 2, pRecBuf, (pBYTE) pszName);
  315.     ChkRslt(rslt, "PutField");
  316.  
  317.     // Customer phone number.
  318.     rslt = DbiPutField(*hCur, 3, pRecBuf, (pBYTE) pszPhone);
  319.     ChkRslt(rslt, "PutField");
  320.  
  321.     // Now insert the record.
  322.     rslt = DbiInsertRecord(*hCur, dbiNOLOCK, pRecBuf);
  323.     ChkRslt(rslt, "InsertRecord");
  324.  
  325.     free(pRecBuf);
  326.  
  327.     return rslt;
  328. }
  329.