home *** CD-ROM | disk | FTP | other *** search
/ PC World 1999 May / PCWorld_1999-05_cd.bin / software / Vyzkuste / inprise / INTRBASE_55 / EXAMPLES / API / API13.C < prev    next >
C/C++ Source or Header  |  1998-10-18  |  5KB  |  182 lines

  1. /*
  2.  *    Program type:  API Interface
  3.  *
  4.  *    Description:
  5.  *        This program performs a multi-database transaction
  6.  *        with a two-phase commit.  A 'currency' field is updated
  7.  *        in database 1 for table country, and corresponding
  8.  *        'from_currency' or 'to_currency' fields are updated in
  9.  *        database 2 for table cross_rate.  The transaction is
  10.  *        committed only if all instances of the string are
  11.  *        changed successfully in both databases.
  12.  */
  13.  
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <ibase.h>
  17. #include <stdio.h>
  18. #include "example.h"
  19.  
  20. #define BUFLEN        512
  21. #define CURRENLEN    10
  22.  
  23. char    *sel_str1 =
  24.     "SELECT currency FROM country WHERE country = 'Canada'";
  25.  
  26.  
  27. int main (ARG(int, argc), ARG(char **, argv))
  28. ARGLIST(int argc)
  29. ARGLIST(char **argv)
  30. {
  31.     char                *country = "Canada";        /* passed as a parameter */
  32.     char                *new_name = "CdnDollar";    /* passed as a parameter */
  33.     char                orig_name[CURRENLEN + 1];
  34.     char                buf[BUFLEN + 1];
  35.     isc_db_handle       db1 = NULL,        /* handle for database 1 */
  36.                         db2 = NULL;        /* handle for database 2 */
  37.     isc_tr_handle       trans1 = NULL;     /* transaction handle */
  38.     long                status[20];
  39.     XSQLDA ISC_FAR *    sel_sqlda;
  40.     isc_stmt_handle     stmt = NULL;
  41.     long                stat1, stat2, stat3;
  42.     char                empdb[128], empdb2[128];
  43.  
  44.     if (argc > 1)
  45.         strcpy(empdb, argv[1]);
  46.     else
  47.         strcpy(empdb, "employee.gdb");
  48.     if (argc > 2)
  49.         strcpy(empdb2, argv[2]);
  50.     else
  51.         strcpy(empdb2, "employe2.gdb");
  52.  
  53.  
  54.     /* Open database 1. */
  55.     printf("Attaching to database %s\n", empdb);
  56.     if (isc_attach_database(status, 0, empdb, &db1, 0, NULL))
  57.     {
  58.         ERREXIT(status, 1)
  59.     }
  60.  
  61.     /* Open database 2. */
  62.     printf ("Attaching to database %s\n", empdb2);
  63.     if (isc_attach_database(status, 0, empdb2, &db2, 0, NULL))
  64.     {
  65.         ERREXIT(status, 1)
  66.     }
  67.  
  68.     /* Start a two-database transaction. */
  69.     if (isc_start_transaction(status, &trans1, 2, &db1, 0, NULL, &db2, 0, NULL))
  70.     {
  71.         ERREXIT(status, 1)
  72.     }          
  73.  
  74.     /*
  75.      *  Get the string, which is to be globally changed.
  76.      */
  77.  
  78.     sprintf(buf, "SELECT currency FROM country WHERE country = '%s'", country);
  79.  
  80.     sel_sqlda = (XSQLDA ISC_FAR *) malloc(XSQLDA_LENGTH(1));
  81.     sel_sqlda->sqln = 1;
  82.     sel_sqlda->version = 1;
  83.  
  84.     if (isc_dsql_allocate_statement(status, &db1, &stmt))
  85.     {
  86.         ERREXIT(status, 1)
  87.     }
  88.     if (isc_dsql_prepare(status, &trans1, &stmt, 0, sel_str1, 1, sel_sqlda))
  89.     {
  90.         ERREXIT(status, 1)
  91.     }
  92.  
  93.     sel_sqlda->sqlvar[0].sqldata = orig_name;
  94.     sel_sqlda->sqlvar[0].sqltype = SQL_TEXT;
  95.     sel_sqlda->sqlvar[0].sqllen = CURRENLEN;
  96.  
  97.     if (isc_dsql_execute(status, &trans1, &stmt, 1, NULL))
  98.     {
  99.         ERREXIT(status, 1)
  100.     }
  101.     if (isc_dsql_fetch(status, &stmt, 1, sel_sqlda))
  102.     {
  103.         ERREXIT(status, 1)
  104.     }
  105.  
  106.     orig_name[CURRENLEN] = '\0';
  107.     printf("Modifying currency string:  %s\n", orig_name);
  108.                    
  109.     /*
  110.      *  Change the string in database 1.
  111.      */
  112.  
  113.     sprintf(buf, "UPDATE country SET currency = '%s' WHERE country = 'Canada'",
  114.             new_name);
  115.  
  116.     stat1 = 0L;
  117.     if (isc_dsql_execute_immediate(status, &db1, &trans1, 0, buf, 1, NULL))
  118.     {
  119.         isc_print_status(status);
  120.         stat1 = isc_sqlcode(status);
  121.     }       
  122.  
  123.     /*
  124.      *  Change all corresponding occurences of the string in database 2.
  125.      */
  126.  
  127.     sprintf(buf, "UPDATE cross_rate SET from_currency = '%s' WHERE \
  128.             from_currency = '%s'", new_name, orig_name);
  129.  
  130.     stat2 = 0L;
  131.     if (isc_dsql_execute_immediate(status, &db2, &trans1, 0, buf, 1, NULL))
  132.     {
  133.         isc_print_status(status);
  134.         stat2 = isc_sqlcode(status);
  135.     }
  136.     
  137.     sprintf(buf, "UPDATE cross_rate SET to_currency = '%s' WHERE \
  138.             to_currency = '%s'", new_name, orig_name);
  139.  
  140.     stat3 = 0L;
  141.     if (isc_dsql_execute_immediate(status, &db2, &trans1, 0, buf, 1, NULL))
  142.     {
  143.         isc_print_status(status);
  144.         stat3 = isc_sqlcode(status);
  145.     }
  146.  
  147.     if (isc_dsql_free_statement(status, &stmt, DSQL_close))
  148.         isc_print_status(status);
  149.  
  150.     /*
  151.      *    If all statements executed successfully, commit the transaction.
  152.      *    Otherwise, undo all work.
  153.      */
  154.     if (!stat1 && !stat2 && !stat3)
  155.     {
  156.         if (isc_commit_transaction (status, &trans1))
  157.             isc_print_status(status);
  158.         printf("Changes committed.\n");
  159.     }
  160.     else
  161.     {
  162.         printf("update1:  %d\n", stat1);
  163.         printf("update2:  %d\n", stat2);
  164.         printf("update3:  %d\n", stat3);
  165.         if (isc_rollback_transaction(status, &trans1))
  166.             isc_print_status(status);
  167.         printf("Changes undone.\n");
  168.     }
  169.  
  170.     /* Close database 1. */
  171.     if (isc_detach_database(status, &db1))
  172.         isc_print_status(status);
  173.  
  174.     /* Close database 2. */
  175.     if (isc_detach_database(status, &db2))
  176.         isc_print_status(status);
  177.     
  178.     free(sel_sqlda);
  179.  
  180.     return 0;
  181. }
  182.