pres_notes.c 6.5 KB

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