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

  1. // BDE - (C) Copyright 1995 by Borland International
  2.  
  3. // idxpdox.c
  4. #include "snipit.h"
  5.  
  6. #define NAMELEN  10 // The length of the name fields.
  7. #define PLACELEN 20 // The length of the POB field.
  8. #define DATELEN  11 // The display length of a date field: mm\dd\yyyy.
  9.  
  10. static const char szTblName[] = "People";
  11. static const char szTblType[] = szPARADOX;
  12.  
  13. // Field descriptor used in creating a table.
  14. static SNIPFAR FLDDesc fldDesc[] = {
  15.               { // Field 1 - First Name
  16.                 1,            // Field number
  17.                 "First Name", // 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, "Middle Name", fldZSTRING, fldUNKNOWN,
  32.                 NAMELEN, 0, 0, 0, 0,
  33.                 fldvNOCHECKS, fldrREADWRITE
  34.               },
  35.               { // Field 3 - Last Name
  36.                 3, "Last Name", 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.               }
  50.              };  // Array of field descriptors.
  51.  
  52. // Index descriptor - describes the index associated with the
  53. // table.  
  54. static SNIPFAR IDXDesc idxDesc[] = {
  55.             { // Primary Index - Full Name.
  56.                "Full Name",  // Name
  57.                1,            // Number
  58.                { NULL },     // Tag name ( for dBase )
  59.                { NULL },     // Optional format ( BTREE,
  60.                              //   HASH, etc )
  61.                TRUE,         // Primary?
  62.                TRUE,         // Unique?
  63.                FALSE,        // Descending?
  64.                TRUE,         // Maintained?
  65.                FALSE,        // Subset?
  66.                FALSE,        // Expression index?
  67.                NULL,         // For QBE only
  68.                3,            // Fields in key
  69.                1,            // Length in bytes
  70.                FALSE,        // Index out of date?
  71.                0,            // Key type of expression
  72.                { 1,2,3 },    // Array of field numbers
  73.                { 0 },        // Key expression
  74.                { 0 },        // Key condition
  75.                FALSE,        // Case insensitive
  76.                0,            // Block size in bytes
  77.                0             // Restructure number
  78.             },
  79.             {  // Secondary Index 1 - single-field - maintained,
  80.                //   Case insensitive.
  81.                "Last Name", 2, { NULL }, { NULL }, FALSE, FALSE, FALSE,
  82.                TRUE, FALSE, FALSE, NULL, 1, 1, FALSE, 0, { 3 }, { 0 },
  83.                { 0 }, TRUE, 0, 0
  84.             },
  85.             { // Secondary Index 2 - multi-field - maintained.
  86.               "Name", 3, { NULL }, { NULL }, FALSE, FALSE, FALSE, TRUE,
  87.                FALSE, FALSE, NULL, 2, 1, FALSE, 0, { 3,1 }, { 0 }, { 0 },
  88.                FALSE, 0, 0
  89.             }
  90.         };
  91.  
  92. // Index descriptor - Describes the indexes associated with the
  93. //   table.  This index will be added to the table after the table
  94. //   has been created.
  95. static SNIPFAR IDXDesc idxDesc1[] = {
  96.             {  // Secondary Index 3 - single-field - not maintained.
  97.                "POB", 4, { NULL }, { NULL }, FALSE, FALSE, FALSE, FALSE,
  98.                FALSE, FALSE, NULL, 1, 1, FALSE, 0, { 5 }, { 0 }, { 0 },
  99.                FALSE, 0, 0
  100.             }
  101.          };
  102.  
  103. // Number of fields in the table.
  104. static const unsigned uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]);
  105.  
  106. // Number of indexes to be created when the table is created.
  107. static const unsigned uNumIndexes = sizeof(idxDesc) / sizeof(idxDesc[0]);
  108.  
  109. static DBIResult InitTable(phDBIDb phDb);
  110. static DBIResult AddRecord(phDBICur hCur, pCHAR pszFirst, pCHAR pszMiddle,
  111.                            pCHAR pszLast, UINT16 iMonth, UINT16 iDay,
  112.                            UINT16 iYear, pCHAR pszPOB);
  113.  
  114. //=====================================================================
  115. //  Function:
  116. //          IndexPDox();
  117. //
  118. //  Description:
  119. //          This example shows how to create and add Paradox indexes.
  120. //          This includes creating primary indexes and managing 
  121. //          non-maintained secondary indexes.
  122. //=====================================================================
  123. void
  124. IndexPDox (void)
  125. {
  126.     hDBIDb      hDb;        // Database handle
  127.     hDBICur     hCur;       // Cursor handle
  128.     CURProps    TblProps;   // Table properties
  129.     IDXDesc     *MyDesc;    // Index descriptor
  130.     UINT16      i;          // Loop variable
  131.     DBIResult   rslt;       // Return value from IDAPI functions
  132.  
  133.     Screen("*** Paradox Index Manipulation Example ***\r\n");
  134.  
  135.     BREAK_IN_DEBUGGER();
  136.  
  137.     Screen("    Initializing IDAPI...");
  138.     if (InitAndConnect(&hDb) != DBIERR_NONE)
  139.     {                                       
  140.         Screen("\r\n*** End of Example ***");
  141.         return;
  142.     }
  143.  
  144.     Screen("    Setting the database directory...");
  145.     rslt = DbiSetDirectory(hDb, (pCHAR) szTblDirectory);
  146.     ChkRslt(rslt, "SetDirectory");
  147.  
  148.     // Create the table and fill with data.
  149.     if (InitTable(&hDb))
  150.     {
  151.         CloseDbAndExit(&hDb);
  152.         Screen("\r\n*** End of Example ***");
  153.         return;
  154.     }
  155.  
  156.     // Add an index to the table.  Note that the index is added to the
  157.     //   table before the table is opened - the table must either be closed
  158.     //   or be opened in exclusive mode to add an index.
  159.     Screen("        Add an index to the table...");
  160.     rslt = DbiAddIndex(hDb, NULL, (pCHAR) szTblName, (pCHAR) szTblType,
  161.                        idxDesc1, NULL);
  162.     ChkRslt(rslt, "AddIndex");
  163.  
  164.  
  165.     Screen("        Open the %s table...", szTblName);
  166.     rslt = DbiOpenTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType,
  167.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
  168.                         xltFIELD, FALSE, NULL, &hCur);
  169.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  170.     {
  171.         CloseDbAndExit(&hDb);
  172.         Screen("\r\n*** End of Example ***");
  173.         return;
  174.     }
  175.  
  176.     Screen("    Get the number of indexes on the %s table...", szTblName);
  177.     rslt = DbiGetCursorProps(hCur, &TblProps);
  178.     ChkRslt(rslt, "GetCursorProps");
  179.  
  180.     Screen("    There are %d indexes on the table", TblProps.iIndexes);
  181.  
  182.     // Allocate space for the index descriptor.
  183.     MyDesc = (IDXDesc *) malloc(sizeof(IDXDesc) * TblProps.iIndexes);
  184.     if (MyDesc == NULL)
  185.     {
  186.         Screen("    Error - Out of memory");
  187.         CloseDbAndExit(&hDb);
  188.         Screen("\r\n*** End of Example ***");
  189.         return;
  190.     }
  191.  
  192.     Screen("    Get and display information about the indexes");
  193.     Screen("\r\n        Name\t\t   ID\tPrimary Maintained "
  194.            "Fields Case_Insensitive");
  195.     Screen("        =================================================="
  196.            "==========");
  197.     for (i = 0;i < TblProps.iIndexes; i++)
  198.     {
  199.         rslt = DbiGetIndexDesc(hCur, (i+1), &(MyDesc[i]));
  200.         ChkRslt(rslt, "GetIndexDesc");
  201.  
  202.         Screen("        %-15s\t%5d \t%s\t%2s\t %4d\t   %2s",
  203.                (strcmp(MyDesc[i].szName, "") ? MyDesc[i].szName :
  204.                 "*Primary Index*"), // Primary indexes don't have a name.
  205.                 MyDesc[i].iIndexId, // The ID of the Index.
  206.                 // Display "TRUE" or "FALSE" as opposed to 1 or 0....
  207.                 (MyDesc[i].bPrimary ? "TRUE" : "FALSE"),
  208.                 (MyDesc[i].bMaintained ? "TRUE" : "FALSE"),
  209.                 MyDesc[i].iFldsInKey,
  210.                 (MyDesc[i].bCaseInsensitive ? "TRUE" : "FALSE"));
  211.     }
  212.  
  213.     rslt = DbiSetToBegin(hCur);
  214.     ChkRslt(rslt, "SetToBegin");
  215.  
  216.     // Display the records in the table. The order of the records depends
  217.     //   on the active index - in this case, it is the primary index.
  218.     Screen("\r\n    Display the records in the table in the order of the"
  219.            " primary \r\n    index - First, Middle, Last");
  220.     DisplayTable(hCur, 0);
  221.  
  222.     // Switch the index that the table is opened on - only need to
  223.     //   provide one of the following: IndexName, TagName, or IndexId.
  224.     Screen("\r\n    Change the table to be opened on the \"Last Name\""
  225.            " index...");
  226.     rslt = DbiSwitchToIndex(&hCur, idxDesc[1].szName, NULL, NULL, FALSE);
  227.     ChkRslt(rslt, "SwitchToIndex");
  228.  
  229.     // Go to the beginning of the table.
  230.     rslt = DbiSetToBegin(hCur);
  231.     ChkRslt(rslt, "SetToBegin");
  232.  
  233.     Screen("    Display the records in the table in the order of the"
  234.            " \"Last Name\" index...");
  235.     DisplayTable(hCur, 0);
  236.  
  237.     Screen("\r\n    Add a record to the table in order to invalidate"
  238.            " non-maintained indexes...");
  239.     AddRecord(&hCur, "Jerry", "Joel", "Raccah", 5, 22, 1958,
  240.               "Lake Tahoe");
  241.  
  242.     // Switch the index that the table is opened on - only need to
  243.     //   provide one of the following: IndexName, TagName, or IndexId.
  244.     //   This function is passed an ID of 5 which is the id of the
  245.     //   single field that it is indexing on.
  246.     Screen("\r\n    Change the table to be opened on the \"POB\""
  247.            " index (which is non-maintained)...");
  248.     Screen("\r\n        Error expected - the \"POB\" index is"
  249.            " not maintained");
  250.  
  251.     rslt = DbiSwitchToIndex(&hCur, NULL, NULL, MyDesc[1].iIndexId, FALSE);
  252.     ChkRslt(rslt, "SwitchToIndex");
  253.  
  254.     Screen("\r\n    Steps to regenerate the \"POB\" index...");
  255.     Screen("        Close the table - the table must be open in"
  256.            " exclusive mode to regenerate \r\n        the indexes...");
  257.  
  258.     rslt = DbiCloseCursor(&hCur);
  259.     ChkRslt(rslt, "CloseCursor");                 
  260.  
  261.     Screen("        Open the table in exclusive mode...");
  262.     rslt = DbiOpenTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType,
  263.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENEXCL,
  264.                         xltFIELD, FALSE, NULL, &hCur);
  265.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  266.     {
  267.         CloseDbAndExit(&hDb);
  268.         Screen("\r\n*** End of Example ***");
  269.         return;
  270.     }
  271.  
  272.     Screen("        Regenerate the index...");
  273.     rslt = DbiRegenIndex(hDb, hCur, (pCHAR) szTblName, (pCHAR) szTblType,
  274.                          MyDesc[1].szName, NULL, NULL);
  275.     ChkRslt(rslt, "RegenIndexes");
  276.  
  277.     // Switch the index that the table is opened on - only need to
  278.     //   provide one of the following: IndexName, TagName, or IndexId
  279.     //   (parameter 2, 3, or 4 to DbiSwitchToIndex).
  280.     Screen("\r\n    Change the table to be opened on the \"POB\""
  281.            " index (which is non-maintained)...");
  282.     rslt = DbiSwitchToIndex(&hCur, MyDesc[1].szName, NULL, NULL, FALSE);
  283.     ChkRslt(rslt, "SwitchToIndex");
  284.  
  285.     rslt = DbiSetToBegin(hCur);
  286.     ChkRslt(rslt, "SetToBegin");
  287.  
  288.     Screen("    Display the records in the table in the order of the"
  289.            " \"POB\" (Place of Birth)\r\n    index...");
  290.     DisplayTable(hCur, 0);
  291.  
  292.     // Note that the table has to be opened in exclusive mode or closed
  293.     //   to delete an index.
  294.     Screen("\r\n    Delete the \"Last Name\" index...");
  295.  
  296.     rslt = DbiDeleteIndex(hDb, NULL, (pCHAR) szTblName, (pCHAR) szTblType,
  297.                           "Last Name", "", NULL);
  298.     ChkRslt(rslt, "DeleteIndex");
  299.  
  300.     Screen("    Close the %s table...", szTblName);
  301.     rslt = DbiCloseCursor(&hCur);
  302.     ChkRslt(rslt, "CloseCursor");
  303.  
  304.     Screen("    Delete the %s table and remaining indexes...", szTblName);
  305.     rslt = DbiDeleteTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType);
  306.     ChkRslt(rslt, "DeleteTable");
  307.  
  308.     free(MyDesc);
  309.  
  310.     Screen("    Close the database and exit IDAPI...");
  311.     CloseDbAndExit(&hDb);
  312.  
  313.     Screen("\r\n*** End of Example ***");
  314. }
  315.  
  316. //=====================================================================
  317. //  Function:
  318. //          InitTable(phDb);
  319. //
  320. //  Input:  phDb    - Pointer to the database handle
  321. //
  322. //  Return: Result of the table initialization
  323. //
  324. //  Description:
  325. //          This function will create a table and fill it
  326. //          with a number of records.  
  327. //=====================================================================
  328. DBIResult
  329. InitTable (phDBIDb phDb)
  330. {
  331.     DBIResult   rslt;               // Value returned from IDAPI functions
  332.     hDBICur     hCur;               // Cursor handle for the table that is
  333.                                     // created
  334.     CRTblDesc   crTblDsc;           // Table descriptor
  335.     BOOL        bOverWrite = TRUE;  // Overwrite, yes/no flag
  336.  
  337.     // Initialize the table create descriptor.
  338.     memset(&crTblDsc, 0, sizeof(CRTblDesc));
  339.     strcpy(crTblDsc.szTblName, szTblName);
  340.     strcpy(crTblDsc.szTblType, szTblType);
  341.     crTblDsc.iFldCount     = uNumFields;
  342.     crTblDsc.pfldDesc      = fldDesc;
  343.     crTblDsc.iIdxCount     = uNumIndexes;
  344.     crTblDsc.pidxDesc      = idxDesc;
  345.  
  346.     Screen("    Creating the %s table...", szTblName);
  347.  
  348.     rslt = DbiCreateTable(*phDb, bOverWrite, &crTblDsc);
  349.     if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
  350.     {
  351.         return rslt;
  352.     }
  353.  
  354.     rslt = DbiOpenTable(*phDb, (pCHAR) szTblName, (pCHAR) szTblType,
  355.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
  356.                         xltFIELD, FALSE, NULL, &hCur);
  357.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  358.     {
  359.         return rslt;
  360.     }
  361.  
  362.     // Add records to the table.
  363.     Screen("    Add records to the table...");
  364.     AddRecord(&hCur, "Klaus", "John", "Lockwood", 7, 28, 1968,
  365.               "Chicago");
  366.     AddRecord(&hCur, "Tracy", "Dunvan", "Aoki", 12, 27, 1969,
  367.               "Hermosa Beach");
  368.     AddRecord(&hCur, "John", "David", "Krull", 2, 7, 1954,
  369.               "Ohmaha");
  370.     AddRecord(&hCur, "Goliath", "Joel", "Raccah", 4, 13, 1966,
  371.               "Tel Aviv");
  372.  
  373.     rslt = DbiCloseCursor(&hCur);
  374.     ChkRslt(rslt, "CloseCursor");
  375.  
  376.     return rslt;
  377. }
  378.  
  379. //=====================================================================
  380. //  Function:
  381. //          AddRecord(hCur, pszFirst, pszMiddle, pszLast, iMonth,
  382. //                    iDay, iYear, pszPOB);
  383. //
  384. //  Input:  hCur        - Pointer to the cursor handle
  385. //          pszFirst    - First name
  386. //          pszMiddle   - Middle name
  387. //          pszLast     - Last name
  388. //          iMonth      - Month of birth
  389. //          iDay        - Day of birth
  390. //          iYear       - Year of birth
  391. //          pszPOB      - Place of birth
  392. //
  393. //  Return: Result of adding the record to the table
  394. //
  395. //  Description:
  396. //          This function will add a record to the given table.
  397. //=====================================================================
  398. DBIResult
  399. AddRecord (phDBICur hCur, pCHAR pszFirst, pCHAR pszMiddle, pCHAR pszLast,
  400.            UINT16 iMonth, UINT16 iDay, UINT16 iYear, pCHAR pszPOB)
  401. {
  402.     DATE        Date;       // Date structure
  403.     DBIResult   rslt;       // Value returned from IDAPI functions
  404.     CURProps    TblProps;   // Table properties
  405.     pBYTE       pRecBuf;    // Record buffer
  406.  
  407.     //  Allocate a record buffer.
  408.     rslt = DbiGetCursorProps(*hCur, &TblProps);
  409.     ChkRslt(rslt, "GetCursorProps");
  410.  
  411.     pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE));
  412.     if (pRecBuf == NULL)
  413.     {
  414.         return DBIERR_NOMEMORY;
  415.     }
  416.  
  417.     // Make sure we're starting with a clean record buffer.
  418.     rslt = DbiInitRecord(*hCur, pRecBuf);
  419.     ChkRslt(rslt, "InitRecord");
  420.  
  421.     // First name.
  422.     rslt = DbiPutField(*hCur, 1, pRecBuf, (pBYTE) pszFirst);
  423.     ChkRslt(rslt, "PutField");
  424.  
  425.     // Middle name.
  426.     rslt = DbiPutField(*hCur, 2, pRecBuf, (pBYTE) pszMiddle);
  427.     ChkRslt(rslt, "PutField");
  428.  
  429.     // Last name.
  430.     rslt = DbiPutField(*hCur, 3, pRecBuf, (pBYTE) pszLast);
  431.     ChkRslt(rslt, "PutField");
  432.  
  433.     // Date of birth.
  434.     rslt = DbiDateEncode(iMonth, iDay, iYear, &Date);
  435.     ChkRslt(rslt, "DateEncode");
  436.  
  437.     rslt = DbiPutField(*hCur, 4,  pRecBuf, (pBYTE) &Date);
  438.     ChkRslt(rslt, "PutField");
  439.  
  440.     // Place of Birth.
  441.     rslt = DbiPutField(*hCur, 5,  pRecBuf, (pBYTE) pszPOB);
  442.     ChkRslt(rslt, "PutField");
  443.  
  444.     rslt = DbiInsertRecord(*hCur, dbiNOLOCK, pRecBuf),
  445.     ChkRslt(rslt, "InsertRecord");
  446.  
  447.     free(pRecBuf);
  448.  
  449.     return rslt;
  450. }
  451.