Merged revisions 78415 via svnmerge from
[asterisk/asterisk.git] / res / res_config_odbc.c
index a5294eb..ce3f672 100644 (file)
@@ -54,6 +54,45 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/res_odbc.h"
 #include "asterisk/utils.h"
 
+struct custom_prepare_struct {
+       const char *sql;
+       const char *extra;
+       va_list *ap;
+};
+
+static SQLHSTMT custom_prepare(struct odbc_obj *obj, void *data)
+{
+       int res, x = 1;
+       struct custom_prepare_struct *cps = data;
+       const char *newparam, *newval;
+       SQLHSTMT stmt;
+       va_list ap;
+       va_copy(ap, *(cps->ap));
+
+       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!\n");
+               return NULL;
+       }
+
+       res = SQLPrepare(stmt, (unsigned char *)cps->sql, SQL_NTS);
+       if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
+               ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", cps->sql);
+               SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+               return NULL;
+       }
+
+       while ((newparam = va_arg(ap, const char *))) {
+               newval = va_arg(ap, const char *);
+               SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(newval), 0, (void *)newval, 0, NULL);
+       }
+       va_end(ap);
+
+       if (!ast_strlen_zero(cps->extra))
+               SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(cps->extra), 0, (void *)cps->extra, 0, NULL);
+       return stmt;
+}
+
 /*!
  * \brief Excute an SQL query and return ast_variable list
  * \param database
@@ -88,30 +127,23 @@ static struct ast_variable *realtime_odbc(const char *database, const char *tabl
        SQLSMALLINT nullable;
        SQLLEN indicator;
        va_list aq;
+       struct custom_prepare_struct cps = { .sql = sql, .ap = &ap };
        
        va_copy(aq, ap);
-       
-       
+
        if (!table)
                return NULL;
 
        obj = ast_odbc_request_obj(database, 0);
-       if (!obj)
-               return NULL;
 
-       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!\n");
-               ast_odbc_release_obj(obj);
+       if (!obj) {
+               ast_log(LOG_ERROR, "No database handle available with the name of '%s' (check res_odbc.conf)\n", database);
                return NULL;
        }
 
        newparam = va_arg(aq, const char *);
-       if (!newparam)  {
-               SQLFreeHandle (SQL_HANDLE_STMT, stmt);
-               ast_odbc_release_obj(obj);
+       if (!newparam)
                return NULL;
-       }
        newval = va_arg(aq, const char *);
        op = !strchr(newparam, ' ') ? " =" : "";
        snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?", table, newparam, op);
@@ -123,27 +155,9 @@ static struct ast_variable *realtime_odbc(const char *database, const char *tabl
        }
        va_end(aq);
 
-       res = SQLPrepare(stmt, (unsigned char *)sql, SQL_NTS);
-       if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
-               ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
-               SQLFreeHandle (SQL_HANDLE_STMT, stmt);
-               ast_odbc_release_obj(obj);
-               return NULL;
-       }
-       
-       /* Now bind the parameters */
-       x = 1;
+       stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
 
-       while((newparam = va_arg(ap, const char *))) {
-               newval = va_arg(ap, const char *);
-               SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(newval), 0, (void *)newval, 0, NULL);
-       }
-       
-       res = ast_odbc_smart_execute(obj, stmt);
-
-       if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
-               ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
-               SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+       if (!stmt) {
                ast_odbc_release_obj(obj);
                return NULL;
        }
