Gerald Dachs
2005-Nov-23 06:20 UTC
[Asterisk-Users] [patch] sqlite3 support for asterisk 1.2.0
Hi, I changed cdr_sqlite so that it builds with sqlite3. I named the new module cdr_sqlite3. It builds, but I will not be able to test it the next days. I provide it anyway, maybe a brave heart gives me response. Gerald diff -Nur asterisk-1.2.0.orig/cdr/cdr_sqlite3.c asterisk-1.2.0.sqlite3/cdr/cdr_sqlite3.c --- asterisk-1.2.0.orig/cdr/cdr_sqlite3.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.0.sqlite3/cdr/cdr_sqlite3.c 2005-11-23 14:01:29.000000000 +0100 @@ -0,0 +1,244 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2004 - 2005, Holger Schurig + * + * + * Ideas taken from other cdr_*.c files + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + * + * Changes for SQLite 3 by Gerald Dachs + * + */ + +/*! \file + * + * \brief Store CDR records in a SQLite database. + * + * \author Holger Schurig <hs4233@mail.mn-solutions.de> + * + * See also + * \arg \ref Config_cdr + * \arg http://www.sqlite.org/ + * + * Creates the database and table on-the-fly + * \ingroup cdr_drivers + */ + +#include <sys/types.h> + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <sqlite3.h> + +#include "asterisk.h" + +ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.11 $") + +#include "asterisk/channel.h" +#include "asterisk/module.h" +#include "asterisk/logger.h" +#include "asterisk/utils.h" + +#define LOG_UNIQUEID 0 +#define LOG_USERFIELD 0 + +/* When you change the DATE_FORMAT, be sure to change the CHAR(19) below to something else */ +#define DATE_FORMAT "%Y-%m-%d %T" + +static char *desc = "SQLite3 CDR Backend"; +static char *name = "sqlite3"; +static sqlite3* db = NULL; + +AST_MUTEX_DEFINE_STATIC(sqlite3_lock); + +/*! \brief SQL table format */ +static char sql_create_table[] = "CREATE TABLE cdr (" +" AcctId INTEGER PRIMARY KEY," +" clid VARCHAR(80)," +" src VARCHAR(80)," +" dst VARCHAR(80)," +" dcontext VARCHAR(80)," +" channel VARCHAR(80)," +" dstchannel VARCHAR(80)," +" lastapp VARCHAR(80)," +" lastdata VARCHAR(80)," +" start CHAR(19)," +" answer CHAR(19)," +" end CHAR(19)," +" duration INTEGER," +" billsec INTEGER," +" disposition INTEGER," +" amaflags INTEGER," +" accountcode VARCHAR(20)" +#if LOG_UNIQUEID +" ,uniqueid VARCHAR(32)" +#endif +#if LOG_USERFIELD +" ,userfield VARCHAR(255)" +#endif +");"; + +static int sqlite3_log(struct ast_cdr *cdr) +{ + int res = 0; + char *zErr = 0; + struct tm tm; + time_t t; + char startstr[80], answerstr[80], endstr[80]; + int count; + char *sqlstmt; + + ast_mutex_lock(&sqlite3_lock); + + t = cdr->start.tv_sec; + localtime_r(&t, &tm); + strftime(startstr, sizeof(startstr), DATE_FORMAT, &tm); + + t = cdr->answer.tv_sec; + localtime_r(&t, &tm); + strftime(answerstr, sizeof(answerstr), DATE_FORMAT, &tm); + + t = cdr->end.tv_sec; + localtime_r(&t, &tm); + strftime(endstr, sizeof(endstr), DATE_FORMAT, &tm); + + for(count=0; count<5; count++) { + if ((sqlstmt = sqlite3_mprintf( + "INSERT INTO cdr (" + "clid,src,dst,dcontext," + "channel,dstchannel,lastapp,lastdata, " + "start,answer,end," + "duration,billsec,disposition,amaflags, " + "accountcode" +# if LOG_UNIQUEID + ",uniqueid" +# endif +# if LOG_USERFIELD + ",userfield" +# endif + ") VALUES (" + "'%q', '%q', '%q', '%q', " + "'%q', '%q', '%q', '%q', " + "'%q', '%q', '%q', " + "%d, %d, %d, %d, " + "'%q'" +# if LOG_UNIQUEID + ",'%q'" +# endif +# if LOG_USERFIELD + ",'%q'" +# endif + ")", cdr->clid, cdr->src, cdr->dst, cdr->dcontext, + cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata, + startstr, answerstr, endstr, + cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags, + cdr->accountcode +# if LOG_UNIQUEID + ,cdr->uniqueid +# endif +# if LOG_USERFIELD + ,cdr->userfield +# endif + )) == NULL) + { + ast_log(LOG_ERROR, "cdr_sqlite3: no memory for sqlite3_mprintf\n"); + return -1; /* Don't know what to return here */ + } + + res = sqlite3_exec(db, sqlstmt, NULL, NULL, &zErr); + + sqlite3_free(sqlstmt); + + if (res != SQLITE_BUSY && res != SQLITE_LOCKED) + break; + usleep(200); + } + + if (zErr) { + ast_log(LOG_ERROR, "cdr_sqlite3: %s\n", zErr); + free(zErr); + } + + ast_mutex_unlock(&sqlite3_lock); + return res; +} + + +char *description(void) +{ + return desc; +} + +int unload_module(void) +{ + if (db) + sqlite3_close(db); + ast_cdr_unregister(name); + return 0; +} + +int load_module(void) +{ + char *zErr; + char fn[PATH_MAX]; + int res; + + /* is the database there? */ + snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR); + if (sqlite3_open(fn, &db) != SQLITE_OK) { + ast_log(LOG_ERROR, "cdr_sqlite3: %s\n", sqlite3_errmsg(db)); + return -1; + } + + /* is the table there? */ + res = sqlite3_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL); + if (res) { + res = sqlite3_exec(db, sql_create_table, NULL, NULL, &zErr); + if (res) { + ast_log(LOG_ERROR, "cdr_sqlite3: Unable to create table 'cdr': %s\n", zErr); + free(zErr); + goto err; + } + + /* TODO: here we should probably create an index */ + } + + res = ast_cdr_register(name, desc, sqlite3_log); + if (res) { + ast_log(LOG_ERROR, "Unable to register SQLite3 CDR handling\n"); + return -1; + } + return 0; + +err: + if (db) + sqlite3_close(db); + return -1; +} + +int reload(void) +{ + return 0; +} + +int usecount(void) +{ + return 0; +} + +char *key() +{ + return ASTERISK_GPL_KEY; +} diff -Nur asterisk-1.2.0.orig/cdr/Makefile asterisk-1.2.0.sqlite3/cdr/Makefile --- asterisk-1.2.0.orig/cdr/Makefile 2005-11-14 01:45:07.000000000 +0100 +++ asterisk-1.2.0.sqlite3/cdr/Makefile 2005-11-23 13:17:41.000000000 +0100 @@ -107,6 +107,10 @@ MODS+=cdr_sqlite.so endif +ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/sqlite3.h),) + MODS+=cdr_sqlite3.so +endif + all: depend $(MODS) install: all @@ -134,6 +138,9 @@ cdr_sqlite.so: cdr_sqlite.o $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} -lsqlite $(MLFLAGS) +cdr_sqlite3.so: cdr_sqlite3.o + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} -lsqlite3 $(MLFLAGS) + depend: .depend .depend: