mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-02 11:58:40 +00:00
Merge ast_str_opaque branch (discontinue usage of ast_str internals)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@163991 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -317,8 +317,8 @@ static SQLHSTMT generic_prepare(struct odbc_obj *obj, void *data)
|
||||
#define LENGTHEN_BUF1(size) \
|
||||
do { \
|
||||
/* Lengthen buffer, if necessary */ \
|
||||
if (sql->used + size + 1 > sql->len) { \
|
||||
if (ast_str_make_space(&sql, ((sql->len + size + 1) / 512 + 1) * 512) != 0) { \
|
||||
if (ast_str_strlen(sql) + size + 1 > ast_str_size(sql)) { \
|
||||
if (ast_str_make_space(&sql, ((ast_str_size(sql) + size + 1) / 512 + 1) * 512) != 0) { \
|
||||
ast_log(LOG_ERROR, "Unable to allocate sufficient memory. Insert CDR '%s:%s' failed.\n", tableptr->connection, tableptr->table); \
|
||||
ast_free(sql); \
|
||||
ast_free(sql2); \
|
||||
@@ -330,8 +330,8 @@ static SQLHSTMT generic_prepare(struct odbc_obj *obj, void *data)
|
||||
|
||||
#define LENGTHEN_BUF2(size) \
|
||||
do { \
|
||||
if (sql2->used + size + 1 > sql2->len) { \
|
||||
if (ast_str_make_space(&sql2, ((sql2->len + size + 3) / 512 + 1) * 512) != 0) { \
|
||||
if (ast_str_strlen(sql2) + size + 1 > ast_str_size(sql2)) { \
|
||||
if (ast_str_make_space(&sql2, ((ast_str_size(sql2) + size + 3) / 512 + 1) * 512) != 0) { \
|
||||
ast_log(LOG_ERROR, "Unable to allocate sufficient memory. Insert CDR '%s:%s' failed.\n", tableptr->connection, tableptr->table); \
|
||||
ast_free(sql); \
|
||||
ast_free(sql2); \
|
||||
@@ -368,12 +368,13 @@ static int odbc_log(struct ast_cdr *cdr)
|
||||
}
|
||||
|
||||
AST_LIST_TRAVERSE(&odbc_tables, tableptr, list) {
|
||||
int first = 1;
|
||||
ast_str_set(&sql, 0, "INSERT INTO %s (", tableptr->table);
|
||||
ast_str_set(&sql2, 0, " VALUES (");
|
||||
|
||||
/* No need to check the connection now; we'll handle any failure in prepare_and_execute */
|
||||
if (!(obj = ast_odbc_request_obj(tableptr->connection, 0))) {
|
||||
ast_log(LOG_WARNING, "cdr_adaptive_odbc: Unable to retrieve database handle for '%s:%s'. CDR failed: %s\n", tableptr->connection, tableptr->table, sql->str);
|
||||
ast_log(LOG_WARNING, "cdr_adaptive_odbc: Unable to retrieve database handle for '%s:%s'. CDR failed: %s\n", tableptr->connection, tableptr->table, ast_str_buffer(sql));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -442,11 +443,11 @@ static int odbc_log(struct ast_cdr *cdr)
|
||||
}
|
||||
}
|
||||
|
||||
ast_str_append(&sql, 0, "%s,", entry->name);
|
||||
ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
|
||||
LENGTHEN_BUF2(strlen(colptr));
|
||||
|
||||
/* Encode value, with escaping */
|
||||
ast_str_append(&sql2, 0, "'");
|
||||
ast_str_append(&sql2, 0, "%s'", first ? "" : ",");
|
||||
for (tmp = colptr; *tmp; tmp++) {
|
||||
if (*tmp == '\'') {
|
||||
ast_str_append(&sql2, 0, "''");
|
||||
@@ -456,7 +457,7 @@ static int odbc_log(struct ast_cdr *cdr)
|
||||
ast_str_append(&sql2, 0, "%c", *tmp);
|
||||
}
|
||||
}
|
||||
ast_str_append(&sql2, 0, "',");
|
||||
ast_str_append(&sql2, 0, "'");
|
||||
break;
|
||||
case SQL_TYPE_DATE:
|
||||
{
|
||||
@@ -469,16 +470,16 @@ static int odbc_log(struct ast_cdr *cdr)
|
||||
(month == 2 && year % 4 == 0 && day > 29) ||
|
||||
(month == 2 && year % 4 != 0 && day > 28)) {
|
||||
ast_log(LOG_WARNING, "CDR variable %s is not a valid date ('%s').\n", entry->name, colptr);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (year > 0 && year < 100) {
|
||||
year += 2000;
|
||||
}
|
||||
|
||||
ast_str_append(&sql, 0, "%s,", entry->name);
|
||||
ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
|
||||
LENGTHEN_BUF2(17);
|
||||
ast_str_append(&sql2, 0, "{ d '%04d-%02d-%02d' },", year, month, day);
|
||||
ast_str_append(&sql2, 0, "%s{ d '%04d-%02d-%02d' }", first ? "" : ",", year, month, day);
|
||||
}
|
||||
break;
|
||||
case SQL_TYPE_TIME:
|
||||
@@ -488,12 +489,12 @@ static int odbc_log(struct ast_cdr *cdr)
|
||||
|
||||
if ((count != 2 && count != 3) || hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 59) {
|
||||
ast_log(LOG_WARNING, "CDR variable %s is not a valid time ('%s').\n", entry->name, colptr);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
ast_str_append(&sql, 0, "%s,", entry->name);
|
||||
ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
|
||||
LENGTHEN_BUF2(15);
|
||||
ast_str_append(&sql2, 0, "{ t '%02d:%02d:%02d' },", hour, minute, second);
|
||||
ast_str_append(&sql2, 0, "%s{ t '%02d:%02d:%02d' }", first ? "" : ",", hour, minute, second);
|
||||
}
|
||||
break;
|
||||
case SQL_TYPE_TIMESTAMP:
|
||||
@@ -511,16 +512,16 @@ static int odbc_log(struct ast_cdr *cdr)
|
||||
(month == 2 && year % 4 != 0 && day > 28) ||
|
||||
hour > 23 || minute > 59 || second > 59 || hour < 0 || minute < 0 || second < 0) {
|
||||
ast_log(LOG_WARNING, "CDR variable %s is not a valid timestamp ('%s').\n", entry->name, colptr);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (year > 0 && year < 100) {
|
||||
year += 2000;
|
||||
}
|
||||
|
||||
ast_str_append(&sql, 0, "%s,", entry->name);
|
||||
ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
|
||||
LENGTHEN_BUF2(26);
|
||||
ast_str_append(&sql2, 0, "{ ts '%04d-%02d-%02d %02d:%02d:%02d' },", year, month, day, hour, minute, second);
|
||||
ast_str_append(&sql2, 0, "%s{ ts '%04d-%02d-%02d %02d:%02d:%02d' }", first ? "" : ",", year, month, day, hour, minute, second);
|
||||
}
|
||||
break;
|
||||
case SQL_INTEGER:
|
||||
@@ -528,12 +529,12 @@ static int odbc_log(struct ast_cdr *cdr)
|
||||
int integer = 0;
|
||||
if (sscanf(colptr, "%d", &integer) != 1) {
|
||||
ast_log(LOG_WARNING, "CDR variable %s is not an integer.\n", entry->name);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
ast_str_append(&sql, 0, "%s,", entry->name);
|
||||
ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
|
||||
LENGTHEN_BUF2(12);
|
||||
ast_str_append(&sql2, 0, "%d,", integer);
|
||||
ast_str_append(&sql2, 0, "%s%d", first ? "" : ",", integer);
|
||||
}
|
||||
break;
|
||||
case SQL_BIGINT:
|
||||
@@ -541,12 +542,12 @@ static int odbc_log(struct ast_cdr *cdr)
|
||||
long long integer = 0;
|
||||
if (sscanf(colptr, "%lld", &integer) != 1) {
|
||||
ast_log(LOG_WARNING, "CDR variable %s is not an integer.\n", entry->name);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
ast_str_append(&sql, 0, "%s,", entry->name);
|
||||
ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
|
||||
LENGTHEN_BUF2(24);
|
||||
ast_str_append(&sql2, 0, "%lld,", integer);
|
||||
ast_str_append(&sql2, 0, "%s%lld", first ? "" : ",", integer);
|
||||
}
|
||||
break;
|
||||
case SQL_SMALLINT:
|
||||
@@ -554,12 +555,12 @@ static int odbc_log(struct ast_cdr *cdr)
|
||||
short integer = 0;
|
||||
if (sscanf(colptr, "%hd", &integer) != 1) {
|
||||
ast_log(LOG_WARNING, "CDR variable %s is not an integer.\n", entry->name);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
ast_str_append(&sql, 0, "%s,", entry->name);
|
||||
ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
|
||||
LENGTHEN_BUF2(6);
|
||||
ast_str_append(&sql2, 0, "%d,", integer);
|
||||
ast_str_append(&sql2, 0, "%s%d", first ? "" : ",", integer);
|
||||
}
|
||||
break;
|
||||
case SQL_TINYINT:
|
||||
@@ -567,12 +568,12 @@ static int odbc_log(struct ast_cdr *cdr)
|
||||
char integer = 0;
|
||||
if (sscanf(colptr, "%hhd", &integer) != 1) {
|
||||
ast_log(LOG_WARNING, "CDR variable %s is not an integer.\n", entry->name);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
ast_str_append(&sql, 0, "%s,", entry->name);
|
||||
ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
|
||||
LENGTHEN_BUF2(4);
|
||||
ast_str_append(&sql2, 0, "%d,", integer);
|
||||
ast_str_append(&sql2, 0, "%s%d", first ? "" : ",", integer);
|
||||
}
|
||||
break;
|
||||
case SQL_BIT:
|
||||
@@ -580,14 +581,14 @@ static int odbc_log(struct ast_cdr *cdr)
|
||||
char integer = 0;
|
||||
if (sscanf(colptr, "%hhd", &integer) != 1) {
|
||||
ast_log(LOG_WARNING, "CDR variable %s is not an integer.\n", entry->name);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (integer != 0)
|
||||
integer = 1;
|
||||
|
||||
ast_str_append(&sql, 0, "%s,", entry->name);
|
||||
ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
|
||||
LENGTHEN_BUF2(2);
|
||||
ast_str_append(&sql2, 0, "%d,", integer);
|
||||
ast_str_append(&sql2, 0, "%s%d", first ? "" : ",", integer);
|
||||
}
|
||||
break;
|
||||
case SQL_NUMERIC:
|
||||
@@ -596,12 +597,12 @@ static int odbc_log(struct ast_cdr *cdr)
|
||||
double number = 0.0;
|
||||
if (sscanf(colptr, "%lf", &number) != 1) {
|
||||
ast_log(LOG_WARNING, "CDR variable %s is not an numeric type.\n", entry->name);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
ast_str_append(&sql, 0, "%s,", entry->name);
|
||||
ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
|
||||
LENGTHEN_BUF2(entry->decimals);
|
||||
ast_str_append(&sql2, 0, "%*.*lf,", entry->decimals, entry->radix, number);
|
||||
ast_str_append(&sql2, 0, "%s%*.*lf", first ? "" : ",", entry->decimals, entry->radix, number);
|
||||
}
|
||||
break;
|
||||
case SQL_FLOAT:
|
||||
@@ -611,35 +612,37 @@ static int odbc_log(struct ast_cdr *cdr)
|
||||
double number = 0.0;
|
||||
if (sscanf(colptr, "%lf", &number) != 1) {
|
||||
ast_log(LOG_WARNING, "CDR variable %s is not an numeric type.\n", entry->name);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
ast_str_append(&sql, 0, "%s,", entry->name);
|
||||
ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
|
||||
LENGTHEN_BUF2(entry->decimals);
|
||||
ast_str_append(&sql2, 0, "%lf,", number);
|
||||
ast_str_append(&sql2, 0, "%s%lf", first ? "" : ",", number);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ast_log(LOG_WARNING, "Column type %d (field '%s:%s:%s') is unsupported at this time.\n", entry->type, tableptr->connection, tableptr->table, entry->name);
|
||||
continue;
|
||||
}
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Concatenate the two constructed buffers */
|
||||
LENGTHEN_BUF1(sql2->used);
|
||||
sql->str[sql->used - 1] = ')';
|
||||
sql2->str[sql2->used - 1] = ')';
|
||||
ast_str_append(&sql, 0, "%s", sql2->str);
|
||||
LENGTHEN_BUF1(ast_str_strlen(sql2));
|
||||
ast_str_append(&sql, 0, ")");
|
||||
ast_str_append(&sql2, 0, ")");
|
||||
ast_str_append(&sql, 0, "%s", ast_str_buffer(sql2));
|
||||
|
||||
ast_verb(11, "[%s]\n", sql->str);
|
||||
ast_verb(11, "[%s]\n", ast_str_buffer(sql));
|
||||
|
||||
stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, sql->str);
|
||||
stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, ast_str_buffer(sql));
|
||||
if (stmt) {
|
||||
SQLRowCount(stmt, &rows);
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||
}
|
||||
if (rows == 0) {
|
||||
ast_log(LOG_WARNING, "cdr_adaptive_odbc: Insert failed on '%s:%s'. CDR failed: %s\n", tableptr->connection, tableptr->table, sql->str);
|
||||
ast_log(LOG_WARNING, "cdr_adaptive_odbc: Insert failed on '%s:%s'. CDR failed: %s\n", tableptr->connection, tableptr->table, ast_str_buffer(sql));
|
||||
}
|
||||
early_release:
|
||||
ast_odbc_release_obj(obj);
|
||||
@@ -647,11 +650,11 @@ early_release:
|
||||
AST_RWLIST_UNLOCK(&odbc_tables);
|
||||
|
||||
/* Next time, just allocate buffers that are that big to start with. */
|
||||
if (sql->used > maxsize) {
|
||||
maxsize = sql->used;
|
||||
if (ast_str_strlen(sql) > maxsize) {
|
||||
maxsize = ast_str_strlen(sql);
|
||||
}
|
||||
if (sql2->used > maxsize2) {
|
||||
maxsize2 = sql2->used;
|
||||
if (ast_str_strlen(sql2) > maxsize2) {
|
||||
maxsize2 = ast_str_strlen(sql2);
|
||||
}
|
||||
|
||||
ast_free(sql);
|
||||
|
||||
@@ -95,7 +95,7 @@ static int load_config(int reload)
|
||||
v = ast_variable_browse(cfg, cat);
|
||||
while (v) {
|
||||
if (customfields && !ast_strlen_zero(v->name) && !ast_strlen_zero(v->value)) {
|
||||
if( (customfields->used + strlen(v->value) + strlen(v->name) + 14) < customfields->len) {
|
||||
if ((ast_str_strlen(customfields) + strlen(v->value) + strlen(v->name) + 14) < ast_str_size(customfields)) {
|
||||
ast_str_append(&customfields, -1, "%s: ${CDR(%s)}\r\n", v->value, v->name);
|
||||
ast_log(LOG_NOTICE, "Added mapping %s: ${CDR(%s)}\n", v->value, v->name);
|
||||
} else {
|
||||
@@ -145,10 +145,10 @@ static int manager_log(struct ast_cdr *cdr)
|
||||
|
||||
buf[0] = 0;
|
||||
/* Custom fields handling */
|
||||
if (customfields != NULL && customfields->used > 0) {
|
||||
if (customfields != NULL && ast_str_strlen(customfields)) {
|
||||
memset(&dummy, 0, sizeof(dummy));
|
||||
dummy.cdr = cdr;
|
||||
pbx_substitute_variables_helper(&dummy, customfields->str, buf, sizeof(buf) - 1);
|
||||
pbx_substitute_variables_helper(&dummy, ast_str_buffer(customfields), buf, sizeof(buf) - 1);
|
||||
}
|
||||
|
||||
manager_event(EVENT_FLAG_CDR, "Cdr",
|
||||
|
||||
143
cdr/cdr_pgsql.c
143
cdr/cdr_pgsql.c
@@ -73,31 +73,31 @@ struct columns {
|
||||
|
||||
static AST_RWLIST_HEAD_STATIC(psql_columns, columns);
|
||||
|
||||
#define LENGTHEN_BUF1(size) \
|
||||
do { \
|
||||
/* Lengthen buffer, if necessary */ \
|
||||
if (sql->used + size + 1 > sql->len) { \
|
||||
if (ast_str_make_space(&sql, ((sql->len + size + 1) / 512 + 1) * 512) != 0) { \
|
||||
#define LENGTHEN_BUF1(size) \
|
||||
do { \
|
||||
/* Lengthen buffer, if necessary */ \
|
||||
if (ast_str_strlen(sql) + size + 1 > ast_str_size(sql)) { \
|
||||
if (ast_str_make_space(&sql, ((ast_str_size(sql) + size + 3) / 512 + 1) * 512) != 0) { \
|
||||
ast_log(LOG_ERROR, "Unable to allocate sufficient memory. Insert CDR failed.\n"); \
|
||||
ast_free(sql); \
|
||||
ast_free(sql2); \
|
||||
AST_RWLIST_UNLOCK(&psql_columns); \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
ast_free(sql); \
|
||||
ast_free(sql2); \
|
||||
AST_RWLIST_UNLOCK(&psql_columns); \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LENGTHEN_BUF2(size) \
|
||||
do { \
|
||||
if (sql2->used + size + 1 > sql2->len) { \
|
||||
if (ast_str_make_space(&sql2, ((sql2->len + size + 3) / 512 + 1) * 512) != 0) { \
|
||||
#define LENGTHEN_BUF2(size) \
|
||||
do { \
|
||||
if (ast_str_strlen(sql2) + size + 1 > ast_str_size(sql2)) { \
|
||||
if (ast_str_make_space(&sql2, ((ast_str_size(sql2) + size + 3) / 512 + 1) * 512) != 0) { \
|
||||
ast_log(LOG_ERROR, "Unable to allocate sufficient memory. Insert CDR failed.\n"); \
|
||||
ast_free(sql); \
|
||||
ast_free(sql2); \
|
||||
AST_RWLIST_UNLOCK(&psql_columns); \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
ast_free(sql); \
|
||||
ast_free(sql2); \
|
||||
AST_RWLIST_UNLOCK(&psql_columns); \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int pgsql_log(struct ast_cdr *cdr)
|
||||
@@ -125,7 +125,8 @@ static int pgsql_log(struct ast_cdr *cdr)
|
||||
struct columns *cur;
|
||||
struct ast_str *sql = ast_str_create(maxsize), *sql2 = ast_str_create(maxsize2);
|
||||
char buf[257], escapebuf[513], *value;
|
||||
|
||||
int first = 1;
|
||||
|
||||
if (!sql || !sql2) {
|
||||
if (sql) {
|
||||
ast_free(sql);
|
||||
@@ -150,85 +151,86 @@ static int pgsql_log(struct ast_cdr *cdr)
|
||||
if (cur->notnull && !cur->hasdefault) {
|
||||
/* Field is NOT NULL (but no default), must include it anyway */
|
||||
LENGTHEN_BUF1(strlen(cur->name) + 2);
|
||||
ast_str_append(&sql, 0, "\"%s\",", cur->name);
|
||||
ast_str_append(&sql, 0, "%s\"%s\"", first ? "" : ",", cur->name);
|
||||
LENGTHEN_BUF2(3);
|
||||
ast_str_append(&sql2, 0, "'',");
|
||||
ast_str_append(&sql2, 0, "%s''", first ? "" : ",");
|
||||
first = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
LENGTHEN_BUF1(strlen(cur->name) + 2);
|
||||
ast_str_append(&sql, 0, "\"%s\",", cur->name);
|
||||
ast_str_append(&sql, 0, "%s\"%s\"", first ? "" : ",", cur->name);
|
||||
|
||||
if (strcmp(cur->name, "start") == 0 || strcmp(cur->name, "calldate") == 0) {
|
||||
if (strncmp(cur->type, "int", 3) == 0) {
|
||||
LENGTHEN_BUF2(12);
|
||||
ast_str_append(&sql2, 0, "%ld", cdr->start.tv_sec);
|
||||
LENGTHEN_BUF2(13);
|
||||
ast_str_append(&sql2, 0, "%s%ld", first ? "" : ",", cdr->start.tv_sec);
|
||||
} else if (strncmp(cur->type, "float", 5) == 0) {
|
||||
LENGTHEN_BUF2(30);
|
||||
ast_str_append(&sql2, 0, "%f", (double)cdr->start.tv_sec + (double)cdr->start.tv_usec / 1000000.0);
|
||||
LENGTHEN_BUF2(31);
|
||||
ast_str_append(&sql2, 0, "%s%f", first ? "" : ",", (double)cdr->start.tv_sec + (double)cdr->start.tv_usec / 1000000.0);
|
||||
} else {
|
||||
/* char, hopefully */
|
||||
LENGTHEN_BUF2(30);
|
||||
LENGTHEN_BUF2(31);
|
||||
ast_localtime(&cdr->start, &tm, NULL);
|
||||
ast_strftime(buf, sizeof(buf), DATE_FORMAT, &tm);
|
||||
ast_str_append(&sql2, 0, "%s", buf);
|
||||
ast_str_append(&sql2, 0, "%s%s", first ? "" : ",", buf);
|
||||
}
|
||||
} else if (strcmp(cur->name, "answer") == 0) {
|
||||
if (strncmp(cur->type, "int", 3) == 0) {
|
||||
LENGTHEN_BUF2(12);
|
||||
ast_str_append(&sql2, 0, "%ld", cdr->answer.tv_sec);
|
||||
LENGTHEN_BUF2(13);
|
||||
ast_str_append(&sql2, 0, "%s%ld", first ? "" : ",", cdr->answer.tv_sec);
|
||||
} else if (strncmp(cur->type, "float", 5) == 0) {
|
||||
LENGTHEN_BUF2(30);
|
||||
ast_str_append(&sql2, 0, "%f", (double)cdr->answer.tv_sec + (double)cdr->answer.tv_usec / 1000000.0);
|
||||
LENGTHEN_BUF2(31);
|
||||
ast_str_append(&sql2, 0, "%s%f", first ? "" : ",", (double)cdr->answer.tv_sec + (double)cdr->answer.tv_usec / 1000000.0);
|
||||
} else {
|
||||
/* char, hopefully */
|
||||
LENGTHEN_BUF2(30);
|
||||
LENGTHEN_BUF2(31);
|
||||
ast_localtime(&cdr->start, &tm, NULL);
|
||||
ast_strftime(buf, sizeof(buf), DATE_FORMAT, &tm);
|
||||
ast_str_append(&sql2, 0, "%s", buf);
|
||||
ast_str_append(&sql2, 0, "%s%s", first ? "" : ",", buf);
|
||||
}
|
||||
} else if (strcmp(cur->name, "end") == 0) {
|
||||
if (strncmp(cur->type, "int", 3) == 0) {
|
||||
LENGTHEN_BUF2(12);
|
||||
ast_str_append(&sql2, 0, "%ld", cdr->end.tv_sec);
|
||||
LENGTHEN_BUF2(13);
|
||||
ast_str_append(&sql2, 0, "%s%ld", first ? "" : ",", cdr->end.tv_sec);
|
||||
} else if (strncmp(cur->type, "float", 5) == 0) {
|
||||
LENGTHEN_BUF2(30);
|
||||
ast_str_append(&sql2, 0, "%f", (double)cdr->end.tv_sec + (double)cdr->end.tv_usec / 1000000.0);
|
||||
LENGTHEN_BUF2(31);
|
||||
ast_str_append(&sql2, 0, "%s%f", first ? "" : ",", (double)cdr->end.tv_sec + (double)cdr->end.tv_usec / 1000000.0);
|
||||
} else {
|
||||
/* char, hopefully */
|
||||
LENGTHEN_BUF2(30);
|
||||
LENGTHEN_BUF2(31);
|
||||
ast_localtime(&cdr->end, &tm, NULL);
|
||||
ast_strftime(buf, sizeof(buf), DATE_FORMAT, &tm);
|
||||
ast_str_append(&sql2, 0, "%s", buf);
|
||||
ast_str_append(&sql2, 0, "%s%s", first ? "" : ",", buf);
|
||||
}
|
||||
} else if (strcmp(cur->name, "duration") == 0 || strcmp(cur->name, "billsec") == 0) {
|
||||
if (cur->type[0] == 'i') {
|
||||
/* Get integer, no need to escape anything */
|
||||
ast_cdr_getvar(cdr, cur->name, &value, buf, sizeof(buf), 0, 0);
|
||||
LENGTHEN_BUF2(12);
|
||||
ast_str_append(&sql2, 0, "%s", value);
|
||||
LENGTHEN_BUF2(13);
|
||||
ast_str_append(&sql2, 0, "%s%s", first ? "" : ",", value);
|
||||
} else if (strncmp(cur->type, "float", 5) == 0) {
|
||||
struct timeval *when = cur->name[0] == 'd' ? &cdr->start : &cdr->answer;
|
||||
LENGTHEN_BUF2(30);
|
||||
ast_str_append(&sql2, 0, "%f", (double)cdr->end.tv_sec - when->tv_sec + cdr->end.tv_usec / 1000000.0 - when->tv_usec / 1000000.0);
|
||||
LENGTHEN_BUF2(31);
|
||||
ast_str_append(&sql2, 0, "%s%f", first ? "" : ",", (double)cdr->end.tv_sec - when->tv_sec + cdr->end.tv_usec / 1000000.0 - when->tv_usec / 1000000.0);
|
||||
} else {
|
||||
/* Char field, probably */
|
||||
struct timeval *when = cur->name[0] == 'd' ? &cdr->start : &cdr->answer;
|
||||
LENGTHEN_BUF2(30);
|
||||
ast_str_append(&sql2, 0, "'%f'", (double)cdr->end.tv_sec - when->tv_sec + cdr->end.tv_usec / 1000000.0 - when->tv_usec / 1000000.0);
|
||||
LENGTHEN_BUF2(31);
|
||||
ast_str_append(&sql2, 0, "%s'%f'", first ? "" : ",", (double)cdr->end.tv_sec - when->tv_sec + cdr->end.tv_usec / 1000000.0 - when->tv_usec / 1000000.0);
|
||||
}
|
||||
} else if (strcmp(cur->name, "disposition") == 0 || strcmp(cur->name, "amaflags") == 0) {
|
||||
if (strncmp(cur->type, "int", 3) == 0) {
|
||||
/* Integer, no need to escape anything */
|
||||
ast_cdr_getvar(cdr, cur->name, &value, buf, sizeof(buf), 0, 1);
|
||||
LENGTHEN_BUF2(12);
|
||||
ast_str_append(&sql2, 0, "%s", value);
|
||||
LENGTHEN_BUF2(13);
|
||||
ast_str_append(&sql2, 0, "%s%s", first ? "" : ",", value);
|
||||
} else {
|
||||
/* Although this is a char field, there are no special characters in the values for these fields */
|
||||
ast_cdr_getvar(cdr, cur->name, &value, buf, sizeof(buf), 0, 0);
|
||||
LENGTHEN_BUF2(30);
|
||||
ast_str_append(&sql2, 0, "'%s'", value);
|
||||
LENGTHEN_BUF2(31);
|
||||
ast_str_append(&sql2, 0, "%s'%s'", first ? "" : ",", value);
|
||||
}
|
||||
} else {
|
||||
/* Arbitrary field, could be anything */
|
||||
@@ -236,20 +238,20 @@ static int pgsql_log(struct ast_cdr *cdr)
|
||||
if (strncmp(cur->type, "int", 3) == 0) {
|
||||
long long whatever;
|
||||
if (value && sscanf(value, "%lld", &whatever) == 1) {
|
||||
LENGTHEN_BUF2(25);
|
||||
ast_str_append(&sql2, 0, "%lld", whatever);
|
||||
LENGTHEN_BUF2(26);
|
||||
ast_str_append(&sql2, 0, "%s%lld", first ? "" : ",", whatever);
|
||||
} else {
|
||||
LENGTHEN_BUF2(1);
|
||||
ast_str_append(&sql2, 0, "0");
|
||||
LENGTHEN_BUF2(2);
|
||||
ast_str_append(&sql2, 0, "%s0", first ? "" : ",");
|
||||
}
|
||||
} else if (strncmp(cur->type, "float", 5) == 0) {
|
||||
long double whatever;
|
||||
if (value && sscanf(value, "%Lf", &whatever) == 1) {
|
||||
LENGTHEN_BUF2(50);
|
||||
ast_str_append(&sql2, 0, "%30Lf", whatever);
|
||||
LENGTHEN_BUF2(51);
|
||||
ast_str_append(&sql2, 0, "%s%30Lf", first ? "" : ",", whatever);
|
||||
} else {
|
||||
LENGTHEN_BUF2(1);
|
||||
ast_str_append(&sql2, 0, "0");
|
||||
LENGTHEN_BUF2(2);
|
||||
ast_str_append(&sql2, 0, "%s0", first ? "" : ",");
|
||||
}
|
||||
/* XXX Might want to handle dates, times, and other misc fields here XXX */
|
||||
} else {
|
||||
@@ -257,19 +259,16 @@ static int pgsql_log(struct ast_cdr *cdr)
|
||||
PQescapeStringConn(conn, escapebuf, value, strlen(value), NULL);
|
||||
else
|
||||
escapebuf[0] = '\0';
|
||||
LENGTHEN_BUF2(strlen(escapebuf) + 2);
|
||||
ast_str_append(&sql2, 0, "'%s'", escapebuf);
|
||||
LENGTHEN_BUF2(strlen(escapebuf) + 3);
|
||||
ast_str_append(&sql2, 0, "%s'%s'", first ? "" : ",", escapebuf);
|
||||
}
|
||||
}
|
||||
LENGTHEN_BUF2(1);
|
||||
ast_str_append(&sql2, 0, ",");
|
||||
first = 0;
|
||||
}
|
||||
AST_RWLIST_UNLOCK(&psql_columns);
|
||||
LENGTHEN_BUF1(sql2->len);
|
||||
sql->str[sql->used - 1] = ')';
|
||||
sql2->str[sql2->used - 1] = ')';
|
||||
ast_str_append(&sql, 0, "%s", sql2->str);
|
||||
ast_verb(11, "[%s]\n", sql->str);
|
||||
LENGTHEN_BUF1(ast_str_strlen(sql2) + 2);
|
||||
ast_str_append(&sql, 0, ")%s)", ast_str_buffer(sql2));
|
||||
ast_verb(11, "[%s]\n", ast_str_buffer(sql));
|
||||
|
||||
ast_debug(2, "inserting a CDR record.\n");
|
||||
|
||||
@@ -297,7 +296,7 @@ static int pgsql_log(struct ast_cdr *cdr)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
result = PQexec(conn, sql->str);
|
||||
result = PQexec(conn, ast_str_buffer(sql));
|
||||
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
|
||||
pgerror = PQresultErrorMessage(result);
|
||||
ast_log(LOG_ERROR, "Failed to insert call detail record into database!\n");
|
||||
@@ -308,7 +307,7 @@ static int pgsql_log(struct ast_cdr *cdr)
|
||||
ast_log(LOG_ERROR, "Connection reestablished.\n");
|
||||
connected = 1;
|
||||
PQclear(result);
|
||||
result = PQexec(conn, sql->str);
|
||||
result = PQexec(conn, ast_str_buffer(sql));
|
||||
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
|
||||
pgerror = PQresultErrorMessage(result);
|
||||
ast_log(LOG_ERROR, "HARD ERROR! Attempted reconnection failed. DROPPING CALL RECORD!\n");
|
||||
|
||||
@@ -101,13 +101,10 @@ static int load_column_config(const char *tmp)
|
||||
ast_free(save);
|
||||
return -1;
|
||||
}
|
||||
if (!column_string->used)
|
||||
ast_str_set(&column_string, 0, "%s", escaped);
|
||||
else
|
||||
ast_str_append(&column_string, 0, ",%s", escaped);
|
||||
ast_str_append(&column_string, 0, "%s%s", ast_str_strlen(column_string) ? "," : "", escaped);
|
||||
sqlite3_free(escaped);
|
||||
}
|
||||
if (!(columns = ast_strdup(column_string->str))) {
|
||||
if (!(columns = ast_strdup(ast_str_buffer(column_string)))) {
|
||||
ast_log(LOG_ERROR, "Out of memory copying columns string for table '%s.'\n", table);
|
||||
ast_free(column_string);
|
||||
ast_free(save);
|
||||
@@ -158,17 +155,16 @@ static int load_config(int reload)
|
||||
struct ast_variable *mappingvar;
|
||||
const char *tmp;
|
||||
|
||||
if (!(cfg = ast_config_load(config_file, config_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
|
||||
if (reload)
|
||||
ast_log(LOG_WARNING, "Failed to reload configuration file.\n");
|
||||
else
|
||||
ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
|
||||
if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
|
||||
ast_log(LOG_WARNING, "Failed to %sload configuration file. %s\n", reload ? "re" : "", reload ? "" : "Module not activated.");
|
||||
return -1;
|
||||
} else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
|
||||
} else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (reload)
|
||||
if (reload) {
|
||||
free_config();
|
||||
}
|
||||
|
||||
ast_mutex_lock(&lock);
|
||||
|
||||
@@ -180,17 +176,15 @@ static int load_config(int reload)
|
||||
}
|
||||
|
||||
/* Mapping must have a table name */
|
||||
tmp = ast_variable_retrieve(cfg, "master", "table");
|
||||
if (!ast_strlen_zero(tmp))
|
||||
if (!ast_strlen_zero(tmp = ast_variable_retrieve(cfg, "master", "table"))) {
|
||||
ast_copy_string(table, tmp, sizeof(table));
|
||||
else {
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Table name not specified. Assuming cdr.\n");
|
||||
strcpy(table, "cdr");
|
||||
}
|
||||
|
||||
/* Columns */
|
||||
tmp = ast_variable_retrieve(cfg, "master", "columns");
|
||||
if (load_column_config(tmp)) {
|
||||
if (load_column_config(ast_variable_retrieve(cfg, "master", "columns"))) {
|
||||
ast_mutex_unlock(&lock);
|
||||
ast_config_destroy(cfg);
|
||||
free_config();
|
||||
@@ -198,8 +192,7 @@ static int load_config(int reload)
|
||||
}
|
||||
|
||||
/* Values */
|
||||
tmp = ast_variable_retrieve(cfg, "master", "values");
|
||||
if (load_values_config(tmp)) {
|
||||
if (load_values_config(ast_variable_retrieve(cfg, "master", "values"))) {
|
||||
ast_mutex_unlock(&lock);
|
||||
ast_config_destroy(cfg);
|
||||
free_config();
|
||||
@@ -230,8 +223,9 @@ static int free_config(void)
|
||||
columns = NULL;
|
||||
}
|
||||
|
||||
while ((value = AST_LIST_REMOVE_HEAD(&sql_values, list)))
|
||||
while ((value = AST_LIST_REMOVE_HEAD(&sql_values, list))) {
|
||||
ast_free(value);
|
||||
}
|
||||
|
||||
ast_mutex_unlock(&lock);
|
||||
|
||||
@@ -253,16 +247,12 @@ static int sqlite3_log(struct ast_cdr *cdr)
|
||||
struct ast_str *value_string = ast_str_create(1024);
|
||||
dummy.cdr = cdr;
|
||||
AST_LIST_TRAVERSE(&sql_values, value, list) {
|
||||
memset(subst_buf, 0, sizeof(subst_buf));
|
||||
pbx_substitute_variables_helper(&dummy, value->expression, subst_buf, sizeof(subst_buf) - 1);
|
||||
escaped = sqlite3_mprintf("%q", subst_buf);
|
||||
if (!value_string->used)
|
||||
ast_str_append(&value_string, 0, "'%s'", escaped);
|
||||
else
|
||||
ast_str_append(&value_string, 0, ",'%s'", escaped);
|
||||
ast_str_append(&value_string, 0, "%s'%s'", ast_str_strlen(value_string) ? "," : "", escaped);
|
||||
sqlite3_free(escaped);
|
||||
}
|
||||
sql = sqlite3_mprintf("INSERT INTO %q (%s) VALUES (%s)", table, columns, value_string->str);
|
||||
sql = sqlite3_mprintf("INSERT INTO %q (%s) VALUES (%s)", table, columns, ast_str_buffer(value_string));
|
||||
ast_debug(1, "About to log: %s\n", sql);
|
||||
ast_free(value_string);
|
||||
}
|
||||
@@ -272,8 +262,9 @@ static int sqlite3_log(struct ast_cdr *cdr)
|
||||
/* XXX This seems awful arbitrary... */
|
||||
for (count = 0; count < 5; count++) {
|
||||
res = sqlite3_exec(db, sql, NULL, NULL, &error);
|
||||
if (res != SQLITE_BUSY && res != SQLITE_LOCKED)
|
||||
if (res != SQLITE_BUSY && res != SQLITE_LOCKED) {
|
||||
break;
|
||||
}
|
||||
usleep(200);
|
||||
}
|
||||
|
||||
@@ -282,8 +273,9 @@ static int sqlite3_log(struct ast_cdr *cdr)
|
||||
sqlite3_free(error);
|
||||
}
|
||||
|
||||
if (sql)
|
||||
if (sql) {
|
||||
sqlite3_free(sql);
|
||||
}
|
||||
|
||||
ast_mutex_unlock(&lock);
|
||||
|
||||
@@ -313,8 +305,9 @@ static int load_module(void)
|
||||
free_config();
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
}
|
||||
|
||||
/* is the database there? */
|
||||
snprintf(filename, sizeof(filename), "%s/master.db", ast_config_AST_LOG_DIR);
|
||||
|
||||
Reference in New Issue
Block a user