ul_db_tran.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /* sp-ul_db module
  2. *
  3. * Copyright (C) 2007 1&1 Internet AG
  4. *
  5. * This file is part of Kamailio, a free SIP server.
  6. *
  7. * Kamailio is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version
  11. *
  12. * Kamailio is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "ul_db_tran.h"
  22. #include "ul_db.h"
  23. #include "p_usrloc_mod.h"
  24. static str autocommit_off = str_init("SET AUTOCOMMIT=0");
  25. static str start_transaction = str_init("START TRANSACTION");
  26. static str commit = str_init("COMMIT");
  27. static str autocommit_on = str_init("SET AUTOCOMMIT=1");
  28. static str rollback = str_init("ROLLBACK");
  29. static int submit_tran_start(db_func_t * dbf, db1_con_t * dbh);
  30. static int submit_tran_commit(db_func_t * dbf, db1_con_t * dbh);
  31. static int submit_tran_rollback(db_func_t * dbf, db1_con_t * dbh);
  32. int ul_db_tran_start(ul_db_handle_t * handle, int working[]) {
  33. int i;
  34. int errors = 0;
  35. int w = 0;
  36. if(!handle || !working) {
  37. LM_ERR("NULL pointer in parameter.\n");
  38. return -1;
  39. }
  40. for(i=0; i<DB_NUM; i++) {
  41. if(handle->db[i].status == DB_ON) {
  42. if(submit_tran_start(&handle->db[i].dbf, handle->db[i].dbh) < 0) {
  43. LM_ERR("error while starting "
  44. "transaction on id %i, db %i.\n", handle->id, handle->db[i].no);
  45. if(db_handle_error(handle, handle->db[i].no) < 0) {
  46. LM_ERR("error during handling error "
  47. "on id %i on db %i, trying again.\n", handle->id, handle->db[i].no);
  48. errors++;
  49. } else {
  50. if(submit_tran_start(&handle->db[i].dbf, handle->db[i].dbh) < 0) {
  51. LM_ERR("error while starting "
  52. "transaction on id %i, db %i.\n", handle->id, handle->db[i].no);
  53. errors++;
  54. }
  55. }
  56. } else {
  57. working[i] = 1;
  58. w++;
  59. }
  60. }
  61. }
  62. if((errors > 0) || (w < handle->working)) {
  63. return -1;
  64. }
  65. return 0;
  66. }
  67. int ul_db_tran_commit(ul_db_handle_t * handle, int working[]) {
  68. int i;
  69. int errors = 0;
  70. int w = 0;
  71. if(!handle || !working) {
  72. LM_ERR("NULL pointer in parameter.\n");
  73. return -1;
  74. }
  75. for(i=0; i<DB_NUM; i++) {
  76. if((handle->db[i].status == DB_ON) && (working[i])) {
  77. if(submit_tran_commit(&handle->db[i].dbf, handle->db[i].dbh) < 0) {
  78. LM_ERR("error while committing "
  79. "transaction on id %i, db %i.\n", handle->id, handle->db[i].no);
  80. if(db_handle_error(handle, handle->db[i].no) < 0) {
  81. LM_ERR("error during handling error "
  82. "on id %i on db %i, trying again.\n", handle->id, handle->db[i].no);
  83. }
  84. errors++;
  85. } else {
  86. w++;
  87. }
  88. }
  89. }
  90. if((errors > 0) || (w < get_working_sum(working, DB_NUM))) {
  91. return -1;
  92. }
  93. return 0;
  94. }
  95. int ul_db_tran_rollback(ul_db_handle_t * handle, int working[]) {
  96. int i;
  97. int errors = 0;
  98. int w = 0;
  99. if(!handle || !working) {
  100. LM_ERR("NULL pointer in parameter.\n");
  101. return -1;
  102. }
  103. for(i=0; i<DB_NUM; i++) {
  104. if((handle->db[i].status == DB_ON) && (working[i])) {
  105. if(submit_tran_rollback(&handle->db[i].dbf, handle->db[i].dbh) < 0) {
  106. LM_ERR("error while rolling back "
  107. "transaction on id %i, db %i.\n", handle->id, handle->db[i].no);
  108. errors++;
  109. } else {
  110. w++;
  111. }
  112. }
  113. }
  114. if((errors > 0) || (w < get_working_sum(working, DB_NUM))) {
  115. return -1;
  116. }
  117. return 0;
  118. }
  119. static int submit_tran_start(db_func_t * dbf, db1_con_t * dbh) {
  120. int errors = 0;
  121. str tmp;
  122. if(dbh) {
  123. if(dbf->raw_query(dbh, &autocommit_off, NULL) < 0) {
  124. LM_ERR("error while turning off "
  125. "autocommit.\n");
  126. errors++;
  127. }
  128. tmp.s = isolation_level;
  129. tmp.len = strlen(isolation_level);
  130. if(dbf->raw_query(dbh, &tmp, NULL) < 0) {
  131. LM_ERR("error while setting "
  132. "isolation level.\n");
  133. errors++;
  134. }
  135. if(dbf->raw_query(dbh, &start_transaction, NULL) < 0) {
  136. LM_ERR("error while starting "
  137. "transaction.\n");
  138. errors++;
  139. }
  140. } else {
  141. LM_ERR("no db handle.\n");
  142. return -1;
  143. }
  144. if(errors > 0) {
  145. return -1;
  146. }
  147. return 0;
  148. }
  149. static int submit_tran_commit(db_func_t * dbf, db1_con_t * dbh) {
  150. int errors = 0;
  151. if(dbh) {
  152. if(dbf->raw_query(dbh, &commit, NULL) < 0) {
  153. LM_ERR("error during commit.\n");
  154. errors++;
  155. }
  156. if(dbf->raw_query(dbh, &autocommit_on, NULL) < 0) {
  157. LM_ERR("error while turning "
  158. "on autocommit.\n");
  159. errors++;
  160. }
  161. } else {
  162. LM_ERR("no db handle.\n");
  163. return -1;
  164. }
  165. if(errors > 0) {
  166. return -1;
  167. }
  168. return 0;
  169. }
  170. static int submit_tran_rollback(db_func_t * dbf, db1_con_t * dbh) {
  171. int errors = 0;
  172. if(dbh) {
  173. if(dbf->raw_query(dbh, &rollback, NULL) < 0) {
  174. LM_ERR("error during "
  175. "rollback.\n");
  176. errors++;
  177. }
  178. if(dbf->raw_query(dbh, &autocommit_on, NULL) < 0) {
  179. LM_ERR("error while "
  180. "turning on autocommit.\n");
  181. errors++;
  182. }
  183. } else {
  184. LM_ERR("no db handle.\n");
  185. return -1;
  186. }
  187. if(errors > 0) {
  188. return -1;
  189. }
  190. return 0;
  191. }
  192. int get_working_sum(int working[], int no) {
  193. int i;
  194. int sum = 0;
  195. if(!working) {
  196. return -1;
  197. }
  198. for(i=0; i<no; i++) {
  199. sum += working[i];
  200. }
  201. return sum;
  202. }