flat_cmd.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2004 FhG FOKUS
  5. * Copyright (C) 2008 iptelorg GmbH
  6. * Written by Jan Janak <[email protected]>
  7. *
  8. * This file is part of SER, a free SIP server.
  9. *
  10. * SER is free software; you can redistribute it and/or modify it under the
  11. * terms of the GNU General Public License as published by the Free Software
  12. * Foundation; either version 2 of the License, or (at your option) any later
  13. * version.
  14. *
  15. * SER is distributed in the hope that it will be useful, but WITHOUT ANY
  16. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  17. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  18. * details.
  19. *
  20. * You should have received a copy of the GNU General Public License along
  21. * with this program; if not, write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. */
  24. /** \addtogroup flatstore
  25. * @{
  26. */
  27. /** \file
  28. * Inmplementation of flatstore commands.
  29. */
  30. #include "flat_cmd.h"
  31. #include "flat_con.h"
  32. #include "flatstore_mod.h"
  33. #include "../../mem/mem.h"
  34. #include <string.h>
  35. #include <errno.h>
  36. /** Destroys a flat_cmd structure.
  37. * This function frees all memory used by flat_cmd structure.
  38. * @param cmd A pointer to generic db_cmd command being freed.
  39. * @param payload A pointer to flat_cmd structure to be freed.
  40. */
  41. static void flat_cmd_free(db_cmd_t* cmd, struct flat_cmd* payload)
  42. {
  43. db_drv_free(&payload->gen);
  44. pkg_free(payload);
  45. }
  46. int flat_cmd(db_cmd_t* cmd)
  47. {
  48. struct flat_cmd* fcmd;
  49. db_con_t* con;
  50. if (cmd->type != DB_PUT) {
  51. ERR("flatstore: The driver supports PUT operation only.\n");
  52. return -1;
  53. }
  54. if (DB_FLD_EMPTY(cmd->vals)) {
  55. ERR("flatstore: PUT command with no values encountered\n");
  56. return -1;
  57. }
  58. fcmd = (struct flat_cmd*)pkg_malloc(sizeof(struct flat_cmd));
  59. if (fcmd == NULL) {
  60. ERR("flatstore: No memory left\n");
  61. return -1;
  62. }
  63. memset(fcmd, '\0', sizeof(struct flat_cmd));
  64. if (db_drv_init(&fcmd->gen, flat_cmd_free) < 0) goto error;
  65. /* FIXME */
  66. con = cmd->ctx->con[db_payload_idx];
  67. if (flat_open_table(&fcmd->file_index, con, &cmd->table) < 0) goto error;
  68. DB_SET_PAYLOAD(cmd, fcmd);
  69. return 0;
  70. error:
  71. if (fcmd) {
  72. DB_SET_PAYLOAD(cmd, NULL);
  73. db_drv_free(&fcmd->gen);
  74. pkg_free(fcmd);
  75. }
  76. return -1;
  77. }
  78. int flat_put(db_res_t* res, db_cmd_t* cmd)
  79. {
  80. struct flat_cmd* fcmd;
  81. struct flat_con* fcon;
  82. db_con_t* con;
  83. int i;
  84. FILE* f;
  85. char delims[4], *s;
  86. size_t len;
  87. fcmd = DB_GET_PAYLOAD(cmd);
  88. /* FIXME */
  89. con = cmd->ctx->con[db_payload_idx];
  90. fcon = DB_GET_PAYLOAD(con);
  91. f = fcon->file[fcmd->file_index].f;
  92. if (f == NULL) {
  93. ERR("flatstore: Cannot write, file handle not open\n");
  94. return -1;
  95. }
  96. if (flat_local_timestamp < *flat_rotate) {
  97. flat_con_disconnect(con);
  98. if (flat_con_connect(con) < 0) {
  99. ERR("flatstore: Error while rotating files\n");
  100. return -1;
  101. }
  102. flat_local_timestamp = *flat_rotate;
  103. }
  104. for(i = 0; !DB_FLD_EMPTY(cmd->vals) && !DB_FLD_LAST(cmd->vals[i]); i++) {
  105. if (i) {
  106. if (fprintf(f, "%c", flat_delimiter.s[0]) < 0) goto error;
  107. }
  108. /* TODO: how to distinguish NULL from empty */
  109. if (cmd->vals[i].flags & DB_NULL) continue;
  110. switch(cmd->vals[i].type) {
  111. case DB_INT:
  112. if (fprintf(f, "%d", cmd->vals[i].v.int4) < 0) goto error;
  113. break;
  114. case DB_FLOAT:
  115. if (fprintf(f, "%f", cmd->vals[i].v.flt) < 0) goto error;
  116. break;
  117. case DB_DOUBLE:
  118. if (fprintf(f, "%f", cmd->vals[i].v.dbl) < 0) goto error;
  119. break;
  120. case DB_DATETIME:
  121. if (fprintf(f, "%u", (unsigned int)cmd->vals[i].v.time) < 0)
  122. goto error;
  123. break;
  124. case DB_CSTR:
  125. s = cmd->vals[i].v.cstr;
  126. delims[0] = flat_delimiter.s[0];
  127. delims[1] = flat_record_delimiter.s[0];
  128. delims[2] = flat_escape.s[0];
  129. delims[3] = '\0';
  130. while (*s) {
  131. len = strcspn(s, delims);
  132. if (fprintf(f, "%.*s", (int)len, s) < 0) goto error;
  133. s += len;
  134. if (*s) {
  135. /* FIXME: do not use the escaped value for easier parsing */
  136. if (fprintf(f, "%c%c", flat_escape.s[0], *s) < 0) goto error;
  137. s++;
  138. }
  139. }
  140. break;
  141. case DB_STR:
  142. case DB_BLOB:
  143. /* FIXME: rewrite */
  144. s = cmd->vals[i].v.lstr.s;
  145. len = cmd->vals[i].v.lstr.len;
  146. while (len > 0) {
  147. char *c;
  148. for (c = s; len > 0 &&
  149. *c != flat_delimiter.s[0] &&
  150. *c != flat_record_delimiter.s[0] &&
  151. *c != flat_escape.s[0];
  152. c++, len--);
  153. if (fprintf(f, "%.*s", (int)(c-s), s) < 0) goto error;
  154. s = c;
  155. if (len > 0) {
  156. if (fprintf(f, "%c%c", flat_escape.s[0], *s) < 0) goto error;
  157. s++;
  158. len--;
  159. }
  160. }
  161. break;
  162. case DB_BITMAP:
  163. if (fprintf(f, "%u", cmd->vals[i].v.bitmap) < 0) goto error;
  164. break;
  165. default:
  166. BUG("flatstore: Unsupported field type %d\n", cmd->vals[i].type);
  167. return -1;
  168. }
  169. }
  170. if (fprintf(f, "%c", flat_record_delimiter.s[0]) < 0) goto error;
  171. if (flat_flush && (fflush(f) != 0)) {
  172. ERR("flatstore: Error while flushing file: %s\n", strerror(errno));
  173. return -1;
  174. }
  175. return 0;
  176. error:
  177. ERR("flastore: Error while writing data to file\n");
  178. return -1;
  179. }
  180. /** @} */