home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bde / snipit.pak / BLOBSMPL.C < prev    next >
C/C++ Source or Header  |  1997-07-23  |  21KB  |  552 lines

  1. // BDE - (C) Copyright 1995 by Borland International
  2.  
  3. // blobsmpl.c
  4. #include "snipit.h"
  5.  
  6. #define  NAMELEN  20    // Set name length to 20 characters
  7. #define  DATELEN   9    // Set date length to 9 characters
  8.  
  9. static const char szTblName[] = "BLOBSMPL"; // Table to create
  10. static const char szTblType[] = szPARADOX;  // Table Type to use
  11.  
  12. static SNIPFAR FLDDesc fldDesc[] = {
  13.                    {
  14.                     1,            // Field number
  15.                     "First Name", // Field name
  16.                     fldZSTRING,   // Field type
  17.                     fldUNKNOWN,   // Field dubtype
  18.                     NAMELEN,      // Field size ( 1 or 0,
  19.                                   // except BLOB or string )
  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.                    {
  29.                     2, "Middle Name", fldZSTRING, fldUNKNOWN,
  30.                     NAMELEN, 0, 0, 0, 0,
  31.                     fldvNOCHECKS, fldrREADWRITE
  32.                    },
  33.                    {
  34.                     3, "Last Name", fldZSTRING, fldUNKNOWN,
  35.                     NAMELEN, 0, 0, 0, 0,
  36.                     fldvNOCHECKS, fldrREADWRITE
  37.                    },
  38.                    {
  39.                     4, "DOB", fldDATE, fldUNKNOWN,
  40.                     0, 0, 0, 0, 0,
  41.                     fldvNOCHECKS, fldrREADWRITE
  42.                    },
  43.                    {
  44.                     5, "POB", fldZSTRING, fldUNKNOWN,
  45.                     20, 0, 0, 0, 0,
  46.                     fldvNOCHECKS, fldrREADWRITE
  47.                    },
  48.                    { // Note that Memo fields in PARADOX require a
  49.                      // size - this is the amount of the BLOB which
  50.                      // is stored within the actual table as well 
  51.                      // as being stored in the .MB file.
  52.                     6, "General Info", fldBLOB, fldstMEMO,
  53.                     20, 0, 0, 0, 0,
  54.                     fldvNOCHECKS, fldrREADWRITE
  55.                    }
  56.         };  // Array of field descriptors
  57.  
  58. static SNIPFAR IDXDesc idxDesc[] = {
  59.                    { // Primary Index
  60.                     "Full Name",  // Name
  61.                     1,            // Number
  62.                     { NULL },     // Tag name ( for dBase )
  63.                     { NULL },     // Optional Format ( BTREE,
  64.                                   // HASH, etc )
  65.                     TRUE,         // Primary?
  66.                     TRUE,         // Unique?
  67.                     FALSE,        // Descending?
  68.                     TRUE,         // Maintained?
  69.                     FALSE,        // SubSet?
  70.                     FALSE,        // Expression index?
  71.                     NULL,         // For QBE only
  72.                     3,            // Fields in key
  73.                     1,            // Length in bytes
  74.                     FALSE,        // Index out of date?
  75.                     0,            // Key type of expression
  76.                     { 1,2,3 },    // Array of field numbers
  77.                     { 0 },        // Key expression
  78.                     { 0 },        // Key condition
  79.                     FALSE,        // Case insensitive
  80.                     0,            // Block size in bytes
  81.                     0
  82.                    }
  83.             };
  84.  
  85. // Number of fields in the table
  86. const unsigned uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]);
  87.  
  88. // Number of indexes in the table
  89. const unsigned uNumIndexes = sizeof(idxDesc) / sizeof(idxDesc[0]);
  90.  
  91. void        FillFullRecord(hDBICur, pBYTE);
  92. void        FillHalfRecord (hDBICur, pBYTE);
  93. DBIResult   FillFields (hDBICur hCur, pCHAR pszFNAME, pCHAR pszMNAME,
  94.                         pCHAR pszLNAME, UINT16 uMonth, UINT16 uDay, UINT16 uYear,
  95.                         pCHAR pszPOB, pBYTE pRecBuf);
  96. void        FillString(pCHAR);
  97. void        FillHalfString (pCHAR);
  98. void        DispBlob(hDBICur , pBYTE);
  99.  
  100. //=====================================================================
  101. //  Function:
  102. //          SimpleBlobIO();
  103. //
  104. //  Description:
  105. //          This example shows how to read and write BLOBs.  This example
  106. //          will cover how to access entire BLOB information and sections
  107. //          of a BLOB.
  108. //=====================================================================
  109. void
  110. SimpleBlobIO (void)
  111. {
  112.     DBIResult   rslt;               // Value returned from IDAPI functions
  113.     hDBIDb      hDb;                // Handle to the database
  114.     hDBICur     hCur;               // Handle to the table
  115.     CURProps    TblProps;           // Table properties
  116.     pBYTE       pRecBuf = NULL;     // Pointer to the record buffer
  117.     CRTblDesc   crTblDsc;           // Create Table descriptor
  118.     BOOL        bOverWrite = TRUE;  // Overwrite, yes/no flag
  119.     UINT16      rcdSize;            // Size of the record
  120.  
  121.     Screen("*** Simple BLOB I/O Example ***\r\n");
  122.  
  123.     BREAK_IN_DEBUGGER();
  124.  
  125.     Screen("    Initializing IDAPI...");
  126.     if (InitAndConnect(&hDb) != DBIERR_NONE) 
  127.     {
  128.         Screen("\r\n*** End of Example ***");
  129.         return;
  130.     }
  131.  
  132.     Screen("    Setting the database directory...");
  133.     rslt = DbiSetDirectory(hDb, (pCHAR) szTblDirectory);
  134.     ChkRslt(rslt, "SetDirectory");
  135.  
  136.     // Initialize the table create descriptor.
  137.     memset(&crTblDsc,0, sizeof(CRTblDesc));
  138.     strcpy(crTblDsc.szTblName, szTblName) ;
  139.     strcpy(crTblDsc.szTblType, szTblType) ;
  140.     crTblDsc.iFldCount     = uNumFields ;
  141.     crTblDsc.pfldDesc      = fldDesc ;
  142.     crTblDsc.iIdxCount     = uNumIndexes ;
  143.     crTblDsc.pidxDesc      = idxDesc ;      
  144.  
  145.     Screen("    Create the %s table...", szTblName);
  146.     rslt = DbiCreateTable(hDb, bOverWrite, &crTblDsc);
  147.     if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
  148.     {
  149.         CloseDbAndExit(&hDb);
  150.         Screen("\r\n*** End of Example ***");
  151.         return;
  152.     }
  153.  
  154.     rslt = DbiOpenTable(hDb,(pCHAR) szTblName,(pCHAR) szTblType,
  155.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
  156.                         xltFIELD, FALSE, NULL, &hCur);
  157.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  158.     {
  159.         CloseDbAndExit(&hDb);
  160.         Screen("\r\n*** End of Example ***");
  161.         return;
  162.     }
  163.  
  164.     // Allocate memory for the record buffer
  165.     rslt = DbiGetCursorProps(hCur, &TblProps);
  166.     ChkRslt(rslt, "GetCursorProps");
  167.  
  168.     rcdSize = TblProps.iRecBufSize;
  169.  
  170.     pRecBuf  = (pBYTE)malloc(sizeof(BYTE) * rcdSize);
  171.  
  172.     // Fill the database with a string set in the FillRecord
  173.     //   function.
  174.     FillFullRecord(hCur, pRecBuf);
  175.  
  176.     // Display the BLOB.
  177.     Screen("\r\n    This is the BLOB information in Record #1\r\n");
  178.     DispBlob(hCur, pRecBuf);
  179.  
  180.     // Create another record and fill it with the same
  181.     //   data.  However, change the BLOB info with DbiPutBlob.
  182.     FillHalfRecord(hCur, pRecBuf);
  183.  
  184.     // Display the BLOB.
  185.     Screen("\r\n    This is the BLOB information in Record #2\r\n");
  186.     DispBlob(hCur, pRecBuf);
  187.  
  188.     // Clean up.
  189.  
  190.     free(pRecBuf);
  191.  
  192.     Screen("\r\n    Close the %s table...", szTblName);
  193.     rslt = DbiCloseCursor(&hCur);
  194.     ChkRslt(rslt, "CloseCursor");
  195.  
  196.     Screen("    Delete the %s table...", szTblName);
  197.     rslt = DbiDeleteTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType);
  198.     ChkRslt(rslt, "DeleteTable");
  199.  
  200.     Screen("    Close the database and exit IDAPI...");
  201.     CloseDbAndExit(&hDb);
  202.  
  203.     Screen("\r\n*** End of Example ***");
  204. }
  205.  
  206. //=====================================================================
  207. //  Function:
  208. //          FillFullRecord(hCur, pRecBuf);
  209. //
  210. //  Input:  hCur    - Cursor to Table
  211. //          pRecBuf - Record Buffer
  212. //
  213. //  Return: Dbi Result
  214. //
  215. //  Desc:   This function takes the cursor and fills the record
  216. //          buffer with pre-assigned values (static values for this
  217. //          example).  It returns an error if we encounter one.
  218. //          This function makes the code a bit more readable.
  219. //=====================================================================
  220. void
  221. FillFullRecord (hDBICur hCur, pBYTE pRecBuf)
  222. {
  223.     pCHAR       pGenInfo;   // Buffer to contain the string which is
  224.                             //   written to the BLOB field.
  225.     DBIResult   rslt;       // Return value from IDAPI functions
  226.  
  227.     // Initialize the record buffer before filling it
  228.     rslt = DbiInitRecord(hCur, pRecBuf);
  229.     ChkRslt(rslt, "InitRecord");
  230.  
  231.     // Allocate a buffer that is capable of holding a large string.
  232.     pGenInfo = (pCHAR) malloc(sizeof (CHAR) * 1200);
  233.     if (pGenInfo == NULL)
  234.     {
  235.         return;
  236.     }
  237.  
  238.     // Function will fill the pGeninfo pointer with a string
  239.     //   that is larger than 256 bytes.
  240.     FillString(pGenInfo);
  241.  
  242.     // Fill the fields of the buffer. The fields are filled directly,
  243.     //   but a variable could be used that would hold the string, date or
  244.     //   BLOB information.
  245.     FillFields(hCur, "Charlie", "L", "Carm", 12, 24, 55, "New York",
  246.                pRecBuf);
  247.  
  248.     // Open the BLOB.  To write or read from a BLOB you must open the
  249.     //   BLOB first.  All that is needed is the cursor, the record buffer,
  250.     //   the field number and the rights.  If the BLOB is opened in
  251.     //   ReadWrite mode, the table must be opened in ReadWrite mode also.
  252.     rslt = DbiOpenBlob(hCur, pRecBuf, 6, dbiREADWRITE);
  253.     ChkRslt(rslt, "OpenBlob");
  254.  
  255.     // Put the whole BLOB into the field.
  256.     rslt = DbiPutBlob(hCur, pRecBuf, 6, 0, (strlen(pGenInfo) + 1),
  257.                       (pBYTE) pGenInfo);
  258.     ChkRslt(rslt, "PutBlob");
  259.  
  260.     // Append a record to the table.
  261.     rslt = DbiAppendRecord(hCur, pRecBuf);
  262.     ChkRslt(rslt, "AppendRecord");
  263.  
  264.     free(pGenInfo);
  265.  
  266.     rslt = DbiFreeBlob(hCur, pRecBuf, 6);
  267.     ChkRslt(rslt, "FreeBlob");
  268. }
  269.  
  270. //=====================================================================
  271. //  Function:
  272. //          FillHalfRecord(hCur, pRecBuf);
  273. //
  274. //  Input:  hCur    - Cursor to Table
  275. //          pRecBuf - Record Buffer
  276. //
  277. //  Return: Dbi Result
  278. //
  279. //  Desc:   This function takes the cursor and fills the record
  280. //          buffer with pre-assigned values (static values for this
  281. //          example).  It returns an error if we encounter one.
  282. //          This function makes the code a bit more readable.
  283. //=====================================================================
  284. void
  285. FillHalfRecord (hDBICur hCur, pBYTE pRecBuf)
  286. {
  287.     pCHAR       pGenInfo;   // Buffer to contain the string which is
  288.                             //   written to the BLOB field.
  289.     UINT16      GenLen;     // Length of the string
  290.     DBIResult   rslt;       // Return value from IDAPI functions
  291.  
  292.     // Initialize the record buffer before filling it.
  293.     rslt = DbiInitRecord(hCur, pRecBuf);
  294.     ChkRslt(rslt, "InitRecord");
  295.  
  296.     // Allocate a buffer that is capable of holding a large string.
  297.     pGenInfo = (pCHAR) malloc(sizeof (CHAR) * 1200);
  298.     if (pGenInfo == NULL)
  299.     {
  300.         return;
  301.     }
  302.  
  303.     // Function will fill the pGeninfo pointer with a string
  304.     //   that is larger than 256 bytes.
  305.     FillString(pGenInfo);
  306.  
  307.     // Fill the fields of the buffer. The fields are filled directly,
  308.     //   but a variable could be used that would hold the string, date or
  309.     //   BLOB information.
  310.     FillFields(hCur, "Ronald", "P", "Halter", 8, 15, 70, "Chicago",
  311.                pRecBuf);
  312.  
  313.     // Open the BLOB.  To write or read from a BLOB you must open the
  314.     //   BLOB first.  All that is needed is the cursor, the record buffer,
  315.     //   the field number and the rights.  If the BLOB is opened in
  316.     //   ReadWrite mode, the table must be opened in ReadWrite mode also.
  317.     rslt = DbiOpenBlob(hCur, pRecBuf, 6, dbiREADWRITE);
  318.     ChkRslt(rslt, "OpenBlob");
  319.  
  320.     // Put the whole BLOB into the field
  321.     rslt = DbiPutBlob(hCur, pRecBuf, 6, 0, (strlen(pGenInfo) + 1),
  322.                       (pBYTE) pGenInfo);
  323.     ChkRslt(rslt, "PutBlob");
  324.  
  325.     // Get the length of the present BLOB information before changing
  326.     //   it.
  327.     GenLen = strlen(pGenInfo);
  328.  
  329.     // Clear the pGenINfo Buffer.
  330.     memset(pGenInfo,0, sizeof(pGenInfo));
  331.  
  332.     // Fill the pGenInfo buffer with a new string.
  333.     FillHalfString(pGenInfo);
  334.  
  335.     // Change half of the present BLOB value by
  336.     //   putting a new string in the second half of the BLOB.
  337.     //   Use the length of the originally inserted BLOB divided
  338.     //   by two to find the halfway point and add one to compensate
  339.     //   for the odd length.
  340.     rslt = DbiPutBlob(hCur, pRecBuf, 6, (GenLen/2), strlen(pGenInfo),
  341.                       (pBYTE) pGenInfo);
  342.     ChkRslt(rslt, "PutBlob");
  343.  
  344.     // Append a record to the table.
  345.     rslt = DbiAppendRecord(hCur, pRecBuf);
  346.     ChkRslt(rslt, "AppendRecord");
  347.  
  348.     free(pGenInfo);
  349.  
  350.     rslt = DbiFreeBlob(hCur, pRecBuf, 6);
  351.     ChkRslt(rslt, "FreeBlob");
  352. }
  353.  
  354. //=====================================================================
  355. //  Function:
  356. //          FillString(pString);
  357. //
  358. //  Input:  pString -   A string buffer that will be written into by the
  359. //                      function
  360. //
  361. //  Return: None  (The input string is modified.)
  362. //
  363. //  Desc:   This example fills the input string with a preset string, 
  364. //          which is larger than 256 bytes.
  365. //=====================================================================
  366. void
  367. FillString (pCHAR pString)
  368. {
  369.     strcpy(pString,
  370.            "        This is a test of the BLOB functions.  The power of "
  371.            "a BLOB is that it can contain anything.\r\n"
  372.            "        This is a test of the BLOB functions.  The power of "
  373.            "a BLOB is that it can contain anything.\r\n"
  374.            "        This is a test of the BLOB functions.  The power of "
  375.            "a BLOB is that it can contain anything.\r\n"
  376.            "        This is a test of the BLOB functions.  The power of "
  377.            "a BLOB is that it can contain anything.\r\n"
  378.            "        This is a test of the BLOB functions.  The power of "
  379.            "a BLOB is that it can contain anything.\r\n"
  380.            "        This is a test of the BLOB functions.  The power of "
  381.            "a BLOB is that it can contain anything.\r\n"
  382.            "        This is a test of the BLOB functions.  The power of "
  383.            "a BLOB is that it can contain anything.\r\n"
  384.            "        This is a test of the BLOB functions.  The power of "
  385.            "a BLOB is that it can contain anything.\r\n");
  386. }
  387.  
  388. //=====================================================================
  389. //  Function:
  390. //          FillHalfString(pString);
  391. //
  392. //  Input:  pString -   A string buffer that will be written into by the
  393. //                      function
  394. //
  395. //  Return: None  (The input string is modified.)
  396. //
  397. //  Desc:   This example fills the input string with a preset string, 
  398. //          which is larger than 256 bytes.  The string used is different
  399. //          from the one used in FillString().
  400. //=====================================================================  
  401. void
  402. FillHalfString (pCHAR pString)
  403. {
  404.     strcpy(pString,
  405.            "        This is line 1 of the BLOB functions.  The power of a"
  406.            " BLOB is that it is dynamic and quick.\r\n"
  407.            "        This is line 2 of the BLOB functions.  The power of a"
  408.            " BLOB is that it is dynamic and quick.\r\n"
  409.            "        This is line 3 of the BLOB functions.  The power of a"
  410.            " BLOB is that it is dynamic and quick.\r\n"
  411.            "        This is line 4 of the BLOB functions.  The power of a"
  412.            " BLOB is that it is dynamic and quick.\r\n");
  413. }
  414.  
  415. //=====================================================================
  416. //  Function:
  417. //          DispBlob(hCur, pRecBuf);
  418. //
  419. //  Input:  hCur    -   Table Cursor
  420. //          pRecBuf -   Record Buffer
  421. //
  422. //  Return: None
  423. //
  424. //  Desc:   This function displays the BLOB field that is pointed to by
  425. //          the cursor and which resides in the record buffer.  The
  426. //          function displays the whole BLOB and then half of the BLOB.
  427. //          It uses DbiGetBlob with and without a range to accomplish
  428. //          this.
  429. //=====================================================================
  430. void
  431. DispBlob (hDBICur hCur, pBYTE pRecBuf)
  432. {
  433.     UINT32      BlobSize;           // Size of the BLOB
  434.     UINT32      ActualSize;         // Actual size of the BLOB as read
  435.                                     //  from the table
  436.     pBYTE       phBlob = NULL;      // Pointer to BLOB data
  437.     pBYTE       phHalfBlob = NULL;  // Pointer to BLOB data
  438.     DBIResult   rslt;
  439.  
  440.     rslt = DbiInitRecord(hCur, pRecBuf);
  441.     ChkRslt(rslt, "InitRecord");
  442.  
  443.     // Get the record from the table.
  444.     rslt = DbiGetRecord(hCur, dbiWRITELOCK, pRecBuf, 0);
  445.     ChkRslt(rslt, "GetRecord");
  446.  
  447.     // Open the BLOB.  The BLOB must be opened before reading from 
  448.     //   or writing to it.
  449.     //   This part locks the record in the previous function DbiGetRecord
  450.     //   with the WRITELOCK option.  No lock on the BLOB is needed as the
  451.     //   BLOB will not be modified.
  452.     rslt = DbiOpenBlob(hCur, pRecBuf, 6, dbiREADONLY);
  453.     ChkRslt(rslt, "OpenBlob");
  454.  
  455.     // Now get the size of the BLOB
  456.     rslt = DbiGetBlobSize(hCur, pRecBuf, 6, &BlobSize);
  457.     ChkRslt(rslt, "GetBlobSize");
  458.  
  459.     // Allocate the memory for the BLOB buffer.
  460.     phBlob  = (pBYTE)malloc( sizeof(BYTE) * (UINT16)BlobSize);
  461.  
  462.     // Allocate memory for the pHalfBlob buffer
  463.     phHalfBlob  = (pBYTE)malloc(((sizeof(BYTE) * (UINT16)BlobSize)/2)+2);
  464.  
  465.     // Initialize the buffers to 0.  Cast the Blobsize to UINT16 because
  466.     //   the memset function expects a UINT16. (Assume for the example that
  467.     //   the BLOB is less than 64K in size.
  468.     memset(phBlob, 0, (UINT16)BlobSize);
  469.     memset(phHalfBlob, 0, ((UINT16)BlobSize/2)+ 2);
  470.  
  471.     // Get the BLOB from the table.
  472.     rslt = DbiGetBlob(hCur, pRecBuf, 6, 0, BlobSize, phBlob, &ActualSize);
  473.     ChkRslt(rslt, "GetBlob");
  474.  
  475.     Screen("    This is the whole BLOB Field\r\n");
  476.     Screen((pCHAR)phBlob);
  477.  
  478.     // Now we are going to get half the BLOB and display that.  To get
  479.     //   half the BLOB we start at half the total size (BlobSize/2) and
  480.     //   retrieve the bytes (BlobSize/2).
  481.     rslt = DbiGetBlob(hCur, pRecBuf, 6, ((BlobSize) / 2), ((BlobSize) / 2),
  482.                       phHalfBlob, &ActualSize);
  483.     ChkRslt(rslt, "GetBlob");
  484.  
  485.     Screen("    This is half of the BLOB field\r\n");
  486.     Screen((pCHAR)phHalfBlob);
  487.  
  488.     rslt = DbiFreeBlob(hCur, pRecBuf, 6);
  489.     ChkRslt(rslt, "FreeBlob");
  490.  
  491.     free(phBlob);
  492.     free(phHalfBlob);
  493. }
  494.  
  495. //=====================================================================
  496. //  Function:
  497. //          FillFields(hCur, pszFirst, pszMiddle, pszLast, iMonth,
  498. //                     iDay, iYear, pszPOB, pRecBuf);
  499. //
  500. //  Input:  hCur        - Cursor handle
  501. //          pszFirst    - First Name
  502. //          pszMiddle   - Middle Name
  503. //          pszLast     - Last Name
  504. //          iMonth      - Month
  505. //          iDay        - Day
  506. //          iYear       - Year
  507. //          pszPOB      - Place of birth
  508. //          pRecBuf     - record buffer
  509. //
  510. //  Return: Result of adding the fields to the record buffer
  511. //
  512. //  Description:
  513. //          This function will add data to a pre-existing
  514. //          record buffer.
  515. //=====================================================================
  516. DBIResult
  517. FillFields (hDBICur hCur, pCHAR pszFirst, pCHAR pszMiddle, pCHAR pszLast,
  518.             UINT16 iMonth, UINT16 iDay, UINT16 iYear, pCHAR pszPOB,
  519.             pBYTE pRecBuf)
  520. {
  521.     DBIDATE     dDate;  // Date structure
  522.     DBIResult   rslt;   // Return value from IDAPI functions
  523.  
  524.     // First Name.
  525.     rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) pszFirst);
  526.     ChkRslt(rslt, "PutField");
  527.  
  528.     // Middle Name.
  529.     rslt = DbiPutField(hCur, 2,  pRecBuf, (pBYTE) pszMiddle);
  530.     ChkRslt(rslt, "PutField");
  531.  
  532.     // Last Name.
  533.     rslt = DbiPutField(hCur, 3,  pRecBuf, (pBYTE) pszLast);
  534.     ChkRslt(rslt, "PutField");
  535.  
  536.     // Date of Birth.
  537.     rslt = DbiDateEncode(iMonth, iDay, iYear, &dDate);
  538.     ChkRslt(rslt, "DateEncode");
  539.  
  540.     // If the date is legal we add it to
  541.     //   the fourth field in the record. (Date of Birth)
  542.     rslt = DbiPutField(hCur, 4, pRecBuf, (pBYTE)&dDate);
  543.     ChkRslt(rslt, "PutField");
  544.  
  545.     // Place of Birth.
  546.     rslt = DbiPutField(hCur, 5,  pRecBuf, (pBYTE) pszPOB);
  547.     ChkRslt(rslt, "PutField");
  548.  
  549.     return DBIERR_NONE;
  550. }
  551.  
  552.