extension_elements.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #include "presentity.h"
  2. #include "extension_elements.h"
  3. #include "pa_mod.h"
  4. #include <cds/logger.h>
  5. #include <cds/list.h>
  6. /* DB manipulation */
  7. static int db_add_extension_element(presentity_t *p, pa_extension_element_t *n)
  8. {
  9. db_key_t cols[20];
  10. db_val_t vals[20];
  11. int n_updates = 0;
  12. if (!use_db) return 0;
  13. /* set data */
  14. cols[n_updates] = col_dbid;
  15. vals[n_updates].type = DB_STR;
  16. vals[n_updates].nul = 0;
  17. vals[n_updates].val.str_val = n->dbid;
  18. n_updates++;
  19. cols[n_updates] = col_pres_id;
  20. vals[n_updates].type = DB_STR;
  21. vals[n_updates].nul = 0;
  22. vals[n_updates].val.str_val = p->pres_id;
  23. n_updates++;
  24. cols[n_updates] = col_etag;
  25. vals[n_updates].type = DB_STR;
  26. vals[n_updates].nul = 0;
  27. vals[n_updates].val.str_val = n->etag;
  28. n_updates++;
  29. cols[n_updates] = col_element;
  30. vals[n_updates].type = DB_BLOB;
  31. vals[n_updates].nul = 0;
  32. vals[n_updates].val.blob_val = n->data.element;
  33. n_updates++;
  34. cols[n_updates] = col_expires;
  35. vals[n_updates].type = DB_DATETIME;
  36. vals[n_updates].nul = 0;
  37. vals[n_updates].val.time_val = n->expires;
  38. n_updates++;
  39. /* run update */
  40. if (pa_dbf.use_table(pa_db, extension_elements_table) < 0) {
  41. ERR("Error in use_table\n");
  42. return -1;
  43. }
  44. if (pa_dbf.insert(pa_db, cols, vals, n_updates) < 0) {
  45. ERR("Can't insert record\n");
  46. return -1;
  47. }
  48. return 0;
  49. }
  50. static int db_remove_extension_element(presentity_t *p, pa_extension_element_t *n)
  51. {
  52. db_key_t keys[] = { col_pres_id, col_etag, col_dbid };
  53. db_op_t ops[] = { OP_EQ, OP_EQ, OP_EQ };
  54. db_val_t k_vals[] = { { DB_STR, 0, { .str_val = p->pres_id } },
  55. { DB_STR, 0, { .str_val = n->etag } },
  56. { DB_STR, 0, { .str_val = n->dbid } }
  57. };
  58. if (!use_db) return 0;
  59. if (pa_dbf.use_table(pa_db, extension_elements_table) < 0) {
  60. ERR("Error in use_table\n");
  61. return -1;
  62. }
  63. if (pa_dbf.delete(pa_db, keys, ops, k_vals, 3) < 0) {
  64. ERR("Can't delete record\n");
  65. return -1;
  66. }
  67. return 0;
  68. }
  69. int db_update_extension_element(presentity_t *p, pa_extension_element_t *n)
  70. {
  71. db_key_t cols[20];
  72. db_val_t vals[20];
  73. int n_updates = 0;
  74. db_key_t keys[] = { col_pres_id, col_etag, col_dbid };
  75. db_op_t ops[] = { OP_EQ, OP_EQ, OP_EQ };
  76. db_val_t k_vals[] = { { DB_STR, 0, { .str_val = p->pres_id } },
  77. { DB_STR, 0, { .str_val = n->etag } },
  78. { DB_STR, 0, { .str_val = n->dbid } }
  79. };
  80. if (!use_db) return 0;
  81. cols[n_updates] = col_element;
  82. vals[n_updates].type = DB_BLOB;
  83. vals[n_updates].nul = 0;
  84. vals[n_updates].val.blob_val = n->data.element;
  85. n_updates++;
  86. cols[n_updates] = col_expires;
  87. vals[n_updates].type = DB_DATETIME;
  88. vals[n_updates].nul = 0;
  89. vals[n_updates].val.time_val = n->expires;
  90. n_updates++;
  91. if (pa_dbf.use_table(pa_db, extension_elements_table) < 0) {
  92. ERR("Error in use_table\n");
  93. return -1;
  94. }
  95. if (pa_dbf.update(pa_db, keys, ops, k_vals,
  96. cols, vals, 3, n_updates) < 0) {
  97. ERR("Can't update record\n");
  98. return -1;
  99. }
  100. return 0;
  101. }
  102. int db_read_extension_elements(presentity_t *p, db_con_t* db)
  103. {
  104. db_key_t keys[] = { col_pres_id };
  105. db_op_t ops[] = { OP_EQ };
  106. db_val_t k_vals[] = { { DB_STR, 0, { .str_val = p->pres_id } } };
  107. int i;
  108. int r = 0;
  109. db_res_t *res = NULL;
  110. db_key_t result_cols[] = { col_dbid, col_etag,
  111. col_element, col_dbid, col_expires
  112. };
  113. if (!use_db) return 0;
  114. if (pa_dbf.use_table(db, extension_elements_table) < 0) {
  115. ERR("Error in use_table\n");
  116. return -1;
  117. }
  118. if (pa_dbf.query (db, keys, ops, k_vals,
  119. result_cols, 1, sizeof(result_cols) / sizeof(db_key_t),
  120. 0, &res) < 0) {
  121. ERR("Error while querying presence extension_elements\n");
  122. return -1;
  123. }
  124. if (!res) return 0; /* ? */
  125. for (i = 0; i < res->n; i++) {
  126. pa_extension_element_t *n = NULL;
  127. db_row_t *row = &res->rows[i];
  128. db_val_t *row_vals = ROW_VALUES(row);
  129. str dbid = STR_NULL;
  130. str etag = STR_NULL;
  131. str extension_element = STR_NULL;
  132. str id = STR_NULL;
  133. time_t expires = 0;
  134. #define get_str_val(i,dst) do{if(!row_vals[i].nul){dst.s=(char*)row_vals[i].val.string_val;dst.len=strlen(dst.s);}}while(0)
  135. #define get_blob_val(i,dst) do{if(!row_vals[i].nul){dst=row_vals[i].val.blob_val;}}while(0)
  136. #define get_time_val(i,dst) do{if(!row_vals[i].nul){dst=row_vals[i].val.time_val;}}while(0)
  137. get_str_val(0, dbid);
  138. get_str_val(1, etag);
  139. get_blob_val(2, extension_element);
  140. get_str_val(3, id);
  141. get_time_val(4, expires);
  142. #undef get_str_val
  143. #undef get_time_val
  144. n = create_pa_extension_element(&etag, &extension_element, expires, &dbid);
  145. if (n) DOUBLE_LINKED_LIST_ADD(p->data.first_unknown_element,
  146. p->data.last_unknown_element, (extension_element_t*)n);
  147. }
  148. pa_dbf.free_result(db, res);
  149. return r;
  150. }
  151. /* in memory presence extension_elements manipulation */
  152. void add_extension_element(presentity_t *_p, pa_extension_element_t *n)
  153. {
  154. DOUBLE_LINKED_LIST_ADD(_p->data.first_unknown_element,
  155. _p->data.last_unknown_element, (extension_element_t*)n);
  156. if (use_db) db_add_extension_element(_p, n);
  157. }
  158. void remove_extension_element(presentity_t *_p, pa_extension_element_t *n)
  159. {
  160. DOUBLE_LINKED_LIST_REMOVE(_p->data.first_unknown_element,
  161. _p->data.last_unknown_element,
  162. (extension_element_t*)n);
  163. if (use_db) db_remove_extension_element(_p, n);
  164. free_pa_extension_element(n);
  165. }
  166. void free_pa_extension_element(pa_extension_element_t *n)
  167. {
  168. if (n) mem_free(n);
  169. }
  170. int remove_extension_elements(presentity_t *p, str *etag)
  171. {
  172. pa_extension_element_t *n, *nn;
  173. int found = 0;
  174. n = (pa_extension_element_t*)p->data.first_unknown_element;
  175. while (n) {
  176. nn = (pa_extension_element_t*)n->data.next;
  177. if (str_case_equals(&n->etag, etag) == 0) {
  178. /* remove this */
  179. found++;
  180. remove_extension_element(p, n);
  181. }
  182. n = nn;
  183. }
  184. return found;
  185. }
  186. pa_extension_element_t *create_pa_extension_element(str *etag,
  187. str *extension_element,
  188. time_t expires, str *dbid)
  189. {
  190. pa_extension_element_t *pan;
  191. int size;
  192. if (!dbid) {
  193. ERR("invalid parameters\n");
  194. return NULL;
  195. }
  196. size = sizeof(pa_extension_element_t);
  197. if (dbid) size += dbid->len;
  198. if (etag) size += etag->len;
  199. if (extension_element) size += extension_element->len;
  200. pan = (pa_extension_element_t*)mem_alloc(size);
  201. if (!pan) {
  202. ERR("can't allocate memory: %d\n", size);
  203. return pan;
  204. }
  205. memset(pan, 0, sizeof(*pan));
  206. pan->expires = expires;
  207. pan->dbid.s = (char*)pan + sizeof(pa_extension_element_t);
  208. if (dbid) str_cpy(&pan->dbid, dbid);
  209. else pan->dbid.len = 0;
  210. pan->etag.s = after_str_ptr(&pan->dbid);
  211. str_cpy(&pan->etag, etag);
  212. pan->data.element.s = after_str_ptr(&pan->etag);
  213. str_cpy(&pan->data.element, extension_element);
  214. return pan;
  215. }
  216. pa_extension_element_t *extension_element2pa(extension_element_t *n, str *etag, time_t expires)
  217. {
  218. dbid_t id;
  219. str s;
  220. generate_dbid(id);
  221. s.len = dbid_strlen(id);
  222. s.s = dbid_strptr(id);
  223. return create_pa_extension_element(etag, &n->element, expires, &s);
  224. }