flat_cmd.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * Copyright (C) 2004 FhG FOKUS
00005  * Copyright (C) 2008 iptelorg GmbH
00006  * Written by Jan Janak <jan@iptel.org>
00007  *
00008  * This file is part of SER, a free SIP server.
00009  *
00010  * SER is free software; you can redistribute it and/or modify it under the
00011  * terms of the GNU General Public License as published by the Free Software
00012  * Foundation; either version 2 of the License, or (at your option) any later
00013  * version.
00014  *
00015  * SER is distributed in the hope that it will be useful, but WITHOUT ANY
00016  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00018  * details.
00019  *
00020  * You should have received a copy of the GNU General Public License along
00021  * with this program; if not, write to the Free Software Foundation, Inc., 
00022  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00023  */
00024 
00033 #include "flat_cmd.h"
00034 #include "flat_con.h"
00035 #include "flatstore_mod.h"
00036 
00037 #include "../../mem/mem.h"
00038 
00039 #include <string.h>
00040 #include <errno.h>
00041 
00042 
00048 static void flat_cmd_free(db_cmd_t* cmd, struct flat_cmd* payload)
00049 {
00050         db_drv_free(&payload->gen);
00051         pkg_free(payload);
00052 }
00053 
00054 
00055 int flat_cmd(db_cmd_t* cmd)
00056 {
00057         struct flat_cmd* fcmd;
00058         db_con_t* con;
00059 
00060         if (cmd->type != DB_PUT) {
00061                 ERR("flatstore: The driver supports PUT operation only.\n");
00062                 return -1;
00063         }
00064 
00065         if (DB_FLD_EMPTY(cmd->vals)) {
00066                 ERR("flatstore: PUT command with no values encountered\n");
00067                 return -1;
00068         }
00069 
00070         fcmd = (struct flat_cmd*)pkg_malloc(sizeof(struct flat_cmd));
00071         if (fcmd == NULL) {
00072                 ERR("flatstore: No memory left\n");
00073                 return -1;
00074         }
00075         memset(fcmd, '\0', sizeof(struct flat_cmd));
00076         if (db_drv_init(&fcmd->gen, flat_cmd_free) < 0) goto error;
00077 
00078         /* FIXME */
00079         con = cmd->ctx->con[db_payload_idx];
00080         if (flat_open_table(&fcmd->file_index, con, &cmd->table) < 0) goto error;
00081 
00082         DB_SET_PAYLOAD(cmd, fcmd);
00083         return 0;
00084 
00085  error:
00086         if (fcmd) {
00087                 DB_SET_PAYLOAD(cmd, NULL);
00088                 db_drv_free(&fcmd->gen);
00089                 pkg_free(fcmd);
00090         }
00091         return -1;
00092 }
00093 
00094 
00095 int flat_put(db_res_t* res, db_cmd_t* cmd)
00096 {
00097         struct flat_cmd* fcmd;
00098         struct flat_con* fcon;
00099         db_con_t* con;
00100         int i;
00101         FILE* f;
00102         char delims[4], *s;
00103         size_t len;
00104 
00105         fcmd = DB_GET_PAYLOAD(cmd);
00106         /* FIXME */
00107         con = cmd->ctx->con[db_payload_idx];
00108         fcon = DB_GET_PAYLOAD(con);
00109 
00110         f = fcon->file[fcmd->file_index].f;
00111         if (f == NULL) {
00112                 ERR("flatstore: Cannot write, file handle not open\n");
00113                 return -1;
00114         }
00115 
00116         if (flat_local_timestamp < *flat_rotate) {
00117                 flat_con_disconnect(con);
00118                 if (flat_con_connect(con) < 0) {
00119                         ERR("flatstore: Error while rotating files\n");
00120                         return -1;
00121                 }
00122                 flat_local_timestamp = *flat_rotate;
00123         }
00124 
00125         for(i = 0; !DB_FLD_EMPTY(cmd->vals) && !DB_FLD_LAST(cmd->vals[i]); i++) {
00126                 if (i) {
00127                         if (fprintf(f, "%c", flat_delimiter.s[0]) < 0) goto error;
00128                 }
00129 
00130                 /* TODO: how to distinguish NULL from empty */
00131                 if (cmd->vals[i].flags & DB_NULL) continue;
00132                 
00133                 switch(cmd->vals[i].type) {
00134                 case DB_INT:
00135                         if (fprintf(f, "%d", cmd->vals[i].v.int4) < 0) goto error;
00136                         break;
00137 
00138                 case DB_FLOAT:
00139                         if (fprintf(f, "%f", cmd->vals[i].v.flt) < 0) goto error;
00140                         break;
00141 
00142                 case DB_DOUBLE:
00143                         if (fprintf(f, "%f", cmd->vals[i].v.dbl) < 0) goto error;
00144                         break;
00145 
00146                 case DB_DATETIME:
00147                         if (fprintf(f, "%u", (unsigned int)cmd->vals[i].v.time) < 0) 
00148                                 goto error;
00149                         break;
00150 
00151                 case DB_CSTR:
00152                         s = cmd->vals[i].v.cstr;
00153                         delims[0] = flat_delimiter.s[0];
00154                         delims[1] = flat_record_delimiter.s[0];
00155                         delims[2] = flat_escape.s[0];
00156                         delims[3] = '\0';
00157                         while (*s) {
00158                                 len = strcspn(s, delims);
00159                                 if (fprintf(f, "%.*s", (int)len, s) < 0) goto error;
00160                                 s += len;
00161                                 if (*s) {
00162                                         /* FIXME: do not use the escaped value for easier parsing */
00163                                         if (fprintf(f, "%c%c", flat_escape.s[0], *s) < 0) goto error;
00164                                         s++;
00165                                 }
00166                         }
00167                         break;
00168 
00169                 case DB_STR:
00170                 case DB_BLOB:
00171                         /* FIXME: rewrite */
00172                         s = cmd->vals[i].v.lstr.s;
00173                         len = cmd->vals[i].v.lstr.len;
00174                         while (len > 0) {
00175                                 char *c;
00176                                 for (c = s; len > 0 && 
00177                                                  *c != flat_delimiter.s[0] && 
00178                                                  *c != flat_record_delimiter.s[0] && 
00179                                                  *c != flat_escape.s[0]; 
00180                                          c++, len--);
00181                                 if (fprintf(f, "%.*s", (int)(c-s), s) < 0) goto error;
00182                                 s = c;
00183                                 if (len > 0) {
00184                                         if (fprintf(f, "%c%c", flat_escape.s[0], *s) < 0) goto error;
00185                                         s++;
00186                                         len--;
00187                                 }
00188                         }
00189                         break;
00190 
00191                 case DB_BITMAP:
00192                         if (fprintf(f, "%u", cmd->vals[i].v.bitmap) < 0) goto error;
00193                         break;
00194 
00195                 default:
00196                         BUG("flatstore: Unsupported field type %d\n", cmd->vals[i].type);
00197                         return -1;
00198                 }
00199         }
00200 
00201         if (fprintf(f, "%c", flat_record_delimiter.s[0]) < 0) goto error;
00202 
00203         if (flat_flush && (fflush(f) != 0)) {
00204                 ERR("flatstore: Error while flushing file: %s\n", strerror(errno));
00205                 return -1;
00206         }
00207 
00208         return 0;
00209 
00210  error:
00211         ERR("flastore: Error while writing data to file\n");
00212         return -1;
00213 }
00214 
00215