[asterisk-addons-commits] tilghman: trunk r653 - /trunk/cdr/cdr_addon_mysql.c
SVN commits to the Asterisk addons project
asterisk-addons-commits at lists.digium.com
Thu Aug 28 11:38:25 CDT 2008
Author: tilghman
Date: Thu Aug 28 11:38:24 2008
New Revision: 653
URL: http://svn.digium.com/view/asterisk-addons?view=rev&rev=653
Log:
Don't DESC the MySQL table every time through, but instead cache the state
at module load and reload, just like the other CDR drivers.
(closes issue #13379)
Reported by: Corydon76
Patches:
20080826__cdr_mysql__2.diff.txt uploaded by Corydon76 (license 14)
Tested by: chris-mac
Modified:
trunk/cdr/cdr_addon_mysql.c
Modified: trunk/cdr/cdr_addon_mysql.c
URL: http://svn.digium.com/view/asterisk-addons/trunk/cdr/cdr_addon_mysql.c?view=diff&rev=653&r1=652&r2=653
==============================================================================
--- trunk/cdr/cdr_addon_mysql.c (original)
+++ trunk/cdr/cdr_addon_mysql.c Thu Aug 28 11:38:24 2008
@@ -83,11 +83,12 @@
struct column {
char *name;
char *cdrname;
+ char *type;
AST_LIST_ENTRY(column) list;
};
/* Protected with mysql_lock */
-static AST_LIST_HEAD_NOLOCK_STATIC(columns, column);
+static AST_RWLIST_HEAD_STATIC(columns, column);
static MYSQL mysql = { { NULL }, };
@@ -149,7 +150,6 @@
static int mysql_log(struct ast_cdr *cdr)
{
- char sqldesc[128];
char *sql1 = ast_calloc(1, 4096), *sql2 = ast_calloc(1, 2048);
int sql1size = 4096, sql2size = 2048;
int retries = 5;
@@ -204,54 +204,27 @@
ast_log(LOG_ERROR, "Unknown connection error: (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));
}
retries--;
- if (retries)
+ if (retries) {
goto db_reconnect;
- else
- ast_log(LOG_ERROR, "Retried to connect fives times, giving up.\n");
+ } else {
+ ast_log(LOG_ERROR, "Retried to connect five times, giving up.\n");
+ }
}
}
if (connected) {
- MYSQL_ROW row;
- MYSQL_RES *result;
int column_count = 0;
+ char *cdrname;
+ char workspace[2048], *value = NULL, *ptr;
+ int sql2len;
+ struct column *entry;
snprintf(sql1, sql1size, "INSERT INTO %s (", dbtable ? dbtable->str : "cdr");
strcpy(sql2, ") VALUES ('");
- /* Get table description */
- snprintf(sqldesc, sizeof(sqldesc), "DESC %s", dbtable ? dbtable->str : "cdr");
- if (mysql_query(&mysql, sqldesc)) {
- ast_log(LOG_ERROR, "Unable to query table description!!\n");
- mysql_close(&mysql);
- connected = 0;
- goto log_exit;
- }
-
- if (!(result = mysql_store_result(&mysql))) {
- ast_log(LOG_ERROR, "Unable to query table description!!\n");
- mysql_close(&mysql);
- connected = 0;
- goto log_exit;
- }
-
- while ((row = mysql_fetch_row(result))) {
- struct column *entry;
- char *cdrname;
- char workspace[2048], *value = NULL, *ptr;
- int sql2len;
-
- ast_debug(1, "Got a field '%s' of type '%s'\n", row[0], row[1]);
- /* Check for an alias */
- AST_LIST_TRAVERSE(&columns, entry, list) {
- /* This would probably be better off as a hash */
- if (!strcasecmp(entry->name, row[0]))
- break;
- }
-
- if (entry) {
- cdrname = entry->cdrname;
- } else if (!strcmp(row[0], "calldate")) {
+ AST_RWLIST_RDLOCK(&columns);
+ AST_RWLIST_TRAVERSE(&columns, entry, list) {
+ if (!strcmp(entry->name, "calldate")) {
/*!\note
* For some dumb reason, "calldate" used to be formulated using
* the datetime the record was posted, rather than the start
@@ -270,7 +243,7 @@
cdrname = "start";
}
} else {
- cdrname = row[0];
+ cdrname = entry->cdrname;
}
/* Construct SQL */
@@ -279,14 +252,14 @@
strcat(sql2, "','");
}
- if (strlen(sql1) + 2 + strlen(row[0]) > sql1size) {
+ if (strlen(sql1) + 2 + strlen(entry->name) > sql1size) {
char *tmp = ast_realloc(sql1, sql1size * 2);
if (!tmp)
goto log_exit;
sql1size *= 2;
sql1 = tmp;
}
- strcat(sql1, row[0]);
+ strcat(sql1, entry->name);
/* Need the type and value to determine if we want the raw value or not */
if ((!strcmp(cdrname, "start") ||
@@ -294,13 +267,13 @@
!strcmp(cdrname, "end") ||
!strcmp(cdrname, "disposition") ||
!strcmp(cdrname, "amaflags")) &&
- (strstr(row[1], "int") ||
- strstr(row[1], "dec") ||
- strstr(row[1], "float") ||
- strstr(row[1], "double") ||
- strstr(row[1], "real") ||
- strstr(row[1], "numeric") ||
- strstr(row[1], "fixed")))
+ (strstr(entry->type, "int") ||
+ strstr(entry->type, "dec") ||
+ strstr(entry->type, "float") ||
+ strstr(entry->type, "double") ||
+ strstr(entry->type, "real") ||
+ strstr(entry->type, "numeric") ||
+ strstr(entry->type, "fixed")))
ast_cdr_getvar(cdr, cdrname, &value, workspace, sizeof(workspace), 0, 1);
else
ast_cdr_getvar(cdr, cdrname, &value, workspace, sizeof(workspace), 0, 0);
@@ -329,7 +302,7 @@
sql2[sql2len] = '\0';
}
}
- mysql_free_result(result);
+ AST_RWLIST_UNLOCK(&columns);
ast_debug(1, "Inserting a CDR record.\n");
if (strlen(sql1) + 3 + strlen(sql2) > sql1size) {
@@ -379,8 +352,11 @@
}
AST_LIST_UNLOCK(&unload_strings);
- while ((entry = AST_LIST_REMOVE_HEAD(&columns, list)))
+ AST_RWLIST_WRLOCK(&columns);
+ while ((entry = AST_RWLIST_REMOVE_HEAD(&columns, list))) {
ast_free(entry);
+ }
+ AST_RWLIST_UNLOCK(&columns);
dbport = 0;
ast_cdr_unregister(name);
@@ -435,6 +411,9 @@
struct column *entry;
char *temp;
struct ast_str *compat;
+ MYSQL_ROW row;
+ MYSQL_RES *result;
+ char sqldesc[128];
#if MYSQL_VERSION_ID >= 50013
my_bool my_bool_true = 1;
#endif
@@ -481,23 +460,10 @@
return AST_MODULE_LOAD_FAILURE;
/* Check for any aliases */
- while ((entry = AST_LIST_REMOVE_HEAD(&columns, list)))
+ AST_RWLIST_WRLOCK(&columns);
+ while ((entry = AST_LIST_REMOVE_HEAD(&columns, list))) {
ast_free(entry);
-
- for (var = ast_variable_browse(cfg, "aliases"); var; var = var->next) {
- struct column *entry = ast_calloc(1, sizeof(*entry) + strlen(var->name) + 1 + strlen(var->value) + 1);
- if (!entry)
- continue;
- entry->cdrname = (char *)entry + sizeof(*entry);
- entry->name = (char *)entry + sizeof(*entry) + strlen(var->name) + 1;
- strcpy(entry->cdrname, var->name);
- strcpy(entry->name, var->value);
-
- AST_LIST_INSERT_TAIL(&columns, entry, list);
- ast_log(LOG_NOTICE, "Found an alias from CDR variable %s to DB column %s\n", entry->cdrname, entry->name);
- }
-
- ast_config_destroy(cfg);
+ }
ast_debug(1, "Got hostname of %s\n", hostname->str);
ast_debug(1, "Got port of %d\n", dbport);
@@ -535,7 +501,70 @@
connected = 1;
records = 0;
connect_time = time(NULL);
- }
+
+ /* Get table description */
+ snprintf(sqldesc, sizeof(sqldesc), "DESC %s", dbtable ? dbtable->str : "cdr");
+ if (mysql_query(&mysql, sqldesc)) {
+ ast_log(LOG_ERROR, "Unable to query table description!! Logging disabled.\n");
+ mysql_close(&mysql);
+ connected = 0;
+ AST_RWLIST_UNLOCK(&columns);
+ ast_config_destroy(cfg);
+ return AST_MODULE_LOAD_SUCCESS;
+ }
+
+ if (!(result = mysql_store_result(&mysql))) {
+ ast_log(LOG_ERROR, "Unable to query table description!! Logging disabled.\n");
+ mysql_close(&mysql);
+ connected = 0;
+ AST_RWLIST_UNLOCK(&columns);
+ ast_config_destroy(cfg);
+ return AST_MODULE_LOAD_SUCCESS;
+ }
+
+ while ((row = mysql_fetch_row(result))) {
+ struct column *entry;
+ int foundalias = 0;
+
+ ast_debug(1, "Got a field '%s' of type '%s'\n", row[0], row[1]);
+ /* Check for an alias */
+ for (var = ast_variable_browse(cfg, "aliases"); var; var = var->next) {
+ if (strcasecmp(var->value, row[0])) {
+ continue;
+ }
+
+ if (!(entry = ast_calloc(1, sizeof(*entry) + strlen(var->name) + 1 + strlen(var->value) + 1 + strlen(row[1]) + 1))) {
+ continue;
+ }
+
+ entry->cdrname = (char *)entry + sizeof(*entry);
+ entry->name = (char *)entry + sizeof(*entry) + strlen(var->name) + 1;
+ entry->type = (char *)entry + sizeof(*entry) + strlen(var->name) + 1 + strlen(var->value) + 1;
+ strcpy(entry->cdrname, var->name);
+ strcpy(entry->name, var->value);
+ strcpy(entry->type, row[1]);
+
+ AST_LIST_INSERT_TAIL(&columns, entry, list);
+ ast_log(LOG_NOTICE, "Found an alias from CDR variable %s to DB column %s, type %s\n", entry->cdrname, entry->name, entry->type);
+ foundalias = 1;
+ break;
+ }
+
+ if (!foundalias && (entry = ast_calloc(1, sizeof(*entry) + strlen(row[0]) + 1 + strlen(row[1]) + 1))) {
+ entry->cdrname = (char *)entry + sizeof(*entry);
+ entry->name = (char *)entry + sizeof(*entry);
+ entry->type = (char *)entry + sizeof(*entry) + strlen(row[0]) + 1;
+ strcpy(entry->name, row[0]);
+ strcpy(entry->type, row[1]);
+
+ AST_LIST_INSERT_TAIL(&columns, entry, list);
+ ast_log(LOG_NOTICE, "Found a DB column %s, type %s\n", entry->name, entry->type);
+ }
+ }
+ mysql_free_result(result);
+ }
+ AST_RWLIST_UNLOCK(&columns);
+ ast_config_destroy(cfg);
res = ast_cdr_register(name, desc, mysql_log);
if (res) {
More information about the asterisk-addons-commits
mailing list