Convert func_odbc to use ast_dummy_alloc_channel()
authorMatthew Nicholson <mnicholson@digium.com>
Thu, 9 Jul 2009 20:04:43 +0000 (20:04 +0000)
committerMatthew Nicholson <mnicholson@digium.com>
Thu, 9 Jul 2009 20:04:43 +0000 (20:04 +0000)
Review: https://reviewboard.asterisk.org/r/290/

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@205666 65c4cc65-6c06-0410-ace0-fbb531ad65f3

funcs/func_odbc.c

index c8b65eb..0205f18 100644 (file)
@@ -233,17 +233,23 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co
        if (!query) {
                ast_log(LOG_ERROR, "No such function '%s'\n", cmd);
                AST_RWLIST_UNLOCK(&queries);
-               pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
+               if (chan) {
+                       pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
+               }
                return -1;
        }
 
        if (!chan) {
-               if ((chan = ast_channel_alloc(0, AST_STATE_DOWN, "", "", "", "", "", "", 0, "Bogus/func_odbc")))
-                       bogus_chan = 1;
+               if (!(chan = ast_dummy_channel_alloc())) {
+                       AST_RWLIST_UNLOCK(&queries);
+                       return -1;
+               }
+               bogus_chan = 1;
        }
 
-       if (chan)
+       if (!bogus_chan) {
                ast_autoservice_start(chan);
+       }
 
        ast_str_make_space(&buf, strlen(query->sql_write) * 2 + 300);
        ast_str_make_space(&insertbuf, strlen(query->sql_insert) * 2 + 300);
