home *** CD-ROM | disk | FTP | other *** search
/ Total C++ 2 / TOTALCTWO.iso / borland / 32snipit.pak / IDXDBASE.C < prev    next >
C/C++ Source or Header  |  1997-05-06  |  16KB  |  430 lines

  1. // BDE32 3.x - (C) Copyright 1996 by Borland International
  2.  
  3. // idxdbase.c
  4. #include "snipit.h"
  5.  
  6. #define NAMELEN  10 // Length of the name field.
  7. #define PLACELEN 20 // Length of the POB field.
  8. #define DATELEN  11 // Display length of a date field: mm\dd\yyyy
  9.  
  10. static const char szTblName[] = "people";
  11. static const char szTblType[] = szDBASE;
  12.  
  13. // Field descriptor used in creating a table.
  14. static SNIPFAR FLDDesc fldDesc[] = {
  15.     { // Field 1 - First Name
  16.         1,            // Field number
  17.         "FirstName",      // Field name
  18.         fldZSTRING,   // Field type
  19.         fldUNKNOWN,   // Field subtype
  20.         NAMELEN,      // Field size ( 1 or 0, except
  21.                       //     BLOb or CHAR field )
  22.         0,            // Decimal places ( 0 )
  23.                       //     computed
  24.         0,            // Offset in record ( 0 )
  25.         0,            // Length in bytes  ( 0 )
  26.         0,            // For Null bits    ( 0 )
  27.         fldvNOCHECKS, // Validity checks   ( 0 )
  28.         fldrREADWRITE // Rights
  29.     },
  30.     { // Field 2 - Middle Name
  31.         2, "MidName", fldZSTRING, fldUNKNOWN,
  32.         NAMELEN, 0, 0, 0, 0,
  33.         fldvNOCHECKS, fldrREADWRITE
  34.     },
  35.     { // Field 3 - Last Name
  36.         3, "LName", fldZSTRING, fldUNKNOWN,
  37.         NAMELEN, 0, 0, 0, 0,
  38.         fldvNOCHECKS, fldrREADWRITE
  39.     },
  40.     { // Field 4 - Date of Birth
  41.         4, "DOB", fldDATE, fldUNKNOWN,
  42.         0, 0, 0, 0, 0,
  43.         fldvNOCHECKS, fldrREADWRITE
  44.     },
  45.     { // Field 5 - Place of Birth
  46.         5, "POB", fldZSTRING, fldUNKNOWN,
  47.         PLACELEN, 0, 0, 0, 0,
  48.         fldvNOCHECKS, fldrREADWRITE
  49.     }};  // Array of field descriptors
  50.  
  51. // Index descriptor - describes the index associated with the
  52. // table.
  53. static SNIPFAR IDXDesc idxDesc[] = {
  54.     {  // Composite Production Index
  55.         "",           // Name
  56.         NULL,         // Number
  57.         {"FNAME"},    // Tag Name ( for dBASE )
  58.         { NULL },     // Optional Format ( BTREE,
  59.                       // HASH, etc )
  60.         FALSE,        // Primary?
  61.         FALSE,        // Unique?
  62.         FALSE,        // Descending?
  63.         TRUE,         // Maintained?
  64.         FALSE,        // SubSet?
  65.         TRUE,         // Expression index?
  66.         NULL,         // for QBE only
  67.         3,            // Fields in key
  68.         1,            // Length in bytes
  69.         FALSE,        // Index out of date?
  70.         0,            // Key type of expression
  71.         { 1,2,3 },    // Array of field numbers
  72.         {"FirstName + MidName + LName" },// Key expression
  73.         { 0 },        // Key condition
  74.         FALSE,        // Case insensitive
  75.         0,            // Block size in bytes
  76.         0             // Restructure number
  77.     },
  78.     {  // Single-field production index
  79.         "", NULL, {"LNAME"}, { NULL }, FALSE, FALSE,
  80.         FALSE, TRUE, FALSE, FALSE, NULL, 1, 1, FALSE,
  81.         0, { 3 }, { 0 }, { 0 }, FALSE, 0, 0
  82.     },
  83.     {  // Single-field production index
  84.         "", NULL, {"POB"}, { NULL }, FALSE, FALSE, FALSE,
  85.         TRUE, FALSE, FALSE, NULL, 1, 1, FALSE, 0, { 5 },
  86.         { 0 }, { 0 }, FALSE, 0, 0
  87.     }};
  88.  
  89. static SNIPFAR IDXDesc idxDesc1[] = {
  90.     {  // Expression index, non-maintained .NDX style index
  91.         "FULLNAME.NDX", NULL, { NULL }, { NULL }, FALSE,
  92.         FALSE, FALSE, FALSE, FALSE, TRUE, NULL, 2, 1,
  93.         FALSE, 0, { 1,3 }, {"FirstName + LName"}, { 0 },
  94.         FALSE, 0, 0
  95.     }};
  96.  
  97. static DBIResult InitTable(phDBIDb);
  98. static DBIResult AddRecord(phDBICur, pCHAR, pCHAR, pCHAR, UINT16, UINT16, UINT16,
  99.                            pCHAR);
  100.  
  101. //=====================================================================
  102. //  Function:
  103. //          IndexDBase();
  104. //
  105. //  Description:
  106. //          This example shows how to set up a dBASE table and dBASE
  107. //          indexes.  This includes expression indexes (multiple field
  108. //          indexes) and the particular needs of the common dBASE index.
  109. //=====================================================================
  110. void
  111. IndexDBase (void)
  112. {
  113.     hDBIDb      hDb = 0;       // Database handle
  114.     hDBICur     hCur = 0;      // Cursor handle
  115.     DBIResult   rslt;          // Return value from IDAPI functions
  116.     IDXDesc     *MyDesc;       // Index descriptor
  117.  
  118.     Screen("*** dBASE Index Example ***\r\n");
  119.  
  120.     BREAK_IN_DEBUGGER();
  121.  
  122.     Screen("    Initializing IDAPI...");
  123.     if (InitAndConnect(&hDb) != DBIERR_NONE)
  124.     {                                        
  125.         Screen("\r\n*** End of Example ***");
  126.         return;
  127.     }
  128.  
  129.     Screen("    Setting the database directory...");
  130.     rslt = DbiSetDirectory(hDb, (pCHAR) szTblDirectory);
  131.     ChkRslt(rslt, "SetDirectory");
  132.  
  133.     // Create the table and add four records.
  134.     if (InitTable(&hDb))
  135.     {
  136.         CloseDbAndExit(&hDb);
  137.         Screen("\r\n*** End of Example ***");
  138.         return;
  139.     }
  140.  
  141.     Screen("    Open the table which we just created in exclusive"
  142.            " mode\r\n        (required in order to add an index to a"
  143.            " dBASE table)...");
  144.     rslt = DbiOpenTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType,
  145.                         NULL, NULL, NULL, dbiREADWRITE, dbiOPENEXCL,
  146.                         xltFIELD, FALSE, NULL, &hCur);
  147.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  148.     {
  149.         CloseDbAndExit(&hDb);
  150.         Screen("\r\n*** End of Example ***");
  151.         return;
  152.     }
  153.  
  154.     // Now add the new index to the table.  To add an index we must have
  155.     // an exclusive lock on the table which we acquired when opening the
  156.     // table.
  157.     Screen("    Adding a non-maintained index to the table...");
  158.     rslt = DbiAddIndex(hDb, hCur,(pCHAR) szTblName, (pCHAR) szTblType,
  159.                        idxDesc1, NULL);
  160.     ChkRslt(rslt, "AddIndex");
  161.  
  162.     // DbiAddIndex() adds the index and automatically opens it
  163.  
  164.     // Close the index. In dBASE, after closing a non-maintained
  165.     // index will not be kept up-to-date.
  166.     Screen("    Closing the non-maintained index we just added...");
  167.     rslt = DbiCloseIndex(hCur, "FULLNAME.NDX", NULL);
  168.     ChkRslt(rslt, "CloseIndex");
  169.  
  170.     // Now add a record to the table to make the index out of date.
  171.     Screen("    Adding a record to invalidate the index...");
  172.     rslt = AddRecord(&hCur, "Charlie", "Joel", "Waternon", 5, 21, 1983,
  173.                      "California");
  174.     ChkRslt(rslt, "AddRecord");
  175.  
  176.     // Open the added index using DbiOpenIndex, which is dBASE-
  177.     // specific.
  178.     Screen("    Open the new index to show that it is out of date...");
  179.  
  180.     rslt = DbiOpenIndex(hCur, "FULLNAME.NDX", NULL);
  181.     ChkRslt(rslt, "OpenIndex");
  182.  
  183.     // Opening the index does not make it the current index.  To make the 
  184.     // index current we need to switch to it. For a non maintained .NDX
  185.     // index, we need to supply the index name.
  186.    
  187.     Screen("    Switch to the newly created index that is out of date...");
  188.  
  189.     rslt = DbiSwitchToIndex(&hCur, "FULLNAME.NDX", NULL, NULL, FALSE);
  190.     ChkRslt(rslt, "SwitchToIndex");
  191.  
  192.     Screen("    Display the table...");
  193.     Screen("\r\n    Note that only 4 entries are displayed even"
  194.            " though there are are 5\r\n        entries in the table"
  195.            " because the index is out of date...");
  196.     DisplayTable(hCur, 0);
  197.  
  198.     // Switch to default order.  We cannot regen the index if it is the 
  199.     // currently active index on the cursor.
  200.     Screen("\r\n    Switching to default order...");
  201.  
  202.     rslt = DbiSwitchToIndex(&hCur, NULL, NULL, NULL, FALSE);
  203.     ChkRslt(rslt, "SwitchToIndex");
  204.  
  205.     Screen("\r\n    Regenerating the index...");
  206.     rslt = DbiRegenIndex(hDb, hCur, (pCHAR) szTblName, (pCHAR) szTblType,
  207.                          "FULLNAME.NDX", NULL, NULL);
  208.     ChkRslt(rslt, "RegenIndex");
  209.  
  210.     // Switch back to the non-maintained index. It should now be up-to-date.
  211.     Screen("    Switch to the newly regenerated index...");
  212.     rslt = DbiSwitchToIndex(&hCur, "FULLNAME.NDX", NULL, NULL, FALSE);
  213.     ChkRslt(rslt, "SwitchToIndex");
  214.  
  215.     Screen("    Display the table according to the new index...");
  216.     DisplayTable(hCur, 0);
  217.  
  218.     // Switch to default order.  The default order for a dBASE table is 
  219.     // the order in which the records were inserted.
  220.     Screen("\r\n    Switching index to show record order...");
  221.  
  222.     rslt = DbiSwitchToIndex(&hCur, NULL, NULL, NULL, FALSE);
  223.     ChkRslt(rslt, "SwitchToIndex");
  224.  
  225.     Screen("    This is the order of the table with no index...");
  226.     DisplayTable(hCur, 0);
  227.  
  228.     MyDesc = (IDXDesc *) malloc(sizeof(IDXDesc));
  229.     if (MyDesc == NULL)
  230.     {
  231.         CloseDbAndExit(&hDb);
  232.         Screen("\r\n*** End of Example ***");
  233.         return;    
  234.     }
  235.  
  236.     // Close the non-maintained index as we are done with this
  237.     // part of the example.
  238.     Screen("\r\n    Closing the non-maintained index.");
  239.  
  240.     rslt = DbiCloseIndex(hCur, "FULLNAME.NDX", NULL);
  241.     ChkRslt(rslt, "CloseIndex");
  242.  
  243.     // The only indexes that are open now are maintained indexes since we
  244.     // have already closed the non-maintained index.
  245.  
  246.     // Get any index descriptor (in this case the first one).
  247.     rslt = DbiGetIndexDesc(hCur, 1, MyDesc);
  248.     ChkRslt(rslt, "GetIndexDesc");
  249.  
  250.     Screen("    Switching to an index in the production index... ");
  251.     rslt = DbiSwitchToIndex(&hCur, MyDesc->szName, MyDesc->szTagName, NULL,
  252.                             FALSE);
  253.     ChkRslt(rslt, "SwitchToIndex");
  254.  
  255.     Screen("    This is the order of the table using a tag inside the"
  256.            " production\r\n        index called %s...", MyDesc->szTagName);
  257.     DisplayTable(hCur, 0);
  258.  
  259.     // Delete the table and its related indexes and files from disk.  To
  260.     // do this we first need to delete the NDX and then we close the
  261.     // table and delete the table.  In this way IDAPI will delete the
  262.     // MDX file for us.
  263.  
  264.     Screen("\r\n    Delete the FULLNAME.NDX index. This must be done separately"
  265.            " as it is not\r\n        a part of the production index...");
  266.     rslt = DbiDeleteIndex(hDb, hCur, (pCHAR) szTblName, (pCHAR) szTblType,
  267.                           "FULLNAME.NDX", NULL, NULL);
  268.     ChkRslt(rslt, "DeleteIndex");
  269.  
  270.     Screen("    Close the %s table...", szTblName);
  271.     rslt = DbiCloseCursor(&hCur);
  272.     ChkRslt(rslt, "CloseCursor");
  273.  
  274.     Screen("    Delete the %s table...", szTblName);
  275.     rslt = DbiDeleteTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType);
  276.     ChkRslt(rslt, "DeleteTable");
  277.  
  278.     free(MyDesc);
  279.  
  280.     Screen("    Close the database and exit IDAPI...");
  281.     CloseDbAndExit(&hDb);
  282.  
  283.     Screen("\r\n*** End of Example ***");
  284. }
  285.  
  286. //=====================================================================
  287. //  Function:
  288. //          InitTable();
  289. //
  290. //  Input:  pointer to the database handle.
  291. //
  292. //  Return: result of the table initialization.
  293. //
  294. //  Description:
  295. //          This function will create a table and fill it
  296. //          with a number of records.  The function uses
  297. //          another function called AddRecord.
  298. //=====================================================================
  299. DBIResult
  300. InitTable (phDBIDb phDb)
  301. {
  302.     DBIResult   rslt;               // Value returned from IDAPI functions
  303.     hDBICur     hCur;               // Cursor handle for the table that is
  304.                                     // created
  305.     CRTblDesc   crTblDsc;           // Table descriptor
  306.     BOOL        bOverWrite = TRUE;  // Overwrite, yes/no flag
  307.  
  308.     // The number of fields in the table - note that fldDesc is defined
  309.     // globally
  310.     const UINT16 uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]);
  311.  
  312.     // Number of indexes to be created when the table is created - note
  313.     // that idxDesc is defined globally.
  314.     const UINT16 uNumIndexes = sizeof(idxDesc) / sizeof(idxDesc[0]);
  315.  
  316.     memset(&crTblDsc, 0, sizeof(CRTblDesc)); // Clear the buffer.
  317.  
  318.     // Set the name and the type of the table
  319.     strcpy(crTblDsc.szTblName, szTblName) ; // name of the table
  320.     strcpy(crTblDsc.szTblType, szTblType) ; // Type of table
  321.  
  322.     // Set the field information for the table
  323.     crTblDsc.iFldCount     = uNumFields ;   // number of fields
  324.     crTblDsc.pfldDesc      = fldDesc ;      // Field descriptor
  325.  
  326.     // Set the index information for the table
  327.     crTblDsc.iIdxCount     = uNumIndexes ;  // Number of indexes
  328.     crTblDsc.pidxDesc      = idxDesc ;      // Index descriptor
  329.  
  330.     // Create the table using information supplied in the table
  331.     // descriptor above
  332.     Screen("    Creating table and indexes...");
  333.  
  334.     rslt = DbiCreateTable(*phDb, bOverWrite, &crTblDsc);
  335.     if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
  336.     {
  337.         return rslt;
  338.     }
  339.  
  340.     rslt = DbiOpenTable(*phDb, (pCHAR) szTblName, (pCHAR) szTblType,
  341.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
  342.                         xltFIELD, FALSE, NULL, &hCur);
  343.     ChkRslt(rslt, "OpenTable");
  344.  
  345.     // Add records to the table
  346.     Screen("    Adding Records to the table...");
  347.     AddRecord(&hCur, "Klaus", "John", "Lockwood", 7, 28, 1968,
  348.               "Chicago");
  349.     AddRecord(&hCur, "Ann", "Tracy", "Brown", 12, 27, 1969,
  350.               "Hermosa Beach");
  351.     AddRecord(&hCur, "John", "Boy", "Krull", 2, 7, 1954,
  352.               "Ohmaha");
  353.     AddRecord(&hCur, "Goliath", "Joel", "Raccah", 4, 13, 1970,
  354.               "Tel Aviv");
  355.  
  356.     // Close the table so it can be reopened from the calling function.
  357.     rslt = DbiCloseCursor(&hCur);
  358.     ChkRslt(rslt, "CloseCursor");
  359.  
  360.     return rslt;
  361. }
  362.  
  363. //=====================================================================
  364. //  Function:
  365. //          AddRecord();
  366. //
  367. //  Input:  pointer to the cursor handle, first name (pCHAR), middle
  368. //          name (pCHAR), last name (pCHAR), Month of Birth (UINT16), Day
  369. //          of Birth (UINT16), Year of Birth (UINT16), Place of birth
  370. //          (pCHAR).
  371. //
  372. //  Return: Result of adding the record to the table
  373. //
  374. //  Description:
  375. //          This function will add a record to the given table.
  376. //=====================================================================
  377. DBIResult
  378. AddRecord (phDBICur hCur, pCHAR pszFirst, pCHAR pszMiddle, pCHAR pszLast,
  379.            UINT16 uMonth, UINT16 uDay, UINT16 uYear, pCHAR pszPOB)
  380. {
  381.     DBIDATE     Date;           // Date structure
  382.     DBIResult   rslt;           // Value returned from IDAPI functions
  383.     CURProps    TblProps;       // Table properties
  384.     pBYTE       pRecBuf;        // Record buffer
  385.  
  386.     //  Allocate a record buffer
  387.     rslt = DbiGetCursorProps(*hCur, &TblProps);
  388.     ChkRslt(rslt, "GetCursorProps");
  389.  
  390.     pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE));
  391.     if (pRecBuf == NULL)
  392.     {
  393.         return DBIERR_NOMEMORY;
  394.     }
  395.  
  396.     //  Make sure we're starting with a clean record buffer
  397.     rslt = DbiInitRecord(*hCur, pRecBuf);
  398.     ChkRslt(rslt, "InitRecord");
  399.  
  400.     // First Name
  401.     rslt = DbiPutField(*hCur, 1, pRecBuf, (pBYTE) pszFirst);
  402.     ChkRslt(rslt, "PutField");
  403.  
  404.     // Middle Name
  405.     rslt = DbiPutField(*hCur, 2, pRecBuf, (pBYTE) pszMiddle);
  406.     ChkRslt(rslt, "PutField");
  407.  
  408.     // Last Name
  409.     rslt = DbiPutField(*hCur, 3, pRecBuf, (pBYTE) pszLast);
  410.     ChkRslt(rslt, "PutField");
  411.  
  412.     // DOB
  413.     rslt = DbiDateEncode(uMonth, uDay, uYear, &Date);
  414.     ChkRslt(rslt, "DateEncode");
  415.  
  416.     rslt = DbiPutField(*hCur, 4,  pRecBuf, (pBYTE) &Date);
  417.     ChkRslt(rslt, "PutField");
  418.  
  419.     // Place of Birth
  420.     rslt = DbiPutField(*hCur, 5,  pRecBuf, (pBYTE) pszPOB);
  421.     ChkRslt(rslt, "PutField");
  422.  
  423.     rslt = DbiInsertRecord(*hCur, dbiNOLOCK, pRecBuf),
  424.     ChkRslt(rslt, "InsertRecord");
  425.  
  426.     free(pRecBuf);
  427.  
  428.     return rslt;
  429. }
  430.