summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKinsey Moore <kmoore@digium.com>2012-02-03 16:50:49 +0000
committerKinsey Moore <kmoore@digium.com>2012-02-03 16:50:49 +0000
commit71a8457d5379fe04cf8d42db40a24866549a88cb (patch)
treee309aa98c01b73c618c21354d43f10f4d4c48343
parent79979313e84f39198812841ac36a44fa990550df (diff)
Support schema selection in cdr_adaptive_odbc
Asterisk now supports using ODBC with databases where a single schema must be selected. Previously, INSERTs would fail because they did not take into account extra fields cause by having multiple schemas. This also corrects some SQL resource leaks. (closes issue ASTERISK-17106) Patch-by: Alexander Frolkin Patch-by: Tilgnman Lesher git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@353964 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--UPGRADE.txt4
-rw-r--r--cdr/cdr_adaptive_odbc.c28
-rw-r--r--configs/cdr_adaptive_odbc.conf.sample1
3 files changed, 28 insertions, 5 deletions
diff --git a/UPGRADE.txt b/UPGRADE.txt
index 83c2b2b6c..6b53de30e 100644
--- a/UPGRADE.txt
+++ b/UPGRADE.txt
@@ -35,6 +35,10 @@ func_enum:
differentiate between a failed query and a successful query with 0 results
matching the specified type.
+CDR:
+ - cdr_adaptive_odbc now supports specifying a schema so that Asterisk can
+ connect to databases that use schemas.
+
Configuration Files:
- Files listed below have been updated to be more consistent with how Asterisk
parses configuration files. This makes configuration files more consistent
diff --git a/cdr/cdr_adaptive_odbc.c b/cdr/cdr_adaptive_odbc.c
index cb9bd0d52..8d66a133c 100644
--- a/cdr/cdr_adaptive_odbc.c
+++ b/cdr/cdr_adaptive_odbc.c
@@ -72,6 +72,7 @@ struct columns {
struct tables {
char *connection;
char *table;
+ char *schema;
unsigned int usegmtime:1;
AST_LIST_HEAD_NOLOCK(odbc_columns, columns) columns;
AST_RWLIST_ENTRY(tables) list;
@@ -90,7 +91,8 @@ static int load_config(void)
char columnname[80];
char connection[40];
char table[40];
- int lenconnection, lentable, usegmtime = 0;
+ char schema[40];
+ int lenconnection, lentable, lenschema, usegmtime = 0;
SQLLEN sqlptr;
int res = 0;
SQLHSTMT stmt = NULL;
@@ -132,6 +134,12 @@ static int load_config(void)
ast_copy_string(table, tmp, sizeof(table));
lentable = strlen(table);
+ if (ast_strlen_zero(tmp = ast_variable_retrieve(cfg, catg, "schema"))) {
+ tmp = "";
+ }
+ ast_copy_string(schema, tmp, sizeof(schema));
+ lenschema = strlen(schema);
+
res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
ast_log(LOG_WARNING, "SQL Alloc Handle failed on connection '%s'!\n", connection);
@@ -139,16 +147,19 @@ static int load_config(void)
continue;
}
- res = SQLColumns(stmt, NULL, 0, NULL, 0, (unsigned char *)table, SQL_NTS, (unsigned char *)"%", SQL_NTS);
+ res = SQLColumns(stmt, NULL, 0, lenschema == 0 ? NULL : (unsigned char *)schema, SQL_NTS, (unsigned char *)table, SQL_NTS, (unsigned char *)"%", SQL_NTS);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
ast_log(LOG_ERROR, "Unable to query database columns on connection '%s'. Skipping.\n", connection);
+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
ast_odbc_release_obj(obj);
continue;
}
- tableptr = ast_calloc(sizeof(char), sizeof(*tableptr) + lenconnection + 1 + lentable + 1);
+ tableptr = ast_calloc(sizeof(char), sizeof(*tableptr) + lenconnection + 1 + lentable + 1 + lenschema + 1);
if (!tableptr) {
- ast_log(LOG_ERROR, "Out of memory creating entry for table '%s' on connection '%s'\n", table, connection);
+ ast_log(LOG_ERROR, "Out of memory creating entry for table '%s' on connection '%s'%s%s%s\n", table, connection,
+ lenschema ? " (schema '" : "", lenschema ? schema : "", lenschema ? "')" : "");
+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
ast_odbc_release_obj(obj);
res = -1;
break;
@@ -157,8 +168,10 @@ static int load_config(void)
tableptr->usegmtime = usegmtime;
tableptr->connection = (char *)tableptr + sizeof(*tableptr);
tableptr->table = (char *)tableptr + sizeof(*tableptr) + lenconnection + 1;
+ tableptr->schema = (char *)tableptr + sizeof(*tableptr) + lenconnection + 1 + lentable + 1;
ast_copy_string(tableptr->connection, connection, lenconnection + 1);
ast_copy_string(tableptr->table, table, lentable + 1);
+ ast_copy_string(tableptr->schema, schema, lenschema + 1);
ast_verb(3, "Found adaptive CDR table %s@%s.\n", tableptr->table, tableptr->connection);
@@ -228,6 +241,7 @@ static int load_config(void)
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;
+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
break;
}
entry->name = (char *)entry + sizeof(*entry);
@@ -376,7 +390,11 @@ 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);
+ if (ast_strlen_zero(tableptr->schema)) {
+ ast_str_set(&sql, 0, "INSERT INTO %s (", tableptr->table);
+ } else {
+ ast_str_set(&sql, 0, "INSERT INTO %s.%s (", tableptr->schema, tableptr->table);
+ }
ast_str_set(&sql2, 0, " VALUES (");
/* No need to check the connection now; we'll handle any failure in prepare_and_execute */
diff --git a/configs/cdr_adaptive_odbc.conf.sample b/configs/cdr_adaptive_odbc.conf.sample
index 9b2725b93..775e9abb2 100644
--- a/configs/cdr_adaptive_odbc.conf.sample
+++ b/configs/cdr_adaptive_odbc.conf.sample
@@ -28,6 +28,7 @@
;[third]
;connection=sqlserver
;table=AsteriskCDR
+;schema=public ; for databases which support schemas
;usegmtime=yes ; defaults to no
;alias src => source
;alias channel => source_channel