@@ -254,12 +260,11 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co
        if (!s || !t) {
                ast_log(LOG_ERROR, "Out of memory\n");
                AST_RWLIST_UNLOCK(&queries);
-               if (chan)
+               if (!bogus_chan) {
                        ast_autoservice_stop(chan);
-               if (bogus_chan) {
-                       ast_channel_release(chan);
-               } else {
                        pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
+               } else {
+                       ast_channel_release(chan);
                }
                return -1;
        }
@@ -283,44 +288,48 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co
        ast_str_substitute_variables(&buf, 0, chan, query->sql_write);
        ast_str_substitute_variables(&insertbuf, 0, chan, query->sql_insert);
 
-       /* Restore prior values */
-       for (i = 0; i < args.argc; i++) {
-               snprintf(varname, sizeof(varname), "ARG%d", i + 1);
-               pbx_builtin_setvar_helper(chan, varname, NULL);
-       }
-
-       for (i = 0; i < values.argc; i++) {
-               snprintf(varname, sizeof(varname), "VAL%d", i + 1);
-               pbx_builtin_setvar_helper(chan, varname, NULL);
-       }
-       pbx_builtin_setvar_helper(chan, "VALUE", NULL);
-
-       /*!\note
-        * Okay, this part is confusing.  Transactions belong to a single database
-        * handle.  Therefore, when working with transactions, we CANNOT failover
-        * to multiple DSNs.  We MUST have a single handle all the way through the
-        * transaction, or else we CANNOT enforce atomicity.
-        */
-       for (dsn = 0; dsn < 5; dsn++) {
-               if (transactional) {
-                       /* This can only happen second time through or greater. */
-                       ast_log(LOG_WARNING, "Transactions do not work well with multiple DSNs for 'writehandle'\n");
+       if (bogus_chan) {
+               chan = ast_channel_release(chan);
+       } else {
+               /* Restore prior values */
+               for (i = 0; i < args.argc; i++) {
+                       snprintf(varname, sizeof(varname), "ARG%d", i + 1);
+                       pbx_builtin_setvar_helper(chan, varname, NULL);
                }
 
-               if (!ast_strlen_zero(query->writehandle[dsn])) {
-                       if ((obj = ast_odbc_retrieve_transaction_obj(chan, query->writehandle[dsn]))) {
-                               transactional = 1;
-                       } else {
-                               obj = ast_odbc_request_obj(query->writehandle[dsn], 0);
-                               transactional = 0;
+               for (i = 0; i < values.argc; i++) {
+                       snprintf(varname, sizeof(varname), "VAL%d", i + 1);
+                       pbx_builtin_setvar_helper(chan, varname, NULL);
+               }
+               pbx_builtin_setvar_helper(chan, "VALUE", NULL);
+
+               /*!\note
+                * Okay, this part is confusing.  Transactions belong to a single database
+                * handle.  Therefore, when working with transactions, we CANNOT failover
+                * to multiple DSNs.  We MUST have a single handle all the way through the
+                * transaction, or else we CANNOT enforce atomicity.
+                */
+               for (dsn = 0; dsn < 5; dsn++) {
+                       if (transactional) {
+                               /* This can only happen second time through or greater. */
+                               ast_log(LOG_WARNING, "Transactions do not work well with multiple DSNs for 'writehandle'\n");
                        }
-                       if (obj && (stmt = ast_odbc_direct_execute(obj, generic_execute, ast_str_buffer(buf)))) {
-                               break;
+
+                       if (!ast_strlen_zero(query->writehandle[dsn])) {
+                               if ((obj = ast_odbc_retrieve_transaction_obj(chan, query->writehandle[dsn]))) {
+                                       transactional = 1;
+                               } else {
+                                       obj = ast_odbc_request_obj(query->writehandle[dsn], 0);
+                                       transactional = 0;
+                               }
+                               if (obj && (stmt = ast_odbc_direct_execute(obj, generic_execute, ast_str_buffer(buf)))) {
+                                       break;
+                               }
                        }
-               }
 
-               if (obj && !transactional) {
-                       ast_odbc_release_obj(obj);
+                       if (obj && !transactional) {
+                               ast_odbc_release_obj(obj);
+                       }
                }
        }
 
@@ -351,9 +360,11 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co
         * flag this as -1 rows.  Note that this is different from 0 affected rows
         * which would be the case if we succeeded in our query, but the values did
         * not change. */
-       snprintf(varname, sizeof(varname), "%d", (int)rows);
-       pbx_builtin_setvar_helper(chan, "ODBCROWS", varname);
-       pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
+       if (!bogus_chan) {
+               snprintf(varname, sizeof(varname), "%d", (int)rows);
+               pbx_builtin_setvar_helper(chan, "ODBCROWS", varname);
+               pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
+       }
 
        if (stmt) {
                SQLCloseCursor(stmt);
@@ -364,10 +375,9 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co
                obj = NULL;
        }
 
-       if (chan)
+       if (!bogus_chan) {
                ast_autoservice_stop(chan);
-       if (bogus_chan)
-               ast_channel_release(chan);
+       }
 
        return 0;
 }
@@ -392,7 +402,9 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
        const char *status = "FAILURE";
 
        if (!sql) {
-               pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
+               if (chan) {
+                       pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
+               }
                return -1;
        }
 
@@ -408,18 +420,22 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
        if (!query) {
                ast_log(LOG_ERROR, "No such function '%s'\n", cmd);
                AST_RWLIST_UNLOCK(&queries);
-               pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
-               pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
+               if (chan) {
+                       pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
+                       pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
+               }
                return -1;
        }
 
        if (!chan) {
-               if ((chan = ast_channel_alloc(0, AST_STATE_DOWN, "", "", "", "", "", "", 0, "Bogus/func_odbc"))) {
-                       bogus_chan = 1;
+               if (!(chan = ast_dummy_channel_alloc())) {
+                       AST_RWLIST_UNLOCK(&queries);
+                       return -1;
                }
+               bogus_chan = 1;
        }
 
-       if (chan) {
+       if (!bogus_chan) {
                ast_autoservice_start(chan);
        }
 
@@ -431,15 +447,19 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
 
        ast_str_substitute_variables(&sql, 0, chan, query->sql_read);
 
-       /* Restore prior values */
-       for (x = 0; x < args.argc; x++) {
-               snprintf(varname, sizeof(varname), "ARG%d", x + 1);
-               pbx_builtin_setvar_helper(chan, varname, NULL);
+       if (bogus_chan) {
+               chan = ast_channel_release(chan);
+       } else {
+               /* Restore prior values */
+               for (x = 0; x < args.argc; x++) {
+                       snprintf(varname, sizeof(varname), "ARG%d", x + 1);
+                       pbx_builtin_setvar_helper(chan, varname, NULL);
+               }
        }
 
        /* Save these flags, so we can release the lock */
        escapecommas = ast_test_flag(query, OPT_ESCAPECOMMAS);
-       if (ast_test_flag(query, OPT_MULTIROW)) {
+       if (!bogus_chan && ast_test_flag(query, OPT_MULTIROW)) {
                resultset = ast_calloc(1, sizeof(*resultset));
                AST_LIST_HEAD_INIT(resultset);
                if (query->rowlimit) {
@@ -468,13 +488,10 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
                        ast_odbc_release_obj(obj);
                        obj = NULL;
                }
-               pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
-               if (chan) {
+               if (!bogus_chan) {
+                       pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
                        ast_autoservice_stop(chan);
                }
-               if (bogus_chan) {
-                       ast_channel_release(chan);
-               }
                return -1;
        }
 
@@ -485,13 +502,10 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
                SQLFreeHandle (SQL_HANDLE_STMT, stmt);
                ast_odbc_release_obj(obj);
                obj = NULL;
-               pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
-               if (chan) {
+               if (!bogus_chan) {
+                       pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
                        ast_autoservice_stop(chan);
                }
-               if (bogus_chan) {
-                       ast_channel_release(chan);
-               }
                return -1;
        }
 
@@ -512,12 +526,11 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
                SQLFreeHandle(SQL_HANDLE_STMT, stmt);
                ast_odbc_release_obj(obj);
                obj = NULL;
-               pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
-               pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
-               if (chan)
+               if (!bogus_chan) {
+                       pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
+                       pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
                        ast_autoservice_stop(chan);
-               if (bogus_chan)
-                       ast_channel_release(chan);
+               }
                return res1;
        }
 
@@ -558,10 +571,7 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
                                                obj = NULL;
                                                pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
                                                pbx_builtin_setvar_helper(chan, "ODBCSTATUS", "MEMERROR");
-                                               if (chan)
-                                                       ast_autoservice_stop(chan);
-                                               if (bogus_chan)
-                                                       ast_channel_release(chan);
+                                               ast_autoservice_stop(chan);
                                                return -1;
                                        }
                                        resultset = tmp;
@@ -636,41 +646,39 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
        }
 
 end_acf_read:
-       snprintf(rowcount, sizeof(rowcount), "%d", y);
-       pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
-       pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
-       pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", ast_str_buffer(colnames));
-       if (resultset) {
-               int uid;
-               struct ast_datastore *odbc_store;
-               uid = ast_atomic_fetchadd_int(&resultcount, +1) + 1;
-               snprintf(buf, len, "%d", uid);
-               odbc_store = ast_datastore_alloc(&odbc_info, buf);
-               if (!odbc_store) {
-                       ast_log(LOG_ERROR, "Rows retrieved, but unable to store it in the channel.  Results fail.\n");
-                       pbx_builtin_setvar_helper(chan, "ODBCSTATUS", "MEMERROR");
-                       odbc_datastore_free(resultset);
-                       SQLCloseCursor(stmt);
-                       SQLFreeHandle(SQL_HANDLE_STMT, stmt);
-                       ast_odbc_release_obj(obj);
-                       obj = NULL;
-                       if (chan)
+       if (!bogus_chan) {
+               snprintf(rowcount, sizeof(rowcount), "%d", y);
+               pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
+               pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
+               pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", ast_str_buffer(colnames));
+               if (resultset) {
+                       int uid;
+                       struct ast_datastore *odbc_store;
+                       uid = ast_atomic_fetchadd_int(&resultcount, +1) + 1;
+                       snprintf(buf, len, "%d", uid);
+                       odbc_store = ast_datastore_alloc(&odbc_info, buf);
+                       if (!odbc_store) {
+                               ast_log(LOG_ERROR, "Rows retrieved, but unable to store it in the channel.  Results fail.\n");
+                               odbc_datastore_free(resultset);
+                               SQLCloseCursor(stmt);
+                               SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+                               ast_odbc_release_obj(obj);
+                               obj = NULL;
+                               pbx_builtin_setvar_helper(chan, "ODBCSTATUS", "MEMERROR");
                                ast_autoservice_stop(chan);
-                       if (bogus_chan)
-                               ast_channel_release(chan);
-                       return -1;
+                               return -1;
+                       }
+                       odbc_store->data = resultset;
+                       ast_channel_datastore_add(chan, odbc_store);
                }
-               odbc_store->data = resultset;
-               ast_channel_datastore_add(chan, odbc_store);
        }
        SQLCloseCursor(stmt);
        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
        ast_odbc_release_obj(obj);
        obj = NULL;
-       if (chan)
+       if (!bogus_chan) {
                ast_autoservice_stop(chan);
-       if (bogus_chan)
-               ast_channel_release(chan);
+       }
        return 0;
 }