Add the "filter" keyword
authorTilghman Lesher <tilghman@meg.abyt.es>
Tue, 15 Jan 2008 23:52:11 +0000 (23:52 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Tue, 15 Jan 2008 23:52:11 +0000 (23:52 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@98947 65c4cc65-6c06-0410-ace0-fbb531ad65f3

cdr/cdr_adaptive_odbc.c
configs/cdr_adaptive_odbc.conf.sample

index 4c97620..b270582 100644 (file)
@@ -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);
index d539433..a16626e 100644 (file)
@@ -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