@@ -160,7 +174,7 @@ static struct ast_variable *realtime_odbc(const char *database, const char *tabl
        if (res == SQL_NO_DATA) {
                SQLFreeHandle (SQL_HANDLE_STMT, stmt);
                ast_odbc_release_obj(obj);
-                return NULL;
+               return NULL;
        }
        if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
                ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
@@ -201,17 +215,19 @@ static struct ast_variable *realtime_odbc(const char *database, const char *tabl
                stringp = rowdata;
                while(stringp) {
                        chunk = strsep(&stringp, ";");
-                       if (prev) {
-                               prev->next = ast_variable_new(coltitle, chunk);
-                               if (prev->next)
-                                       prev = prev->next;
-                       } else 
-                               prev = var = ast_variable_new(coltitle, chunk);
+                       if (!ast_strlen_zero(ast_strip(chunk))) {
+                               if (prev) {
+                                       prev->next = ast_variable_new(coltitle, chunk);
+                                       if (prev->next)
+                                               prev = prev->next;
+                               } else 
+                                       prev = var = ast_variable_new(coltitle, chunk);
+                       }
                }
        }
 
 
-       SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+       SQLFreeHandle(SQL_HANDLE_STMT, stmt);
        ast_odbc_release_obj(obj);
        return var;
 }
@@ -253,6 +269,7 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char *
        SQLSMALLINT decimaldigits;
        SQLSMALLINT nullable;
        SQLLEN indicator;
+       struct custom_prepare_struct cps = { .sql = sql, .ap = &ap };
 
        va_list aq;
        va_copy(aq, ap);
@@ -264,16 +281,8 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char *
        if (!obj)
                return NULL;
 
-       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!\n");
-               ast_odbc_release_obj(obj);
-               return NULL;
-       }
-
        newparam = va_arg(aq, const char *);
        if (!newparam)  {
-               SQLFreeHandle(SQL_HANDLE_STMT, stmt);
                ast_odbc_release_obj(obj);
                return NULL;
        }
@@ -293,27 +302,9 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char *
                snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield);
        va_end(aq);
 
-       res = SQLPrepare(stmt, (unsigned char *)sql, SQL_NTS);
-       if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
-               ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
-               SQLFreeHandle(SQL_HANDLE_STMT, stmt);
-               ast_odbc_release_obj(obj);
-               return NULL;
-       }
-       
-       /* Now bind the parameters */
-       x = 1;
+       stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
 
-       while((newparam = va_arg(ap, const char *))) {
-               newval = va_arg(ap, const char *);
-               SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(newval), 0, (void *)newval, 0, NULL);
-       }
-               
-       res = ast_odbc_smart_execute(obj, stmt);
-
-       if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
-               ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
-               SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+       if (!stmt) {
                ast_odbc_release_obj(obj);
                return NULL;
        }
@@ -407,8 +398,8 @@ static int update_odbc(const char *database, const char *table, const char *keyf
        SQLLEN rowcount=0;
        const char *newparam, *newval;
        int res;
-       int x;
        va_list aq;
+       struct custom_prepare_struct cps = { .sql = sql, .ap = &ap, .extra = lookup };
        
        va_copy(aq, ap);
        
@@ -419,16 +410,8 @@ static int update_odbc(const char *database, const char *table, const char *keyf
        if (!obj)
                return -1;
 
-       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!\n");
-               ast_odbc_release_obj(obj);
-               return -1;
-       }
-
        newparam = va_arg(aq, const char *);
        if (!newparam)  {
-               SQLFreeHandle (SQL_HANDLE_STMT, stmt);
                ast_odbc_release_obj(obj);
                return -1;
        }
@@ -440,30 +423,10 @@ static int update_odbc(const char *database, const char *table, const char *keyf
        }
        va_end(aq);
        snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s=?", keyfield);
-       
-       res = SQLPrepare(stmt, (unsigned char *)sql, SQL_NTS);
-       if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
-               ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
-               SQLFreeHandle (SQL_HANDLE_STMT, stmt);
-               ast_odbc_release_obj(obj);
-               return -1;
-       }
-       
-       /* Now bind the parameters */
-       x = 1;
 
-       while((newparam = va_arg(ap, const char *))) {
-               newval = va_arg(ap, const char *);
-               SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(newval), 0, (void *)newval, 0, NULL);
-       }
-               
-       SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(lookup), 0, (void *)lookup, 0, NULL);
-
-       res = ast_odbc_smart_execute(obj, stmt);
+       stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
 
-       if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
-               ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
-               SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+       if (!stmt) {
                ast_odbc_release_obj(obj);
                return -1;
        }