You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/modules/db_flatstore/flat_cmd.c

217 lines
4.9 KiB

/*
* $Id$
*
* Copyright (C) 2004 FhG FOKUS
* Copyright (C) 2008 iptelorg GmbH
* Written by Jan Janak <jan@iptel.org>
*
* This file is part of SER, a free SIP server.
*
* SER is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* SER is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** \addtogroup flatstore
* @{
*/
/** \file
* Inmplementation of flatstore commands.
*/
#include "flat_cmd.h"
#include "flat_con.h"
#include "flatstore_mod.h"
#include "../../mem/mem.h"
#include <string.h>
#include <errno.h>
/** Destroys a flat_cmd structure.
* This function frees all memory used by flat_cmd structure.
* @param cmd A pointer to generic db_cmd command being freed.
* @param payload A pointer to flat_cmd structure to be freed.
*/
static void flat_cmd_free(db_cmd_t* cmd, struct flat_cmd* payload)
{
db_drv_free(&payload->gen);
pkg_free(payload);
}
int flat_cmd(db_cmd_t* cmd)
{
struct flat_cmd* fcmd;
db_con_t* con;
if (cmd->type != DB_PUT) {
ERR("flatstore: The driver supports PUT operation only.\n");
return -1;
}
if (DB_FLD_EMPTY(cmd->vals)) {
ERR("flatstore: PUT command with no values encountered\n");
return -1;
}
fcmd = (struct flat_cmd*)pkg_malloc(sizeof(struct flat_cmd));
if (fcmd == NULL) {
ERR("flatstore: No memory left\n");
return -1;
}
memset(fcmd, '\0', sizeof(struct flat_cmd));
if (db_drv_init(&fcmd->gen, flat_cmd_free) < 0) goto error;
/* FIXME */
con = cmd->ctx->con[db_payload_idx];
if (flat_open_table(&fcmd->file_index, con, &cmd->table) < 0) goto error;
DB_SET_PAYLOAD(cmd, fcmd);
return 0;
error:
if (fcmd) {
DB_SET_PAYLOAD(cmd, NULL);
db_drv_free(&fcmd->gen);
pkg_free(fcmd);
}
return -1;
}
int flat_put(db_res_t* res, db_cmd_t* cmd)
{
struct flat_cmd* fcmd;
struct flat_con* fcon;
db_con_t* con;
int i;
FILE* f;
char delims[4], *s;
size_t len;
fcmd = DB_GET_PAYLOAD(cmd);
/* FIXME */
con = cmd->ctx->con[db_payload_idx];
fcon = DB_GET_PAYLOAD(con);
f = fcon->file[fcmd->file_index].f;
if (f == NULL) {
ERR("flatstore: Cannot write, file handle not open\n");
return -1;
}
if (flat_local_timestamp < *flat_rotate) {
flat_con_disconnect(con);
if (flat_con_connect(con) < 0) {
ERR("flatstore: Error while rotating files\n");
return -1;
}
flat_local_timestamp = *flat_rotate;
}
for(i = 0; !DB_FLD_EMPTY(cmd->vals) && !DB_FLD_LAST(cmd->vals[i]); i++) {
if (i) {
if (fprintf(f, "%c", flat_delimiter.s[0]) < 0) goto error;
}
/* TODO: how to distinguish NULL from empty */
if (cmd->vals[i].flags & DB_NULL) continue;
switch(cmd->vals[i].type) {
case DB_INT:
if (fprintf(f, "%d", cmd->vals[i].v.int4) < 0) goto error;
break;
case DB_FLOAT:
if (fprintf(f, "%f", cmd->vals[i].v.flt) < 0) goto error;
break;
case DB_DOUBLE:
if (fprintf(f, "%f", cmd->vals[i].v.dbl) < 0) goto error;
break;
case DB_DATETIME:
if (fprintf(f, "%u", (unsigned int)cmd->vals[i].v.time) < 0)
goto error;
break;
case DB_CSTR:
s = cmd->vals[i].v.cstr;
delims[0] = flat_delimiter.s[0];
delims[1] = flat_record_delimiter.s[0];
delims[2] = flat_escape.s[0];
delims[3] = '\0';
while (*s) {
len = strcspn(s, delims);
if (fprintf(f, "%.*s", (int)len, s) < 0) goto error;
s += len;
if (*s) {
/* FIXME: do not use the escaped value for easier parsing */
if (fprintf(f, "%c%c", flat_escape.s[0], *s) < 0) goto error;
s++;
}
}
break;
case DB_STR:
case DB_BLOB:
/* FIXME: rewrite */
s = cmd->vals[i].v.lstr.s;
len = cmd->vals[i].v.lstr.len;
while (len > 0) {
char *c;
for (c = s; len > 0 &&
*c != flat_delimiter.s[0] &&
*c != flat_record_delimiter.s[0] &&
*c != flat_escape.s[0];
c++, len--);
if (fprintf(f, "%.*s", (int)(c-s), s) < 0) goto error;
s = c;
if (len > 0) {
if (fprintf(f, "%c%c", flat_escape.s[0], *s) < 0) goto error;
s++;
len--;
}
}
break;
case DB_BITMAP:
if (fprintf(f, "%u", cmd->vals[i].v.bitmap) < 0) goto error;
break;
default:
BUG("flatstore: Unsupported field type %d\n", cmd->vals[i].type);
return -1;
}
}
if (fprintf(f, "%c", flat_record_delimiter.s[0]) < 0) goto error;
if (flat_flush && (fflush(f) != 0)) {
ERR("flatstore: Error while flushing file: %s\n", strerror(errno));
return -1;
}
return 0;
error:
ERR("flastore: Error while writing data to file\n");
return -1;
}
/** @} */