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

  1. // BDE - (C) Copyright 1995 by Borland International
  2.  
  3. // transact.c
  4. #include "snipit.h"
  5.  
  6. static pCHAR SQLTblName = "SQLTRAN";
  7.  
  8. // Field descriptor used in creating a table
  9. static FLDDesc FldDesc =
  10.                           { // Field 1 - First Name
  11.                             1,              // Field number
  12.                             "NAME",         // Field name
  13.                             fldZSTRING,     // Field type
  14.                             fldUNKNOWN,     // Field subtype
  15.                             10,             // Field size ( 1 or 0, except
  16.                                             //     BLOb or CHAR field )
  17.                             0,              // Decimal places ( 0 )
  18.                                             //     computed
  19.                             0,              // Offset in record ( 0 )
  20.                             0,              // Length in bytes  ( 0 )
  21.                             0,              // For Null bits    ( 0 )
  22.                             fldvNOCHECKS,   // Validity checks   ( 0 )
  23.                             fldrREADWRITE   // Rights
  24.                           };
  25.  
  26. // Index descriptor - describes the index associated with the table.
  27. static IDXDesc IdxDesc =
  28.                     {
  29.                         { "BASEIDX" },      // Name
  30.                         1,                  // Number
  31.                         { NULL },           // Tag name (dBASE only)
  32.                         { NULL },           // Optional format
  33.                         FALSE,              // Primary?
  34.                         TRUE,               // Unique?
  35.                         FALSE,              // Descending?
  36.                         TRUE,               // Maintained?
  37.                         FALSE,              // SubSet?
  38.                         FALSE,              // Expression index?
  39.                         NULL,               // for QBE only
  40.                         1,                  // Fields in key
  41.                         NULL,               // Length in bytes
  42.                         FALSE,              // Index out of date?
  43.                         0,                  // Key type of expression
  44.                         { 1 },              // Array of field numbers
  45.                         { NULL },           // Key expression
  46.                         { NULL },           // Key condition
  47.                         FALSE,              // Case insensitive
  48.                         0,                  // Block size in bytes
  49.                         0                   // Restructure number
  50.                     };
  51.  
  52. // Function prototypes
  53. static DBIResult CreateAndOpenSQLTable(hDBIDb hDb, phDBICur phTbl,
  54.                                        pCHAR pTblName, pCHAR pTblType);
  55. static DBIResult AddTranRecord(hDBICur hCur, pCHAR pStr);
  56.  
  57. //=====================================================================
  58. //  Function:
  59. //          SQLTran();
  60. //
  61. //  Description:
  62. //          This example will describe how to begin a transaction,
  63. //          verify that the transaction is still active, and commit
  64. //          (or rollback) the transaction based on its state.
  65. //
  66. //  WARNING: This example requires write access to the SQL server.
  67. //=====================================================================
  68. void
  69. SQLTran (void)
  70. {
  71.     hDBIDb      hDb;        // Handle to the database.
  72.     hDBICur     hCur;       // Handle to the table.
  73.     hDBIXact    hTran;      // Handle to the transaction.
  74.     XInfo       TranInfo;   // Information about the transaction.
  75.     pCHAR       pTblType;   // Buffer to contain the type of the table.
  76.     DBIResult   rslt;       // Return value from IDAPI functions
  77.     eXEnd       TranAct;    // Transaction action to take:  commit or
  78.                             //   rollback. 
  79.     UINT16      uLength;    // Length of property returned from DbiGetProp
  80.  
  81.     Screen("*** SQL Transaction Example ***\r\n");
  82.  
  83.     BREAK_IN_DEBUGGER();
  84.  
  85.     Screen("    Initializing IDAPI...");
  86.     if (InitAndConnect2(&hDb) != DBIERR_NONE)
  87.     {                                         
  88.         Screen("\r\n*** End of Example ***");
  89.         return;
  90.     }
  91.  
  92.     // Get the database type
  93.     pTblType = (pCHAR)malloc((DBIMAXNAMELEN + 1) * sizeof(CHAR));
  94.     if (pTblType == NULL)
  95.     {
  96.         Screen("        Error - Out of memory.");
  97.         CloseDbAndExit(&hDb);
  98.         Screen("\r\n*** End of Example ***");
  99.     }
  100.  
  101.     rslt = DbiGetProp(hDb, dbDATABASETYPE, pTblType, sizeof(DBINAME),
  102.                       &uLength);
  103.     ChkRslt(rslt, "GetProp");
  104.  
  105.     // Verify that the selected database is a remote SQL server: this
  106.     //   example only works with remote SQL databases such as Interbase
  107.     //   and Oracle.
  108.     if (!strcmp(pTblType, "STANDARD"))
  109.     {
  110.         Screen("This example only works on remote SQL"
  111.                " databases.");
  112.         free(pTblType);
  113.         CloseDbAndExit(&hDb);
  114.         Screen("\r\n*** End of Example ***");
  115.         return;
  116.     }
  117.  
  118.     // Create a sample table and insert records.
  119.     if (CreateAndOpenSQLTable(hDb, &hCur, SQLTblName, pTblType)
  120.         != DBIERR_NONE)
  121.     {
  122.         free(pTblType);
  123.         CloseDbAndExit(&hDb);
  124.         Screen("\r\n*** End of Example ***");
  125.         return;
  126.     }
  127.  
  128.     Screen("\r\n    The table before the transaction...");
  129.  
  130.     rslt = DbiSetToBegin(hCur);
  131.     ChkRslt(rslt, "SetToBegin");
  132.     DisplayTable(hCur, 0);
  133.  
  134.     // Start a transaction with a READCOMMIT isolation level
  135.     rslt = DbiBeginTran(hDb, xilREADCOMMITTED, &hTran);
  136.     if (ChkRslt(rslt, "BeginTran") == DBIERR_NONE)
  137.     {
  138.         // Set the default to commit the transaction.  Rollback only if
  139.         //   an error occurs.
  140.         TranAct = xendCOMMIT;
  141.  
  142.         // Verify the state of the transaction
  143.         rslt = DbiGetTranInfo(hDb, hTran, &TranInfo);
  144.         ChkRslt(rslt, "GetTranInfo");
  145.  
  146.         if (TranInfo.exState != xsACTIVE)
  147.         {
  148.             Screen("    Error - Transaction is not active");
  149.         }
  150.         else
  151.         {
  152.             // Transaction is usable.  Add some data!
  153.             Screen("\r\n    Inserting two new records...");
  154.             rslt = AddTranRecord(hCur, "Angela");
  155.             if (rslt != DBIERR_NONE)
  156.             {
  157.                 // Rollback the transaction if the insert failed
  158.                 TranAct = xendABORT;
  159.             }
  160.             rslt = AddTranRecord(hCur, "Bernice");
  161.             if (rslt != DBIERR_NONE)
  162.             {
  163.                 // Rollback the transaction if the insert failed
  164.                 TranAct = xendABORT;
  165.             }
  166.         }
  167.  
  168.         // End the transaction (committing changes), then reread the
  169.         //   table (updates the cache).
  170.         Screen("    Ending the transaction...");
  171.         rslt = DbiEndTran(hDb, hTran, TranAct);
  172.         ChkRslt(rslt, "EndTran");
  173.  
  174.         // Note: The call to DbiForceReread is only required in 
  175.         //   a multi-user environment when we need to guarantee the
  176.         //   concurrency of data.
  177.         rslt = DbiForceReread(hCur);
  178.         ChkRslt(rslt, "ForceReread");
  179.  
  180.         Screen("\r\n    The table after the transaction...");
  181.         rslt = DbiSetToBegin(hCur);
  182.         ChkRslt(rslt, "SetToBegin");
  183.         DisplayTable(hCur, 0);
  184.     }
  185.  
  186.     rslt = DbiCloseCursor(&hCur);
  187.     ChkRslt(rslt, "CloseCursor");
  188.  
  189.     // Cleanup.
  190.     Screen("\r\n    Delete the table from the server...");
  191.     rslt = DbiDeleteTable(hDb, SQLTblName, pTblType);
  192.     ChkRslt(rslt, "DeleteTable");
  193.  
  194.     Screen("    Close the database and exit IDAPI...");
  195.     CloseDbAndExit(&hDb);
  196.  
  197.     free(pTblType);
  198.  
  199.     Screen("\r\n*** End of Example ***");
  200. }
  201.  
  202. //=====================================================================
  203. //  Function:
  204. //          CreateSQLTable(hDb, phCur, pTblName, pTblType);
  205. //
  206. //  Input:  phDb        - Pointer to the database handle.
  207. //          phCur       - Cursor to the table.
  208. //          pTblName    - The name of the table to create.
  209. //          pTblType    - The type of table.
  210. //
  211. //  Return: Result returned by IDAPI.
  212. //
  213. //  Description:
  214. //          This will try to create a table on the SQL server. It will
  215. //          also insert a few records.
  216. //
  217. //  Note:   This example will not work on local tables.
  218. //=====================================================================
  219. DBIResult
  220. CreateAndOpenSQLTable (hDBIDb hDb, phDBICur phCur, pCHAR pTblName,
  221.                        pCHAR pTblType)
  222. {
  223.     DBIResult   rslt;          // Value returned from IDAPI functions
  224.     CRTblDesc   crTblDsc;      // Table descriptor
  225.  
  226.     // Initialize the create table descriptor
  227.     memset(&crTblDsc, 0, sizeof(CRTblDesc));
  228.     strcpy(crTblDsc.szTblName, pTblName) ;
  229.     strcpy(crTblDsc.szTblType, pTblType) ;
  230.     crTblDsc.iFldCount     = 1;
  231.     crTblDsc.pfldDesc      = &FldDesc ;
  232.     crTblDsc.iIdxCount     = 1;
  233.     crTblDsc.pidxDesc      = &IdxDesc ;
  234.  
  235.     Screen("    Creating the table...");
  236.     rslt = DbiCreateTable(hDb, TRUE, &crTblDsc);
  237.     if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
  238.     {
  239.         return rslt;
  240.     }
  241.  
  242.     rslt = DbiOpenTable(hDb, pTblName, pTblType,
  243.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
  244.                         xltFIELD, FALSE, NULL, phCur);
  245.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  246.     {
  247.         rslt = DbiDeleteTable(hDb, pTblName, pTblType);
  248.         ChkRslt(rslt, "DeleteTable");
  249.         return rslt;
  250.     }
  251.  
  252.     // Add records to the table
  253.     Screen("    Adding records to the table...");
  254.     AddTranRecord(*phCur, "Tom");
  255.     AddTranRecord(*phCur, "Jim");
  256.     rslt = AddTranRecord(*phCur, "Larry");
  257.  
  258.     // The table handle is returned to the calling function in the phCur
  259.     // parameter.
  260.     return rslt;
  261. }
  262.  
  263. //=====================================================================
  264. //  Function:
  265. //          AddTranRecord(hCur, pStr);
  266. //
  267. //  Input:  hCur - The table handle
  268. //          pStr - The data to insert
  269. //
  270. //  Return: Result of adding the record to the table
  271. //
  272. //  Description:
  273. //          Insert a record into the table.
  274. //=====================================================================
  275. DBIResult
  276. AddTranRecord (hDBICur hCur, pCHAR pStr)
  277. {
  278.     DBIResult   rslt;       // Value returned from IDAPI functions.
  279.     pBYTE       pRecBuf;    // Record buffer.
  280.     CURProps    TblProps;   // Table properties.
  281.  
  282.     //  Allocate a record buffer.
  283.     rslt = DbiGetCursorProps(hCur, &TblProps);
  284.     ChkRslt(rslt, "GetCursorProps");
  285.  
  286.     pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE));
  287.     if (pRecBuf == NULL)
  288.     {
  289.         Screen("    Error - Out of memory");
  290.         return DBIERR_NOMEMORY;
  291.     }
  292.  
  293.     // Clear the record buffer, then add the data.
  294.     rslt = DbiInitRecord(hCur, pRecBuf);
  295.     ChkRslt(rslt, "InitRecord");
  296.  
  297.     rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) pStr);
  298.     ChkRslt(rslt, "PutField");
  299.  
  300.     rslt = DbiInsertRecord(hCur, dbiNOLOCK, pRecBuf);
  301.     ChkRslt(rslt, "InsertRecord");
  302.  
  303.     free(pRecBuf);
  304.  
  305.     return rslt;
  306. }
  307.  
  308.