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

  1. // BDE - (C) Copyright 1995 by Borland International
  2.  
  3. // valcheck.c
  4. #include "snipit.h"
  5. #include <dos.h>
  6.  
  7. // Set the length of the Cube Number field.
  8. #define CUBELEN  10
  9.  
  10. static const char szTblName[] = "personel";
  11. static const char szTblType[] = szPARADOX;
  12.  
  13. // Lookup table name.
  14. static const char szTblLookup[] = "CubeNum";
  15.  
  16. // Field descriptor used in creating the main table.
  17. static SNIPFAR FLDDesc fldDesc[] = {
  18.                   { // Field 1 - Full Name
  19.                      1,            // Field number
  20.                      "Full Name",  // Field name
  21.                      fldZSTRING,   // Field type
  22.                      fldUNKNOWN,   // Field subtype
  23.                      40,           // 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.                      fldvHASCHECKS,// This field has validity checking
  31.                      fldrREADWRITE // Rights
  32.                   },
  33.                   { // Field 2 - Employee Number
  34.                      2, "Employee Number", fldINT16, fldUNKNOWN,
  35.                      0, 0, 0, 0, 0,
  36.                      fldvHASCHECKS, fldrREADWRITE
  37.                   },
  38.                   { // Field 3 - Department Number
  39.                      3, "Department Number", fldINT16, fldUNKNOWN,
  40.                      0, 0, 0, 0, 0,
  41.                      fldvHASCHECKS, fldrREADWRITE
  42.                   },
  43.                   { // Field 4 - Building Number
  44.                      4, "Building Number", fldINT16, fldUNKNOWN,
  45.                      0, 0, 0, 0, 0,
  46.                      fldvHASCHECKS, fldrREADWRITE
  47.                   },
  48.                   { // Field 5 - Social Security Number
  49.                      5, "SS Number", fldZSTRING, fldUNKNOWN,
  50.                      11, 0, 0, 0, 0,
  51.                      fldvHASCHECKS, fldrREADWRITE
  52.                   },
  53.                   { // Field 6 - Cube Number
  54.                      6, "Cube Number", fldZSTRING, fldUNKNOWN,
  55.                      CUBELEN, 0, 0, 0, 0,
  56.                      fldvHASCHECKS, fldrREADWRITE
  57.                   }
  58.                  };  // Array of field descriptors.
  59.  
  60. // Field descriptor used to create the lookup table.
  61. static SNIPFAR FLDDesc lkfldDesc[] = {
  62.                   { // Field 1 - Full Name
  63.                      1,            // Field number
  64.                      "Cube Number",// Field name
  65.                      fldZSTRING,   // Field type
  66.                      fldUNKNOWN,   // Field subtype
  67.                      CUBELEN,      // Field size (1 or 0, except
  68.                                    //   BLOB or CHAR field)
  69.                      0,            // Decimal places   ( 0 )
  70.                                    //   computed
  71.                      0,            // Offset in record ( 0 )
  72.                      0,            // Length in bytes  ( 0 )
  73.                      0,            // For Null bits    ( 0 )
  74.                      fldvNOCHECKS, // This field has validity checking
  75.                      fldrREADWRITE // Rights
  76.                   }
  77.                  };  // Array of field descriptors
  78.                                   
  79. // Validity check descriptor - Describes the validity checks.  This validity
  80. //   check will be added to the table when the table is created.
  81. //   Note: The min val, max val, and default val validity checks are set
  82. //   within the CreateValCheck function, because the validity check
  83. //   needs to store data in the same format as the field.  In this case
  84. //   the fields are fldINT16.  This requires that a memset be done to
  85. //   copy the value into the validity check.
  86. static SNIPFAR VCHKDesc VchkDesc[] = {
  87.             { // First field validity check - Required field.
  88.                 1,          // Field number this belongs to
  89.                 TRUE,       // Is a required field
  90.                 FALSE,      // If True, has min value
  91.                 FALSE,      // If True, has max value
  92.                 FALSE,      // If True, has default value
  93.                 { NULL },   // Min value
  94.                 { NULL },   // Max value
  95.                 { NULL },   // Default value
  96.                 { NULL },   // Picture string
  97.                 lkupNONE,   // Lookup/Fill type
  98.                 { NULL },   // Lookup table name
  99.             },
  100.             { // Second field validity check - min value - see note above.
  101.                 2, FALSE, TRUE, FALSE, FALSE, {"15"}, { NULL },
  102.                 { NULL }, { NULL }, lkupNONE, { NULL }
  103.             },
  104.             { // Third field validity check - max value - see note above.
  105.                 3, FALSE, FALSE, TRUE, FALSE, { NULL }, {"3000"},
  106.                 { NULL }, { NULL }, lkupNONE, { NULL }
  107.             },
  108.             { // Fourth field validity check - default value - see note
  109.               // above.
  110.                 4, FALSE, FALSE, FALSE, TRUE, { NULL }, { NULL },
  111.                 {"8"}, { NULL }, lkupNONE, { NULL }
  112.             },
  113.             { // Fifth field validity check - picture of a SS number.
  114.                 5, FALSE, FALSE, FALSE, FALSE, { NULL }, { NULL },
  115.                 { NULL }, { "###-##-####" }, lkupNONE, { NULL }
  116.             },
  117.             { // Sixth field validity check - lookup table.
  118.                 6, FALSE, FALSE, FALSE, FALSE, { NULL }, { NULL },
  119.                 { NULL }, { NULL }, lkupPRIVATE, "cubenum.db"
  120.             }
  121.         };
  122.  
  123. // Index descriptor.
  124. static SNIPFAR IDXDesc idxDesc[] = {
  125.                 { // Primary Index - Full Name
  126.                     "Employee Name",    // Name
  127.                     1,                  // Number
  128.                     { NULL },           // Tag name ( for dBase )
  129.                     { NULL },           // Optional format ( BTREE,
  130.                                         // HASH, etc )
  131.                     TRUE,               // Primary?
  132.                     TRUE,               // Unique?
  133.                     FALSE,              // Descending?
  134.                     TRUE,               // Maintained?
  135.                     FALSE,              // Subset?
  136.                     FALSE,              // Expression index?
  137.                     NULL,               // For QBE only
  138.                     1,                  // Fields in key
  139.                     1,                  // Length in bytes
  140.                     FALSE,              // Index out of date?
  141.                     0,                  // Key type of expression
  142.                     { 1 },              // Array of field numbers
  143.                     { 0 },              // Key expression
  144.                     { 0 },              // Key condition
  145.                     FALSE,              // Case insensitive
  146.                     0,                  // Block size in bytes
  147.                     0                   // Restructure number
  148.                 }
  149.           };
  150.  
  151. // Index descriptor. This index array will be used to create the lookup table's
  152. // primary index.
  153. static SNIPFAR IDXDesc lkidxDesc[] = {
  154.                 { // Primary Index - Full name
  155.                     "Cube_Number",// Name
  156.                     1,            // Number
  157.                     { NULL },     // Tag name ( for dBase )
  158.                     { NULL },     // Optional format ( BTREE,
  159.                                   //   HASH, etc )
  160.                     TRUE,         // Primary?
  161.                     TRUE,         // Unique?
  162.                     FALSE,        // Descending?
  163.                     TRUE,         // Maintained?
  164.                     FALSE,        // Subset?
  165.                     FALSE,        // Expression index?
  166.                     NULL,         // For QBE only
  167.                     1,            // Fields in key
  168.                     1,            // Length in bytes
  169.                     FALSE,        // Index out of date?
  170.                     0,            // Key type of expression
  171.                     { 1 },        // Array of field numbers
  172.                     { 0 },        // Key expression
  173.                     { 0 },        // Key condition
  174.                     FALSE,        // Case insensitive
  175.                     0,            // Block size in bytes
  176.                     0             // Restructure number
  177.                 }
  178.           };
  179.  
  180. // The number of fields in the table.
  181. static const unsigned uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]);
  182.  
  183. // Number of indexes to be created when the table is created.
  184. static const unsigned uNumIndexes = sizeof(idxDesc) / sizeof(idxDesc[0]);
  185.  
  186. // The number of fields in the lookup table.
  187. static const unsigned ulkNumFields = sizeof(lkfldDesc) /
  188.                                      sizeof (lkfldDesc[0]);
  189.  
  190. // Number of indexes to be created when the lookup table is created.
  191. static const UINT16 ulkNumIndexes = sizeof(lkidxDesc) / sizeof(lkidxDesc[0]);
  192.  
  193. // Number of validity checks to be created.
  194. static const UINT16 uNumVchks = sizeof(VchkDesc) / sizeof(VchkDesc[0]);
  195.  
  196. static DBIResult CreateVCHKTable(phDBIDb phDb);
  197. static DBIResult InitLKTable(phDBIDb phDb);
  198. static DBIResult AddRecord(hDBICur hCur, pCHAR pszName, INT16 lEmpNum,
  199.                            INT16 lDeptNum, INT16 lBuildNum, pCHAR pszSSNum,
  200.                            pCHAR pszCube);
  201. static DBIResult AddLKRecord(hDBICur hCur, pCHAR pszCube);
  202. static DBIResult FindRecord(pCHAR pszString, hDBICur hCur);
  203. static void FormatPic(pCHAR pszDest, pCHAR pszPicture, pCHAR pszData);
  204.  
  205. //=====================================================================
  206. //  Function:
  207. //          ValCheck();
  208. //
  209. //  Description:
  210. //          This function shows how validity checks are used on a Paradox
  211. //          table.  This example will create a table to which the validity
  212. //          checks are added, as well as a lookup table which is used as
  213. //          part of the validity checks.  All tables are deleted at the end
  214. //          of this example.
  215. //
  216. //          This example places the following validity checks on the table:
  217. //              Required on the "Full Name" field.
  218. //              Minimum value of "15" on the "Employee Number" field.
  219. //              Maximum value of "3000" on the "Department Number" field.
  220. //              Default value of "8" on the "Building Number" field.
  221. //              Picture on the "SS Number" field.
  222. //              Lookup table for the "Cube Number" field.
  223. //=====================================================================
  224. void
  225. ValCheck (void)
  226. {
  227.     DBIResult   rslt;           // Return value from IDAPI functions
  228.     hDBIDb      hDb;            // Database handle
  229.     hDBICur     hCur;           // Cursor handle
  230.     CURProps    TblProps;       // Table properties
  231.     CHAR        SSNumber[12];   // SS number string used for VC pictures
  232.  
  233.     Screen("*** Validity Check Example ***\r\n");
  234.  
  235.     BREAK_IN_DEBUGGER();
  236.  
  237.     Screen("    Initializing IDAPI...");
  238.     if (InitAndConnect(&hDb) != DBIERR_NONE)
  239.     {
  240.         Screen("\r\n*** End of Example ***");
  241.         return;
  242.     }
  243.  
  244.     Screen("    Setting the database directory...");
  245.     rslt = DbiSetDirectory(hDb, (pCHAR) szTblDirectory);
  246.     ChkRslt(rslt, "SetDirectory");
  247.  
  248.     // Create the lookup table and fill with data.
  249.     if (InitLKTable(&hDb))
  250.     {
  251.         CloseDbAndExit(&hDb);
  252.         Screen("\r\n*** End of Example ***");
  253.         return;
  254.     }
  255.  
  256.     // Create the table and attach the validity checks.
  257.     if (CreateVCHKTable(&hDb))
  258.     {
  259.         CloseDbAndExit(&hDb);
  260.         Screen("\r\n*** End of Example ***");
  261.         return;
  262.     }
  263.  
  264.     Screen("    Open the %s table...", szTblName);
  265.     rslt = DbiOpenTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType,
  266.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
  267.                         xltFIELD, FALSE, NULL, &hCur);
  268.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  269.     {
  270.         CloseDbAndExit(&hDb);
  271.         Screen("\r\n*** End of Example ***");
  272.         return;
  273.     }
  274.  
  275.     Screen("    Get the number of validity checks on the %s table...",
  276.            szTblName);
  277.     rslt = DbiGetCursorProps(hCur, &TblProps);
  278.     ChkRslt(rslt, "GetCursorProps");
  279.  
  280.     Screen("    There are %d validity checks on the table",
  281.            TblProps.iValChecks);
  282.  
  283.     // Add a record without the required field (field #1).
  284.     Screen("\r\n    Adding the first record...");
  285.  
  286.     // IDAPI does not format the data to match the picture.  It only stores
  287.     //   the picture.
  288.     FormatPic(SSNumber, "###-##-####", "111223333");
  289.  
  290.     Screen("        Error expected - adding a record that does not have data"
  291.            "\r\n                         in the first field (Full Name),"
  292.            "\r\n                         which is a required field...");
  293.     AddRecord(hCur, "", 20, 2809, NULL, SSNumber, "2001");
  294.  
  295.     Screen("\r\n    Adding a record which satisfies the following"
  296.            " validity checks:\r\n\r\n\t"
  297.            "    Required field for the first field - Full Name\r\n\t"
  298.            "    Minimum Value of 15 for the second field - Employee Number"
  299.            "\r\n\t"
  300.            "    Maximum value of 3000 for the third field - Department Number"
  301.            "\r\n\t"
  302.            "    Default value of 8 for the fourth field - Building Number"
  303.            "\r\n\t"
  304.            "    Picture of ###-##-#### for the fifth field - SS Number"
  305.            "\r\n\t"
  306.            "    Lookup table for the sixth field - Cube Number\r\n");
  307.  
  308.     // We are passing in NULL to the AddRecord function so that IDAPI will
  309.     //   fill in the default value of 8 for the Building Number field.       
  310.     AddRecord(hCur, "Goliath Mager", 24, 2806, NULL, SSNumber, "2004");
  311.  
  312.     // Find the newly added record so we can display it.
  313.     FindRecord("Goliath Mager", hCur);
  314.  
  315.     Screen("    Displaying the record...");
  316.     DisplayNextRecord(hCur);
  317.  
  318.     Screen("\r\n    Close the table...");
  319.     rslt = DbiCloseCursor(&hCur);
  320.     ChkRslt(rslt, "CloseCursor");
  321.  
  322.     Screen("    Delete the table...");
  323.     rslt = DbiDeleteTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType);
  324.     ChkRslt(rslt, "DeleteTable");
  325.  
  326.     Screen("    Delete the lookup table and indexes...");
  327.     rslt = DbiDeleteTable(hDb, (pCHAR) szTblLookup, (pCHAR) szTblType);
  328.     ChkRslt(rslt, "DeleteTable");
  329.  
  330.     Screen("    Close the database and exit IDAPI...");
  331.     CloseDbAndExit(&hDb);
  332.  
  333.     Screen("\r\n*** End of Example ***");
  334. }
  335.  
  336. //=====================================================================
  337. //  Function:
  338. //          CreateVCHKTable(phDb);
  339. //
  340. //  Input:  phDb    - Pointer to the database handle
  341. //
  342. //  Return: Result of the table initialization
  343. //
  344. //  Description:
  345. //          This function will create a table with the validity
  346. //          checks that are in the array called VchkDesc.
  347. //=====================================================================
  348. DBIResult
  349. CreateVCHKTable (phDBIDb phDb)
  350. {
  351.     DBIResult   rslt;               // Value returned from IDAPI functions
  352.     CRTblDesc   crTblDsc;           // Table descriptor
  353.     BOOL        bOverWrite = TRUE;  // Overwrite, yes/no flag
  354.     INT16       iDefVal = 8;        // Default value for the "Building Number"
  355.                                     //   Field
  356.     INT16       iMinVal = 15;       // Min Value for the "Employee Number"
  357.                                     //   field
  358.     INT16       iMaxVal = 3000;     // Max value for the "Department Number"
  359.                                     //   field
  360.  
  361.     // Need to have actual integer values for the validity check.
  362.     memcpy(&(VchkDesc[1].aMinVal), &iMinVal, sizeof(INT16));
  363.     memcpy(&(VchkDesc[2].aMaxVal), &iMaxVal, sizeof(INT16));
  364.     memcpy(&(VchkDesc[3].aDefVal), &iDefVal, sizeof(INT16));
  365.  
  366.     // Initialize the table create descriptor.
  367.     memset(&crTblDsc, 0, sizeof(CRTblDesc));
  368.     strcpy(crTblDsc.szTblName, szTblName);
  369.     strcpy(crTblDsc.szTblType, szTblType);
  370.     crTblDsc.iFldCount     = uNumFields;
  371.     crTblDsc.pfldDesc      = fldDesc;
  372.     crTblDsc.iIdxCount     = uNumIndexes;
  373.     crTblDsc.pidxDesc      = idxDesc;
  374.     crTblDsc.iValChkCount  = uNumVchks;
  375.     crTblDsc.pvchkDesc     = VchkDesc;
  376.  
  377.     Screen("    Creating the %s table...", szTblName);
  378.     rslt = DbiCreateTable(*phDb, bOverWrite, &crTblDsc);
  379.     if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
  380.     {
  381.         return rslt;
  382.     }
  383.  
  384.     return rslt;
  385. }
  386.  
  387. //=====================================================================
  388. //  Function:
  389. //          InitLKTable(phDb);
  390. //
  391. //  Input:  phDb    - Pointer to the database handle
  392. //
  393. //  Return: Result of the table initialization
  394. //
  395. //  Description:
  396. //          This function will create the lookup table that is used
  397. //          by the validity checks.
  398. //=====================================================================
  399. DBIResult
  400. InitLKTable (phDBIDb phDb)
  401. {
  402.     DBIResult   rslt;               // Value returned from IDAPI functions
  403.     hDBICur     hCur;               // Cursor handle for the table that is
  404.                                     //   created
  405.     CRTblDesc   crTblDsc;           // Table descriptor
  406.     BOOL        bOverWrite = TRUE;  // Overwrite, yes/no flag
  407.  
  408.     // Initialize the Table Create Descriptor.
  409.     memset(&crTblDsc, 0, sizeof(CRTblDesc));
  410.     strcpy(crTblDsc.szTblName, szTblLookup);
  411.     strcpy(crTblDsc.szTblType, szTblType);
  412.     crTblDsc.iFldCount     = ulkNumFields;
  413.     crTblDsc.pfldDesc      = lkfldDesc;
  414.     crTblDsc.iIdxCount     = ulkNumIndexes;
  415.     crTblDsc.pidxDesc      = lkidxDesc;
  416.  
  417.     Screen("    Creating lookup table and indexes...");
  418.     rslt = DbiCreateTable(*phDb, bOverWrite, &crTblDsc);
  419.     if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
  420.     {
  421.         return rslt;
  422.     }
  423.  
  424.     rslt = DbiOpenTable(*phDb, (pCHAR) szTblLookup, (pCHAR) szTblType,
  425.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
  426.                         xltFIELD, FALSE, NULL, &hCur);
  427.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  428.     {
  429.         return rslt;
  430.     }
  431.  
  432.     // Add some records into the lookup table.
  433.     AddLKRecord(hCur, "2001");
  434.     AddLKRecord(hCur, "2002");
  435.     AddLKRecord(hCur, "2003");
  436.     AddLKRecord(hCur, "2004");
  437.     AddLKRecord(hCur, "2005");
  438.     AddLKRecord(hCur, "2006");
  439.     AddLKRecord(hCur, "2007");
  440.  
  441.     // Close the table so it can be reopened from the calling function.
  442.     rslt = DbiCloseCursor(&hCur);
  443.     ChkRslt(rslt, "CloseCursor");
  444.  
  445.     return rslt;
  446. }
  447.  
  448. //=====================================================================
  449. //  Function:
  450. //          AddRecord(hCur, pszName, lEmpNum, lDeptNum, lBuildNum,
  451. //                    pszSSNum, pszCube);
  452. //
  453. //  Input:  hCur        - Pointer to the cursor handle
  454. //          pszName     - Name
  455. //          lEmpNum     - Employee number
  456. //          lDeptNum    - Dept number
  457. //          lBuildNum   - Building number
  458. //          pszSSNum    - SS number
  459. //          pszCube     - Cube number
  460. //
  461. //  Return: Result of adding the record to the table
  462. //
  463. //  Description:
  464. //          This function will add a record to the given table.
  465. //=====================================================================
  466. DBIResult
  467. AddRecord (hDBICur hCur, pCHAR pszName, INT16 lEmpNum, INT16 lDeptNum,
  468.            INT16 lBuildNum, pCHAR pszSSNum, pCHAR pszCube)
  469. {
  470.     DBIResult   rslt;           // Value returned from IDAPI functions
  471.     CURProps    TblProps;       // Table properties
  472.     pBYTE       pRecBuf;        // Record buffer
  473.  
  474.     // Allocate a record buffer.
  475.     rslt = DbiGetCursorProps(hCur, &TblProps);
  476.     ChkRslt(rslt, "GetCursorProps");
  477.  
  478.     pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE));
  479.     if (pRecBuf == NULL)
  480.     {
  481.         return DBIERR_NOMEMORY;
  482.     }
  483.  
  484.     // Initialize record buffer.
  485.     rslt = DbiInitRecord(hCur, pRecBuf);
  486.     ChkRslt(rslt, "InitRecord");
  487.  
  488.     // First name.
  489.     rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) pszName);
  490.     ChkRslt(rslt, "PutField");
  491.  
  492.     // Employee number.
  493.     rslt = DbiPutField(hCur, 2, pRecBuf, (pBYTE) &lEmpNum);
  494.     ChkRslt(rslt, "PutField");
  495.  
  496.     // Department number.
  497.     rslt = DbiPutField(hCur, 3, pRecBuf, (pBYTE) &lDeptNum);
  498.     ChkRslt(rslt, "PutField");
  499.  
  500.     // Building number. If NULL, allow the default value to be used.
  501.     if (lBuildNum != NULL)
  502.     {
  503.         rslt = DbiPutField(hCur, 4, pRecBuf, (pBYTE) &lBuildNum);
  504.         ChkRslt(rslt, "PutField");
  505.     }
  506.  
  507.     // SS number.
  508.     rslt = DbiPutField(hCur, 5, pRecBuf, (pBYTE) pszSSNum);
  509.     ChkRslt(rslt, "PutField");
  510.  
  511.     // Place of birth.
  512.     rslt = DbiPutField(hCur, 6, pRecBuf, (pBYTE) pszCube);
  513.     ChkRslt(rslt, "PutField");
  514.  
  515.     // Write the record to disk.
  516.     rslt = DbiInsertRecord(hCur, dbiNOLOCK, pRecBuf);
  517.     ChkRslt(rslt, "InsertRecord");
  518.  
  519.     free(pRecBuf);
  520.  
  521.     return rslt;
  522. }
  523.  
  524. //=====================================================================
  525. //  Function:
  526. //          AddLKRecord(hCur, pszCube);
  527. //
  528. //  Input:  hCur    - Pointer to the cursor handle
  529. //          pszCube - Cube name
  530. //
  531. //  Return: Result of adding the record to the table
  532. //
  533. //  Description:
  534. //          This function will add a record to the given table.
  535. //=====================================================================
  536. DBIResult
  537. AddLKRecord (hDBICur hCur, pCHAR pszCube)
  538. {
  539.     DBIResult   rslt;           // Value returned from IDAPI functions
  540.     CURProps    TblProps;       // Table properties
  541.     pBYTE       pRecBuf;        // Record buffer
  542.  
  543.     //  Allocate a record buffer.
  544.     rslt = DbiGetCursorProps(hCur, &TblProps);
  545.     ChkRslt(rslt, "GetCursorProps");
  546.  
  547.     pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE));
  548.     if (pRecBuf == NULL)
  549.     {
  550.         return DBIERR_NOMEMORY;
  551.     }
  552.  
  553.     // Initialize the record buffer.
  554.     rslt = DbiInitRecord(hCur, pRecBuf);
  555.     ChkRslt(rslt, "InitRecord");
  556.  
  557.     // Cube number.
  558.     rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) pszCube);
  559.     ChkRslt(rslt, "PutField");
  560.  
  561.     // Write the record to disk..
  562.     rslt = DbiInsertRecord(hCur, dbiNOLOCK, pRecBuf);
  563.     ChkRslt(rslt, "InsertRecord");
  564.  
  565.     free(pRecBuf);
  566.  
  567.     return rslt;
  568. }
  569.  
  570. //=====================================================================
  571. //  Function:
  572. //          FindRecord(pszString, hCur);
  573. //
  574. //  Input:  pszString   - String to find in the first field
  575. //          hCur        - Cursor handle
  576. //
  577. //  Return: Result of the search
  578. //
  579. //  Description:
  580. //          This function will search the given table for the string
  581. //          passed to it in the first parameter.  It will place this
  582. //          string into the first field of the record buffer and search
  583. //          for the string using the record buffer.
  584. //=====================================================================
  585. DBIResult
  586. FindRecord (pCHAR pszString, hDBICur hCur)
  587. {
  588.     CURProps    TblProps;       // Table properties
  589.     pBYTE       pBuf = NULL;    // Pointer to the record buffer
  590.     DBIResult   rslt;           // Return value from IDAPI functions
  591.  
  592.     // Create the key buffer.  The size comes from the property iRecBufSize.
  593.     rslt = DbiGetCursorProps(hCur,&TblProps);
  594.     ChkRslt(rslt, "GetCursorProps");
  595.  
  596.     pBuf = (pBYTE) malloc(TblProps.iRecBufSize);
  597.     if (pBuf == NULL)
  598.     {
  599.         Screen("    Error - Out of memory");
  600.         return  DBIERR_NOMEMORY;
  601.     }
  602.  
  603.     // Search the "First Name" field for the pszString value.
  604.     rslt = DbiPutField(hCur, 1, pBuf, (pBYTE) pszString);
  605.     ChkRslt(rslt, "PutField");
  606.  
  607.     rslt = DbiSetToKey(hCur, keySEARCHEQ, FALSE, 0, 0, pBuf);
  608.     ChkRslt(rslt, "SetToKey");
  609.  
  610.     free(pBuf);
  611.  
  612.     return rslt;
  613. }
  614.  
  615. //=====================================================================
  616. //  Function:
  617. //          FormatPic(pszDest, pszPicture, pszData);
  618. //
  619. //  Input:  pszDest     - Pointer to buffer that will receive the formatted
  620. //                        string
  621. //          pszPicture  - Pointer to buffer that holds the picture                        the data.
  622. //          pszData     - Pointer to buffer that holds the data to be
  623. //                        converted
  624. //
  625. //  Return: A string in pszDest that matches the picture
  626. //
  627. //  Description:
  628. //          This function only works for pictures that have a '#' symbol
  629. //          in them.  This function can be expanded to work with all of
  630. //          the pictures that IDAPI provides.  IDAPI does not actually
  631. //          format the string itself.  This function expects that the
  632. //          pszDest variable will be large enough to hold the string after
  633. //          conversion.  Therefore, the length of the pszDest variable must
  634. //          be the length of the picture plus 1 for the NULL terminating
  635. //          character.
  636. //=====================================================================
  637. void
  638. FormatPic (pCHAR pszDest, pCHAR pszPicture, pCHAR pszData)
  639. {
  640.     UINT16  iDest = 0;
  641.     UINT16  iPic  = 0;
  642.     UINT16  iData = 0;
  643.  
  644.     // Loop through the whole picture string and convert the data string to
  645.     //   conform to it.
  646.     while (pszPicture[iPic] != NULL)
  647.     {
  648.         // If the character is a number put the number from the pszData string
  649.         //   into the StrDest string.
  650.         if (pszPicture[iPic] == '#')
  651.         {
  652.             // Clean up the string one character at a time.
  653.             pszDest[iDest] = pszData[iData];
  654.             iDest++;
  655.             iPic++;
  656.             iData++;
  657.         }
  658.  
  659.         // Otherwise the character is a constant to be placed within
  660.         //   the string.
  661.         else
  662.         {
  663.             // Clean up the string one character at a time.
  664.             pszDest[iDest] = pszPicture[iPic];
  665.             iDest++;
  666.             iPic++;
  667.         }
  668.     }
  669.     pszDest[iDest] = 0;
  670. }
  671.