From 799246dae34ebe986b71fb20aa24bf25cbb19778 Mon Sep 17 00:00:00 2001 From: Tilghman Lesher Date: Tue, 15 Jan 2008 23:52:11 +0000 Subject: Add the "filter" keyword git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@98947 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- cdr/cdr_adaptive_odbc.c | 34 +++++++++++++++++++++++++++++++--- configs/cdr_adaptive_odbc.conf.sample | 4 ++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/cdr/cdr_adaptive_odbc.c b/cdr/cdr_adaptive_odbc.c index 4c9762082..b270582af 100644 --- a/cdr/cdr_adaptive_odbc.c +++ b/cdr/cdr_adaptive_odbc.c @@ -56,6 +56,7 @@ static int maxsize = 512, maxsize2 = 512; struct columns { char *name; char *cdrname; + char *filtervalue; SQLSMALLINT type; SQLINTEGER size; SQLSMALLINT decimals; @@ -153,7 +154,7 @@ static int load_config(void) ast_verb(3, "Found adaptive CDR table %s@%s.\n", tableptr->table, tableptr->connection); while ((res = SQLFetch(stmt)) != SQL_NO_DATA && res != SQL_ERROR) { - char *cdrvar = ""; + char *cdrvar = "", *filter = ""; SQLGetData(stmt, 4, SQL_C_CHAR, columnname, sizeof(columnname), &sqlptr); @@ -164,14 +165,24 @@ static int load_config(void) * really don't parse this file all that often, anyway. */ for (var = ast_variable_browse(cfg, catg); var; var = var->next) { - if (strcasecmp(var->value, columnname) == 0) { + if (strncmp(var->name, "alias", 5) == 0 && strcasecmp(var->value, columnname) == 0) { char *tmp = ast_strdupa(var->name + 5); cdrvar = ast_strip(tmp); ast_verb(3, "Found alias %s for column %s in %s@%s\n", cdrvar, columnname, tableptr->table, tableptr->connection); break; } } - entry = ast_calloc(sizeof(char), sizeof(*entry) + strlen(columnname) + 1 + strlen(cdrvar) + 1); + /* Two loops, because alias and filter could be in reverse order */ + for (var = ast_variable_browse(cfg, catg); var; var = var->next) { + if (strncmp(var->name, "filter", 6) == 0 && strcasecmp(var->name + 6, S_OR(cdrvar, columnname))) { + char *tmp = ast_strdupa(var->name + 6); + filter = ast_strip(tmp); + ast_verb(3, "Found filter %s for cdr variable %s in %s@%s\n", filter, S_OR(cdrvar, columnname), tableptr->table, tableptr->connection); + break; + } + } + + entry = ast_calloc(sizeof(char), sizeof(*entry) + strlen(columnname) + 1 + strlen(cdrvar) + 1 + strlen(filter) + 1); if (!entry) { ast_log(LOG_ERROR, "Out of memory creating entry for column '%s' in table '%s' on connection '%s'\n", columnname, table, connection); res = -1; @@ -186,6 +197,11 @@ static int load_config(void) } else /* Point to same place as the column name */ entry->cdrname = (char *)entry + sizeof(*entry); + if (!ast_strlen_zero(filter)) { + entry->filtervalue = entry->cdrname + strlen(entry->cdrname) + 1; + strcpy(entry->filtervalue, filter); + } + SQLGetData(stmt, 5, SQL_C_SHORT, &entry->type, sizeof(entry->type), NULL); SQLGetData(stmt, 7, SQL_C_LONG, &entry->size, sizeof(entry->size), NULL); SQLGetData(stmt, 9, SQL_C_SHORT, &entry->decimals, sizeof(entry->decimals), NULL); @@ -341,6 +357,17 @@ static int odbc_log(struct ast_cdr *cdr) strcasecmp(entry->cdrname, "end") == 0) ? 0 : 1); if (colptr) { + /* Check first if the column filters this entry. Note that this + * is very specifically NOT ast_strlen_zero(), because the filter + * could legitimately specify that the field is blank, which is + * different from the field being unspecified (NULL). */ + if (entry->filtervalue && strcasecmp(colptr, entry->filtervalue) != 0) { + ast_verb(4, "CDR column '%s' with value '%s' does not match filter of" + " '%s'. Cancelling this CDR.\n", + entry->cdrname, colptr, entry->filtervalue); + goto early_release; + } + LENGTHEN_BUF1(strlen(entry->name)); switch (entry->type) { @@ -567,6 +594,7 @@ static int odbc_log(struct ast_cdr *cdr) if (rows == 0) { ast_log(LOG_WARNING, "cdr_adaptive_odbc: Insert failed on '%s:%s'. CDR failed: %s\n", tableptr->connection, tableptr->table, sql); } +early_release: ast_odbc_release_obj(obj); } AST_RWLIST_UNLOCK(&odbc_tables); diff --git a/configs/cdr_adaptive_odbc.conf.sample b/configs/cdr_adaptive_odbc.conf.sample index d539433f3..a16626e58 100644 --- a/configs/cdr_adaptive_odbc.conf.sample +++ b/configs/cdr_adaptive_odbc.conf.sample @@ -32,5 +32,9 @@ ;alias channel => source_channel ;alias dst => dest ;alias dstchannel => dest_channel +; +; Any filter specified MUST match exactly or the CDR will be discarded +;filter accountcode => somename +;filter src => 123 -- cgit v1.2.3