api13.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. * The contents of this file are subject to the Interbase Public
  13. * License Version 1.0 (the "License"); you may not use this file
  14. * except in compliance with the License. You may obtain a copy
  15. * of the License at http://www.Inprise.com/IPL.html
  16. *
  17. * Software distributed under the License is distributed on an
  18. * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
  19. * or implied. See the License for the specific language governing
  20. * rights and limitations under the License.
  21. *
  22. * The Original Code was created by Inprise Corporation
  23. * and its predecessors. Portions created by Inprise Corporation are
  24. * Copyright (C) Inprise Corporation.
  25. *
  26. * All Rights Reserved.
  27. * Contributor(s): ______________________________________.
  28. */
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <ibase.h>
  32. #include <stdio.h>
  33. #include "example.h"
  34. #define BUFLEN 512
  35. #define CURRENLEN 10
  36. char *sel_str1 =
  37. "SELECT currency FROM country WHERE country = 'Canada'";
  38. int main (int argc, char** argv)
  39. {
  40. char *country = "Canada"; /* passed as a parameter */
  41. char *new_name = "CdnDollar"; /* passed as a parameter */
  42. char orig_name[CURRENLEN + 1];
  43. char buf[BUFLEN + 1];
  44. isc_db_handle db1 = NULL, /* handle for database 1 */
  45. db2 = NULL; /* handle for database 2 */
  46. isc_tr_handle trans1 = NULL; /* transaction handle */
  47. ISC_STATUS_ARRAY status;
  48. XSQLDA * sel_sqlda;
  49. isc_stmt_handle stmt = NULL;
  50. long stat1, stat2, stat3;
  51. char empdb[128], empdb2[128];
  52. if (argc > 1)
  53. strcpy(empdb, argv[1]);
  54. else
  55. strcpy(empdb, "employee.fdb");
  56. if (argc > 2)
  57. strcpy(empdb2, argv[2]);
  58. else
  59. strcpy(empdb2, "employe2.fdb");
  60. /* Open database 1. */
  61. printf("Attaching to database %s\n", empdb);
  62. if (isc_attach_database(status, 0, empdb, &db1, 0, NULL))
  63. {
  64. ERREXIT(status, 1)
  65. }
  66. /* Open database 2. */
  67. printf ("Attaching to database %s\n", empdb2);
  68. if (isc_attach_database(status, 0, empdb2, &db2, 0, NULL))
  69. {
  70. ERREXIT(status, 1)
  71. }
  72. /* Start a two-database transaction. */
  73. if (isc_start_transaction(status, &trans1, 2, &db1, 0, NULL, &db2, 0, NULL))
  74. {
  75. ERREXIT(status, 1)
  76. }
  77. /*
  78. * Get the string, which is to be globally changed.
  79. */
  80. sprintf(buf, "SELECT currency FROM country WHERE country = '%s'", country);
  81. sel_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
  82. sel_sqlda->sqln = 1;
  83. sel_sqlda->version = 1;
  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. sel_sqlda->sqlvar[0].sqldata = orig_name;
  93. sel_sqlda->sqlvar[0].sqltype = SQL_TEXT;
  94. sel_sqlda->sqlvar[0].sqllen = CURRENLEN;
  95. if (isc_dsql_execute(status, &trans1, &stmt, 1, NULL))
  96. {
  97. ERREXIT(status, 1)
  98. }
  99. if (isc_dsql_fetch(status, &stmt, 1, sel_sqlda))
  100. {
  101. ERREXIT(status, 1)
  102. }
  103. orig_name[CURRENLEN] = '\0';
  104. printf("Modifying currency string: %s\n", orig_name);
  105. /*
  106. * Change the string in database 1.
  107. */
  108. sprintf(buf, "UPDATE country SET currency = '%s' WHERE country = 'Canada'",
  109. new_name);
  110. stat1 = 0L;
  111. if (isc_dsql_execute_immediate(status, &db1, &trans1, 0, buf, 1, NULL))
  112. {
  113. isc_print_status(status);
  114. stat1 = isc_sqlcode(status);
  115. }
  116. /*
  117. * Change all corresponding occurrences of the string in database 2.
  118. */
  119. sprintf(buf, "UPDATE cross_rate SET from_currency = '%s' WHERE \
  120. from_currency = '%s'", new_name, orig_name);
  121. stat2 = 0L;
  122. if (isc_dsql_execute_immediate(status, &db2, &trans1, 0, buf, 1, NULL))
  123. {
  124. isc_print_status(status);
  125. stat2 = isc_sqlcode(status);
  126. }
  127. sprintf(buf, "UPDATE cross_rate SET to_currency = '%s' WHERE \
  128. to_currency = '%s'", new_name, orig_name);
  129. stat3 = 0L;
  130. if (isc_dsql_execute_immediate(status, &db2, &trans1, 0, buf, 1, NULL))
  131. {
  132. isc_print_status(status);
  133. stat3 = isc_sqlcode(status);
  134. }
  135. if (isc_dsql_free_statement(status, &stmt, DSQL_close))
  136. isc_print_status(status);
  137. /*
  138. * If all statements executed successfully, commit the transaction.
  139. * Otherwise, undo all work.
  140. */
  141. if (!stat1 && !stat2 && !stat3)
  142. {
  143. if (isc_commit_transaction (status, &trans1))
  144. isc_print_status(status);
  145. printf("Changes committed.\n");
  146. }
  147. else
  148. {
  149. printf("update1: %d\n", stat1);
  150. printf("update2: %d\n", stat2);
  151. printf("update3: %d\n", stat3);
  152. if (isc_rollback_transaction(status, &trans1))
  153. isc_print_status(status);
  154. printf("Changes undone.\n");
  155. }
  156. /* Close database 1. */
  157. if (isc_detach_database(status, &db1))
  158. isc_print_status(status);
  159. /* Close database 2. */
  160. if (isc_detach_database(status, &db2))
  161. isc_print_status(status);
  162. free(sel_sqlda);
  163. return 0;
  164. }