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

  1. // BDE - (C) Copyright 1995 by Borland International
  2.  
  3. // updtcrnt.c
  4. #include "snipit.h"
  5.  
  6. static pCHAR szTblName = "UPDTCRNT";
  7.  
  8. // Field Descriptor used in creating a table.
  9. static SNIPFAR FLDDesc fldDesc[] =
  10.                         {
  11.                           { // Field 1 - FRSTNAME
  12.                             1,              // Field Number
  13.                             "FRSTNAME",     // Field Name
  14.                             fldZSTRING,     // Field Type
  15.                             fldUNKNOWN,     // Field Subtype
  16.                             10,             // Field Size ( 1 or 0, except
  17.                                             //     BLOb or CHAR field )
  18.                             0,              // Decimal places ( 0 )
  19.                                             //     computed
  20.                             0,              // Offset in record ( 0 )
  21.                             0,              // Length in Bytes  ( 0 )
  22.                             0,              // For Null Bits    ( 0 )
  23.                             fldvNOCHECKS,   // Validiy checks   ( 0 )
  24.                             fldrREADWRITE   // Rights
  25.                           },
  26.                           { // Field 2 - LASTNAME
  27.                             2, "LASTNAME", fldZSTRING, fldUNKNOWN,
  28.                             12, 0, 0, 0, 0,
  29.                             fldvNOCHECKS, fldrREADWRITE
  30.                           }
  31.                        };
  32.  
  33. // Index Descriptor - describes the index associated with the table.
  34. static IDXDesc IdxDesc =
  35.                     {
  36.                         { "UPDTIDX" },      // Name
  37.                         1,                  // Number
  38.                         { NULL },           // Tag name (dBASE only)
  39.                         { NULL },           // Optional format
  40.                         FALSE,              // Primary?
  41.                         TRUE,               // Unique?
  42.                         FALSE,              // Descending?
  43.                         TRUE,               // Maintained?
  44.                         FALSE,              // SubSet?
  45.                         FALSE,              // Expression index?
  46.                         NULL,               // for QBE only
  47.                         2,                  // Fields in key
  48.                         NULL,               // Length in bytes
  49.                         FALSE,              // Index out of date?
  50.                         0,                  // Key Type of Expression
  51.                         { 2, 1 },           // Array of field numbers
  52.                         { NULL },           // Key expression
  53.                         { NULL },           // Key Condition
  54.                         FALSE,              // Case insensitive
  55.                         0,                  // Block size in bytes
  56.                         0                   // Restructure number
  57.                     };
  58.  
  59. // Function prototypes
  60. static DBIResult CreateSQLTable(hDBIDb hDb, pCHAR pszTblName);
  61. static DBIResult AddRecord(hDBICur hCur, pCHAR pFirst, pCHAR pLast);
  62.  
  63. static const UINT16 uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]);
  64.  
  65. //=====================================================================
  66. //  Function:
  67. //          UpdateCurrent();
  68. //
  69. //  Description:
  70. //          This example shows how to set up a cursor on the server for
  71. //          update. This allows for updating the current record.
  72. //
  73. //          Notes:
  74. //
  75. //              This functionality is only supported by the InterBase 4.0
  76. //              server.
  77. //
  78. //              DbiSetToBegin will not modify the current position of the
  79. //              cursor on the server - the cursor needs to be re-set.
  80. //
  81. //              The 'SQLPASSTHRU MODE' in the InterBase alias used for
  82. //              this example needs to be set to 'SHARED AUTOCOMMIT' for
  83. //              this example to work.
  84. //=====================================================================
  85. void
  86. UpdateCurrent (void)
  87. {
  88.     DBIResult       rslt;       // Return value from IDAPI functions
  89.     hDBIDb          hDb;        // Handle to the database
  90.     hDBICur         hCur;       // Handle to the result set
  91.     hDBICur         hMCur;      // Handle to the table on the server
  92.     hDBIStmt        hStmt;      // Handle to the SQL statement
  93.     hDBIXact        hTran = 0;  // Transaction Handle
  94.     CHAR            szQuery[100] = { // The text of the SQL statement
  95.                 "SELECT *"
  96.                 " FROM UPDTCRNT"
  97.                 " FOR UPDATE OF FRSTNAME"
  98.                                   };
  99.     UINT16          uLength;         // Length of returned property
  100.     CURProps        TblProps;        // Used to determine the size of the
  101.                                      //   Record buffer.
  102.     pBYTE           pRecBuf = NULL;  // Pointer to the record buffer
  103.     BOOL            bBlank;          // Determine if the field is blank
  104.     BYTE            szFirst[20];     // Variable to store the current first name
  105.     BYTE            szNewFirst[]="Bob";      // Name to change to
  106.     CHAR            szDbType[DBIMAXNAMELEN]; // Type of the connection
  107.     CHAR            szCursorName[] = "MyCursor";
  108.  
  109.     Screen("*** Live Answer Table Example ***\r\n");
  110.  
  111.     BREAK_IN_DEBUGGER();
  112.  
  113.     Screen("    Initializing IDAPI...");
  114.     if (InitAndConnect2(&hDb) != DBIERR_NONE)
  115.     {
  116.         Screen("\r\n*** End of Example ***");
  117.         return;
  118.     }
  119.  
  120.     rslt = DbiGetProp(hDb, dbDATABASETYPE, szDbType, sizeof(DBINAME),
  121.                       &uLength);
  122.     ChkRslt(rslt, "GetProp");
  123.  
  124.     // Make certain that the server supports this opperation.
  125.     if (strcmp(szDbType, "INTRBASE"))
  126.     {
  127.         Screen("        Error - 'UPDATE ... WHERE CURRENT OF' is currently"
  128.                " only supported for InterBase v4.0.");
  129.         CloseDbAndExit(&hDb);
  130.         Screen("\r\n*** End of Example ***");
  131.         return;
  132.     }
  133.  
  134.     // Create the table
  135.     if (CreateSQLTable(hDb, szTblName)
  136.         != DBIERR_NONE)
  137.     {
  138.         CloseDbAndExit(&hDb);
  139.         Screen("\r\n*** End of Example ***");
  140.         return;
  141.     }
  142.  
  143.     // Start a transaction to handle the update to the table
  144.     rslt = DbiBeginTran(hDb, xilREADCOMMITTED, &hTran);
  145.     if (ChkRslt(rslt, "BeginTran"))
  146.     {
  147.         CloseDbAndExit(&hDb);
  148.         Screen("\r\n*** End of Example ***");
  149.         return;
  150.     }
  151.  
  152.     Screen("    Perform the following SQL statement on the table:\r\n");
  153.     Screen(szQuery);
  154.  
  155.     // Prepare the query as a non-live query.
  156.     Screen("\r\n    Prepare the SQL statement...");
  157.     rslt = DbiQPrepareExt(hDb, qrylangSQL, szQuery,  qprepNONE, &hStmt);
  158.     if (ChkRslt(rslt, "QPrepareExt") != DBIERR_NONE)
  159.     {
  160.         rslt = DbiEndTran(hDb, hTran, xendABORT);
  161.         ChkRslt(rslt, "EndTran");
  162.         rslt = DbiDeleteTable(hDb, szTblName, NULL);
  163.         ChkRslt(rslt, "DeleteTable");
  164.         CloseDbAndExit(&hDb);
  165.         Screen("\r\n*** End of Example ***");
  166.         return;
  167.     }
  168.  
  169.     Screen("    Set the name of the cursor...");
  170.     rslt = DbiSetProp((hDBIObj)hStmt, stmtCURSORNAME, (UINT32)szCursorName);
  171.     ChkRslt(rslt, "SetProp");
  172.  
  173.     Screen("    Force the use of a Uni-Directional cursor...");
  174.     rslt = DbiSetProp((hDBIObj)hStmt, stmtUNIDIRECTIONAL, TRUE);
  175.     ChkRslt(rslt, "SetProp");
  176.  
  177.     Screen("    Execute the SQL statement...");
  178.     rslt = DbiQExec(hStmt, &hCur);
  179.     if (ChkRslt(rslt, "QExec") != DBIERR_NONE)
  180.     {
  181.         rslt = DbiEndTran(hDb, hTran, xendABORT);
  182.         ChkRslt(rslt, "EndTran");
  183.         rslt = DbiDeleteTable(hDb, szTblName, NULL);
  184.         ChkRslt(rslt, "DeleteTable");
  185.         CloseDbAndExit(&hDb);
  186.         Screen("\r\n*** End of Example ***");
  187.         return;
  188.     }
  189.  
  190.     // Check for a valid cursor.
  191.     if (hCur)
  192.     {
  193.         rslt = DbiOpenTable(hDb, szTblName, NULL, "UPDTIDX", NULL, 0,
  194.                             dbiREADONLY, dbiOPENSHARED, xltFIELD, TRUE, NULL,
  195.                             &hMCur);
  196.         ChkRslt(rslt, "OpenTable");
  197.  
  198.         Screen("    Display the table using the UPDTIDX index...");
  199.         DisplayTable(hMCur, 0);
  200.  
  201.         rslt = DbiGetCursorProps(hCur, &TblProps);
  202.         ChkRslt(rslt, "GetCursorProps");
  203.  
  204.         pRecBuf = (pBYTE)malloc(TblProps.iRecBufSize * sizeof(BYTE));
  205.  
  206.         Screen("\r\n    Get the first record in the result set (set the current"
  207.                " position in the cursor...)");
  208.         rslt = DbiGetNextRecord(hCur, dbiNOLOCK, pRecBuf, NULL);
  209.         ChkRslt(rslt, "GetNextRecord");
  210.  
  211.         rslt = DbiGetField(hCur, 1, pRecBuf, szFirst, &bBlank);
  212.         ChkRslt(rslt, "GetField");
  213.  
  214.         sprintf(szQuery, "UPDATE UPDTCRNT SET FRSTNAME = '%s' WHERE CURRENT OF"
  215.                 " %s", szNewFirst, szCursorName);
  216.  
  217.         Screen("\r\n    Modifying a record in the query result:"
  218.                "\r\n      change the FRSTNAME field from %s to %s....",
  219.                szFirst, szNewFirst);
  220.  
  221.         // Can also use DbiQPrepareExt/DbiQExec/DbiQFree
  222.         rslt = DbiQExecDirect(hDb, qrylangSQL, szQuery, NULL);
  223.         ChkRslt(rslt, "QExecDirect");
  224.  
  225.         Screen("\r\n    Close the cursor...");
  226.         rslt = DbiCloseCursor(&hCur);
  227.         ChkRslt(rslt, "CloseCursor");
  228.  
  229.         Screen("    Commit the changes...");
  230.         rslt = DbiEndTran(hDb, hTran, xendCOMMIT);
  231.         ChkRslt(rslt, "EndTran");
  232.  
  233.         // Refresh the cursor
  234.         Screen("\r\n    Resynch the cursor to the table...");
  235.         rslt = DbiForceReread(hMCur);
  236.         ChkRslt(rslt, "ForceReread");
  237.  
  238.         rslt = DbiSetToBegin(hMCur);
  239.         ChkRslt(rslt, "SetToBegin");
  240.  
  241.         Screen("\r\n    Again, display the table opened using DbiOpenTable");
  242.         Screen("      (Notice that the table reflects the changes made"
  243.                " to the query)");
  244.         DisplayTable(hMCur, 0);
  245.  
  246.         rslt = DbiCloseCursor(&hMCur);
  247.         ChkRslt(rslt, "CloseCursor");
  248.     }
  249.     else
  250.     {
  251.         Screen("        Could not get cursor to the answer set.");
  252.     }
  253.  
  254.     Screen("\r\n    Release memory allocated for the query...");
  255.     rslt = DbiQFree(&hStmt);
  256.     ChkRslt(rslt, "QryFree");
  257.  
  258.     rslt = DbiDeleteTable(hDb, szTblName, NULL);
  259.     ChkRslt(rslt, "DeleteTable");
  260.  
  261.     if (pRecBuf)
  262.     {
  263.         free(pRecBuf);
  264.     }
  265.  
  266.     Screen("    Close the database and exit IDAPI...");
  267.     CloseDbAndExit(&hDb);
  268.  
  269.     Screen("\r\n*** End of Example ***");
  270. }
  271.  
  272. //=====================================================================
  273. //  Function:
  274. //          CreateSQLTable(hDb, pszTblName);
  275. //
  276. //  Input:  phDb        - Pointer to the database handle.
  277. //          pszTblName  - The name of the table to create.
  278. //
  279. //  Return: Result returned by IDAPI.
  280. //
  281. //  Description:
  282. //          This function will create a table and add records to that
  283. //          table.
  284. //=====================================================================
  285. DBIResult
  286. CreateSQLTable (hDBIDb hDb, pCHAR pszTblName)
  287. {
  288.     DBIResult   rslt;           // Value returned from IDAPI functions
  289.     CRTblDesc   crTblDesc;      // Table Descriptor
  290.     hDBICur     hCur;           // Cursor used for adding records
  291.  
  292.     // Initialize the Table Create Descriptor.
  293.     memset(&crTblDesc, 0, sizeof(CRTblDesc));
  294.  
  295.     strcpy(crTblDesc.szTblName, pszTblName);
  296.     crTblDesc.iFldCount     = uNumFields;
  297.     crTblDesc.pfldDesc      = fldDesc;
  298.     crTblDesc.iIdxCount     = 1;
  299.     crTblDesc.pidxDesc      = &IdxDesc;
  300.  
  301.     Screen("    Creating the table...");
  302.     rslt = DbiCreateTable(hDb, TRUE, &crTblDesc);
  303.     if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
  304.     {
  305.         return rslt;
  306.     }
  307.  
  308.     rslt = DbiOpenTable(hDb, pszTblName, NULL,
  309.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENEXCL,
  310.                         xltFIELD, TRUE, NULL, &hCur);
  311.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  312.     {
  313.         rslt = DbiDeleteTable(hDb, pszTblName, NULL);
  314.         ChkRslt(rslt, "DeleteTable");
  315.         return rslt;
  316.     }
  317.  
  318.     // Add records to the table.
  319.     Screen("    Adding records to the table...");
  320.     rslt = AddRecord(hCur, "Tom", "Smith");
  321.     rslt = AddRecord(hCur, "Jim", "Jones");
  322.     rslt = AddRecord(hCur, "Larry", "Peterson");
  323.     rslt = AddRecord(hCur, "Jane", "Jackson");
  324.     rslt = AddRecord(hCur, "Mary", "Wong");
  325.  
  326.     rslt = DbiCloseCursor(&hCur);
  327.     ChkRslt(rslt, "CloseTable");
  328.  
  329.     return rslt;
  330. }
  331.  
  332. //=====================================================================
  333. //  Function:
  334. //          AddRecord (hDBICur hCur, pCHAR pFirst, pCHAR pLast)
  335. //
  336. //  Input:  hCur    - The table handle
  337. //          pFirst  - First Name
  338. //          pLast   - Last Name
  339. //
  340. //  Return: Result of adding the record to the table
  341. //
  342. //  Description:
  343. //          Insert a record into the table.
  344. //=====================================================================
  345. DBIResult
  346. AddRecord (hDBICur hCur, pCHAR pFirst, pCHAR pLast)
  347. {
  348.     DBIResult   rslt;       // Return value from IDAPI functions
  349.     pBYTE       pRecBuf;    // Record buffer
  350.     CURProps    TblProps;   // Table properties
  351.  
  352.     // Allocate a record buffer.
  353.     rslt = DbiGetCursorProps(hCur, &TblProps);
  354.     ChkRslt(rslt, "GetCursorProps");
  355.  
  356.     pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE));
  357.     if (pRecBuf == NULL)
  358.     {
  359.         Screen("    Error - Out of memory");
  360.         return DBIERR_NOMEMORY;
  361.     }
  362.  
  363.     // Clear the record buffer, then add the data.
  364.     rslt = DbiInitRecord(hCur, pRecBuf);
  365.     ChkRslt(rslt, "InitRecord");
  366.  
  367.     rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) pFirst);
  368.     ChkRslt(rslt, "PutField");
  369.  
  370.     rslt = DbiPutField(hCur, 2, pRecBuf, (pBYTE) pLast);
  371.     ChkRslt(rslt, "PutField");
  372.  
  373.     rslt = DbiInsertRecord(hCur, dbiNOLOCK, pRecBuf);
  374.     ChkRslt(rslt, "InsertRecord");
  375.  
  376.     free(pRecBuf);
  377.  
  378.     return rslt;
  379. }
  380.  
  381.  
  382.