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

  1. // BDE - (C) Copyright 1995 by Borland International
  2.  
  3. // refinteg.c
  4. #include "snipit.h"
  5.  
  6. static DBIResult AddRecord(hDBICur hCur, DFLOAT fStatus, DFLOAT fOrder,
  7.                            CHAR *szDateSent, CHAR *szDateDelivered);
  8.  
  9. static const char szTblName[] = "RefInteg";
  10. static const char szTblType[] = szPARADOX;
  11.  
  12. // Field descriptor used in creating a table.
  13. static SNIPFAR FLDDesc fldDesc[] = {
  14.               { // Field 1 - AUTOINC
  15.                 1,              // Field number
  16.                 "Status ID",    // Field name
  17.                 fldFLOAT,       // Field type
  18.                 fldUNKNOWN,     // Field subtype
  19.                 0,              // Field size
  20.                 0,              // Decimal places ( 0 )
  21.                                 //   computed
  22.                 0,              // Offset in record ( 0 )
  23.                 0,              // Length in bytes  ( 0 )
  24.                 0,              // For NULL bits    ( 0 )
  25.                 fldvNOCHECKS,   // Validity checks  ( 0 )
  26.                 fldrREADWRITE   // Rights
  27.               },
  28.               { // Field 2 - ALPHA
  29.                 2, "Order No", fldFLOAT, fldUNKNOWN,
  30.                 0, 0, 0, 0, 0,
  31.                 fldvNOCHECKS, fldrREADWRITE
  32.               },
  33.               { // Field 4 - DATE
  34.                 3, "Date Sent", fldDATE, fldUNKNOWN,
  35.                 0, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE
  36.               },
  37.               { // Field 4 - DATE
  38.                 4, "Date Received", fldDATE, fldUNKNOWN,
  39.                 0, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE
  40.               }
  41.              }; // Array of field descriptors.
  42.  
  43. // The number of fields in the table.
  44. static const UINT16 uNumFields = sizeof(fldDesc) / sizeof(fldDesc[0]);
  45.  
  46. // Array of referential integrity rules.
  47. static SNIPFAR RINTDesc rintDesc[] = {
  48.                 {
  49.                     1,                  // Referential integrity number
  50.                     "Order No",         // Name for this integrity
  51.                     rintDEPENDENT,      // Whether master or dependent
  52.                     "orders.db",        // Other table name
  53.                     rintCASCADE,        // Modify qualifier
  54.                     rintRESTRICT,       // Delete modifier
  55.                     1,                  // Fields in foreign key
  56.                     {2},                // Fields in this table
  57.                     {1}                 // Fields in other table
  58.                 }
  59.             };
  60.  
  61. // Number of referential integrity rules.
  62. static const INT16 iRintCount = sizeof(rintDesc) / sizeof(rintDesc[0]);
  63.  
  64. // Index Descriptor - describes the indexes associated with the
  65. //   table. This index is going to be added to the table when the
  66. //   table is created.
  67. static SNIPFAR IDXDesc idxDesc[] = {
  68.             { // Primary Index
  69.                "",          // Name
  70.                1,           // Number
  71.                { NULL },    // Tag name (for dBase)
  72.                { NULL },    // Optional format (BTREE,
  73.                             //   HASH, etc)
  74.                TRUE,        // Primary?
  75.                TRUE,        // Unique?
  76.                FALSE,       // Descending?
  77.                TRUE,        // Maintained?
  78.                FALSE,       // Subset?
  79.                FALSE,       // Expression index?
  80.                NULL,        // For QBE only
  81.                2,           // Fields in key
  82.                1,           // Length in bytes
  83.                FALSE,       // Index out of date?
  84.                0,           // Key type of expression
  85.                { 1,2 },     // Array of field numbers
  86.                { 0 },       // Key expression
  87.                { 0 },       // Key condition
  88.                FALSE,       // Case insensitive
  89.                0,           // Block size in bytes
  90.                0            // Restructure number
  91.             },
  92.             {  // Secondary Index 1 - Single-Field - Maintained,
  93.                //   case insensitive.
  94.                "Order No", 2, { NULL }, { NULL }, FALSE, FALSE, FALSE,
  95.                TRUE, FALSE, FALSE, NULL, 1, 1, FALSE, 0, { 2 }, { 0 },
  96.                { 0 }, FALSE, 0, 0
  97.             }
  98.         };
  99.  
  100. // Number of indexes to be created when the table is created.
  101. static const unsigned uNumIndexes = sizeof(idxDesc) / sizeof(idxDesc[0]);
  102.                               
  103. //=====================================================================
  104. //  Function:
  105. //          RefInteg();
  106. //
  107. //  Description:
  108. //          This function shows how to create and use referential
  109. //          integrity.
  110. //=====================================================================
  111. void
  112. RefInteg (void)
  113. {
  114.     DBIResult   rslt;               // Return value from IDAPI functions
  115.     hDBIDb      hDb;                // Handle to the database
  116.     hDBICur     hCur;               // Handle to the table
  117.     CRTblDesc   TblDesc;            // Create table descriptor
  118.     UINT16      uDispNumRecs = 10 ; // Number of records to add and
  119.                                     //   display
  120.     CROpType    crOpType[] = { crADD }; // Define the operation on the table.
  121.  
  122.     Screen("*** Referential Integrity Example ***\r\n");
  123.  
  124.     BREAK_IN_DEBUGGER();
  125.  
  126.     Screen("    Initializing IDAPI...");
  127.     if (InitAndConnect(&hDb) != DBIERR_NONE)
  128.     {
  129.         Screen("\r\n*** End of Example ***");
  130.         return;
  131.     }
  132.  
  133.     Screen("    Setting the default database directory...");
  134.     rslt = DbiSetDirectory(hDb, (pCHAR) szTblDirectory);
  135.     ChkRslt(rslt, "SetDirectory");
  136.  
  137.     Screen("    Initializing the table descriptor...");
  138.     memset((void *)&TblDesc, 0, sizeof(CRTblDesc));
  139.     lstrcpy(TblDesc.szTblName, szTblName);
  140.     lstrcpy(TblDesc.szTblType, szTblType);
  141.     TblDesc.iFldCount   = uNumFields;
  142.     TblDesc.pfldDesc    = fldDesc;
  143.     TblDesc.iIdxCount   = uNumIndexes;
  144.     TblDesc.pidxDesc    = idxDesc;
  145.     TblDesc.iRintCount  = iRintCount;
  146.     TblDesc.pecrRintOp  = crOpType;
  147.     TblDesc.printDesc   = rintDesc;
  148.  
  149.     Screen("    Creating the %s table...", szTblName);
  150.     rslt = DbiCreateTable(hDb, TRUE, &TblDesc);
  151.     if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
  152.     {
  153.         CloseDbAndExit(&hDb);
  154.         Screen("\r\n*** End of Example ***");
  155.         return;
  156.     }
  157.  
  158.     Screen("    Open the %s table...", szTblName);
  159.     rslt = DbiOpenTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType,
  160.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
  161.                         xltFIELD, FALSE, NULL, &hCur);
  162.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  163.     {
  164.         rslt = DbiDeleteTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType);
  165.         ChkRslt(rslt, "DeleteTable");
  166.         CloseDbAndExit(&hDb);
  167.         Screen("\r\n*** End of Example ***");
  168.         return;
  169.     }
  170.  
  171.     // This add will fail. Order ID 900 does not exist within the
  172.     //   Orders table.
  173.     Screen("    Add a record to the table.");
  174.     Screen("        Error Expected - no record in the orders table has an"
  175.            " ID of 900...");
  176.     AddRecord(hCur, 1, 900, "07/28/1994", "08/12/1994");
  177.  
  178.     // This add will succeed. Order ID 1004 exists within the Orders
  179.     //   table.
  180.     Screen("\r\n    Add a record to the table with a valid Order ID...");
  181.     AddRecord(hCur, 1, 1004, "07/28/1994", "08/12/1994");
  182.  
  183.     rslt = DbiSetToBegin(hCur);
  184.     ChkRslt(rslt, "SetToBegin");
  185.  
  186.     Screen("    Display the \"%s\" table...", szTblName);
  187.     DisplayTable(hCur, uDispNumRecs);
  188.  
  189.     Screen("\r\n    Close the table...");
  190.     rslt = DbiCloseCursor(&hCur);
  191.     ChkRslt(rslt, "CloseCursor");
  192.  
  193.     Screen("    Deleting the table...");
  194.     rslt = DbiDeleteTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType);
  195.     ChkRslt(rslt, "DeleteTable");
  196.  
  197.     Screen("    Close the database and exit IDAPI...");
  198.     CloseDbAndExit(&hDb);
  199.  
  200.     Screen("\r\n*** End of Example ***");
  201. }
  202.  
  203. //=====================================================================
  204. //  Function:
  205. //          AddRecord(hCur, fStatus, fOrder, *DateSent, *DateDelivered)
  206. //
  207. //  Input:  hCur            - Cursor to which the record will be added
  208. //          fStatus         - Value to write to the Status ID field
  209. //          fOrder          - Value to write to the Order ID field
  210. //          DateSent        - Value to write to the Date Sent field
  211. //          DateDelivered   - Value to write to the Date Received field
  212. //
  213. //  Return: Success of the function.
  214. //
  215. //  Description:
  216. //          This function is used to add a record to the table.
  217. //=====================================================================
  218. DBIResult
  219. AddRecord (hDBICur hCur, DFLOAT fStatus, DFLOAT fOrder, CHAR *szDateSent,
  220.            CHAR *szDateDelivered)
  221. {
  222.     DBIResult   rslt;               // Return value from IDAPI functions
  223.     pBYTE       pRecBuf;            // Record buffer
  224.     CURProps    TblProps;           // The properties of the table
  225.     UINT16      uMonth;             // Contains the month portion of the
  226.                                     //   date
  227.     UINT16      uDay;               // Contains the day portion of the
  228.                                     //   date
  229.     INT16       iYear;              // Contains the year portion of the
  230.                                     //   date
  231.     CHAR        szDate[30];         // Pointer to be allocated off the
  232.                                     //   heap
  233.     CHAR        *pszTemp;           // Temporary string used in parsing
  234.                                     //   the date
  235.     DBIDATE     Date;               // Date structure, used in
  236.                                     //   DbiPutField
  237.  
  238.     // Allocate a record buffer.
  239.     rslt = DbiGetCursorProps(hCur, &TblProps);
  240.     ChkRslt(rslt, "GetCursorProps");
  241.  
  242.     pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(pBYTE));
  243.     if (pRecBuf == NULL)
  244.     {
  245.         Screen("    Error - Out of Memory");
  246.         return DBIERR_NOMEMORY;
  247.     }
  248.  
  249.     // Make sure we're starting with a clean record buffer
  250.     rslt = DbiInitRecord(hCur, pRecBuf);
  251.     ChkRslt(rslt, "InitRecord");
  252.  
  253.     // Add the Status ID to the record buffer
  254.     rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) &fStatus);
  255.     ChkRslt(rslt, "PutField");
  256.  
  257.     // Add the Order ID to the record buffer.
  258.     rslt = DbiPutField(hCur, 2, pRecBuf, (pBYTE) &fOrder);
  259.     ChkRslt(rslt, "PutField");
  260.  
  261.     strcpy(szDate, szDateSent);
  262.  
  263.     // Need to convert the string to a Date structure.
  264.     pszTemp = strtok(szDate, "/");
  265.     if (pszTemp)
  266.     {
  267.         uMonth = atoi(pszTemp); // uMonth set to 0 if invalid date.
  268.         pszTemp = strtok(NULL, "/");
  269.         if (pszTemp)
  270.         {
  271.             uDay = atoi(pszTemp); // uDay set to 0 if invalid date.
  272.             pszTemp = strtok(NULL, "/");
  273.             if (pszTemp)
  274.             {
  275.                 iYear = atoi(pszTemp);  // iYear set to 0 if
  276.                                         //   invalid date.
  277.             }
  278.         }
  279.     }
  280.  
  281.     // Encode the date.
  282.     rslt = DbiDateEncode(uMonth, uDay, iYear, &Date);
  283.     ChkRslt(rslt, "DateEncode");
  284.  
  285.     // Put the data into the record buffer.
  286.     rslt = DbiPutField(hCur, 3, pRecBuf, (pBYTE) &Date);
  287.  
  288.     strcpy(szDate, szDateDelivered);
  289.  
  290.     // Need to convert the string to a Date structure.
  291.     pszTemp = strtok(szDate, "/");
  292.     if (pszTemp)
  293.     {
  294.         uMonth = atoi(pszTemp); // uMonth set to 0 if invalid date.
  295.         pszTemp = strtok(NULL, "/");
  296.         if (pszTemp)
  297.         {
  298.             uDay = atoi(pszTemp); // uDay set to 0 if invalid date.
  299.             pszTemp = strtok(NULL, "/");
  300.             if (pszTemp)
  301.             {
  302.                 iYear = atoi(pszTemp);  // iYear set to 0 if
  303.                                         //   invalid date.
  304.             }
  305.         }
  306.     }
  307.  
  308.     // Encode the date.
  309.     rslt = DbiDateEncode(uMonth, uDay, iYear, &Date);
  310.     ChkRslt(rslt, "DateEncode");
  311.  
  312.     // Put the data into the record buffer.
  313.     rslt = DbiPutField(hCur, 4, pRecBuf, (pBYTE) &Date);
  314.     ChkRslt(rslt, "PutField");
  315.  
  316.     // Insert the record into the table.
  317.     rslt = DbiInsertRecord(hCur, dbiNOLOCK, pRecBuf);
  318.     ChkRslt(rslt, "InsertRecord");
  319.  
  320.     free(pRecBuf);
  321.  
  322.     return rslt;
  323. }
  324.