mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-06 04:30:28 +00:00
Allow multiple rows to be fetched within the normal mode of operation.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@216846 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
4
CHANGES
4
CHANGES
@@ -105,6 +105,10 @@ Dialplan Functions
|
|||||||
channel, is one approach that will avoid conflicts.
|
channel, is one approach that will avoid conflicts.
|
||||||
* Added new dialplan function MUTEAUDIO() for muting inbound and/or outbound
|
* Added new dialplan function MUTEAUDIO() for muting inbound and/or outbound
|
||||||
audio in a channel.
|
audio in a channel.
|
||||||
|
* func_odbc now allows multiple row results to be retrieved without using
|
||||||
|
mode=multirow. If rowlimit is set, then additional rows may be retrieved
|
||||||
|
from the same query by using the name of the function which retrieved the
|
||||||
|
first row as an argument to ODBC_FETCH().
|
||||||
|
|
||||||
Dialplan Variables
|
Dialplan Variables
|
||||||
------------------
|
------------------
|
||||||
|
@@ -62,10 +62,14 @@
|
|||||||
; query was initially performed. Additionally, as the results are
|
; query was initially performed. Additionally, as the results are
|
||||||
; associated with a channel, mode=multirow is incompatible with
|
; associated with a channel, mode=multirow is incompatible with
|
||||||
; the global space.
|
; the global space.
|
||||||
; rowlimit An additional option for within mode=multirow, rowlimit limits
|
; rowlimit Rowlimit limits the total number of rows which can be stored for
|
||||||
; the total number of rows which can be stored for that query.
|
; that query. For mode=multirow, otherwise, func_odbc will
|
||||||
; Otherwise, func_odbc will attempt to store all rows in the
|
; attempt to store all rows in the resultset, up to the maximum
|
||||||
; resultset, up to the maximum amount of memory.
|
; amount of memory. In normal mode, rowlimit can be set to allow
|
||||||
|
; additional rows to be fetched, rather than just the first one.
|
||||||
|
; These additional rows can be returned by using the name of the
|
||||||
|
; function which was called to retrieve the first row as an
|
||||||
|
; argument to ODBC_FETCH().
|
||||||
|
|
||||||
|
|
||||||
; ODBC_SQL - Allow an SQL statement to be built entirely in the dialplan
|
; ODBC_SQL - Allow an SQL statement to be built entirely in the dialplan
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* Asterisk -- An open source telephony toolkit.
|
* Asterisk -- An open source telephony toolkit.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2005, 2006 Tilghman Lesher
|
* Copyright (c) 2005, 2006 Tilghman Lesher
|
||||||
* Copyright (c) 2008 Digium, Inc.
|
* Copyright (c) 2008, 2009 Digium, Inc.
|
||||||
*
|
*
|
||||||
* Tilghman Lesher <func_odbc__200508@the-tilghman.com>
|
* Tilghman Lesher <func_odbc__200508@the-tilghman.com>
|
||||||
*
|
*
|
||||||
@@ -144,6 +144,8 @@ AST_THREADSTORAGE(sql2_buf);
|
|||||||
AST_THREADSTORAGE(coldata_buf);
|
AST_THREADSTORAGE(coldata_buf);
|
||||||
AST_THREADSTORAGE(colnames_buf);
|
AST_THREADSTORAGE(colnames_buf);
|
||||||
|
|
||||||
|
static int acf_fetch(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
|
||||||
|
|
||||||
static void odbc_datastore_free(void *data)
|
static void odbc_datastore_free(void *data)
|
||||||
{
|
{
|
||||||
struct odbc_datastore *result = data;
|
struct odbc_datastore *result = data;
|
||||||
@@ -388,7 +390,7 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
|
|||||||
struct acf_odbc_query *query;
|
struct acf_odbc_query *query;
|
||||||
char varname[15], rowcount[12] = "-1";
|
char varname[15], rowcount[12] = "-1";
|
||||||
struct ast_str *colnames = ast_str_thread_get(&colnames_buf, 16);
|
struct ast_str *colnames = ast_str_thread_get(&colnames_buf, 16);
|
||||||
int res, x, y, buflen = 0, escapecommas, rowlimit = 1, dsn, bogus_chan = 0;
|
int res, x, y, buflen = 0, escapecommas, rowlimit = 1, multirow = 0, dsn, bogus_chan = 0;
|
||||||
AST_DECLARE_APP_ARGS(args,
|
AST_DECLARE_APP_ARGS(args,
|
||||||
AST_APP_ARG(field)[100];
|
AST_APP_ARG(field)[100];
|
||||||
);
|
);
|
||||||
@@ -460,13 +462,30 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
|
|||||||
/* Save these flags, so we can release the lock */
|
/* Save these flags, so we can release the lock */
|
||||||
escapecommas = ast_test_flag(query, OPT_ESCAPECOMMAS);
|
escapecommas = ast_test_flag(query, OPT_ESCAPECOMMAS);
|
||||||
if (!bogus_chan && ast_test_flag(query, OPT_MULTIROW)) {
|
if (!bogus_chan && ast_test_flag(query, OPT_MULTIROW)) {
|
||||||
resultset = ast_calloc(1, sizeof(*resultset));
|
if (!(resultset = ast_calloc(1, sizeof(*resultset)))) {
|
||||||
|
pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
|
||||||
|
pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
|
||||||
|
ast_autoservice_stop(chan);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
AST_LIST_HEAD_INIT(resultset);
|
AST_LIST_HEAD_INIT(resultset);
|
||||||
if (query->rowlimit) {
|
if (query->rowlimit) {
|
||||||
rowlimit = query->rowlimit;
|
rowlimit = query->rowlimit;
|
||||||
} else {
|
} else {
|
||||||
rowlimit = INT_MAX;
|
rowlimit = INT_MAX;
|
||||||
}
|
}
|
||||||
|
multirow = 1;
|
||||||
|
} else if (!bogus_chan) {
|
||||||
|
if (query->rowlimit > 1) {
|
||||||
|
rowlimit = query->rowlimit;
|
||||||
|
if (!(resultset = ast_calloc(1, sizeof(*resultset)))) {
|
||||||
|
pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
|
||||||
|
pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
|
||||||
|
ast_autoservice_stop(chan);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
AST_LIST_HEAD_INIT(resultset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
AST_RWLIST_UNLOCK(&queries);
|
AST_RWLIST_UNLOCK(&queries);
|
||||||
|
|
||||||
@@ -480,6 +499,8 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
|
|||||||
if (stmt) {
|
if (stmt) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
ast_odbc_release_obj(obj);
|
||||||
|
obj = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stmt) {
|
if (!stmt) {
|
||||||
@@ -654,8 +675,22 @@ end_acf_read:
|
|||||||
if (resultset) {
|
if (resultset) {
|
||||||
int uid;
|
int uid;
|
||||||
struct ast_datastore *odbc_store;
|
struct ast_datastore *odbc_store;
|
||||||
uid = ast_atomic_fetchadd_int(&resultcount, +1) + 1;
|
if (multirow) {
|
||||||
snprintf(buf, len, "%d", uid);
|
uid = ast_atomic_fetchadd_int(&resultcount, +1) + 1;
|
||||||
|
snprintf(buf, len, "%d", uid);
|
||||||
|
} else {
|
||||||
|
/* Name of the query is name of the resultset */
|
||||||
|
ast_copy_string(buf, cmd, len);
|
||||||
|
|
||||||
|
/* If there's one with the same name already, free it */
|
||||||
|
ast_channel_lock(chan);
|
||||||
|
if ((odbc_store = ast_channel_datastore_find(chan, &odbc_info, buf))) {
|
||||||
|
ast_channel_datastore_remove(chan, odbc_store);
|
||||||
|
odbc_datastore_free(odbc_store->data);
|
||||||
|
ast_free(odbc_store);
|
||||||
|
}
|
||||||
|
ast_channel_unlock(chan);
|
||||||
|
}
|
||||||
odbc_store = ast_datastore_alloc(&odbc_info, buf);
|
odbc_store = ast_datastore_alloc(&odbc_info, buf);
|
||||||
if (!odbc_store) {
|
if (!odbc_store) {
|
||||||
ast_log(LOG_ERROR, "Rows retrieved, but unable to store it in the channel. Results fail.\n");
|
ast_log(LOG_ERROR, "Rows retrieved, but unable to store it in the channel. Results fail.\n");
|
||||||
@@ -676,6 +711,12 @@ end_acf_read:
|
|||||||
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||||
ast_odbc_release_obj(obj);
|
ast_odbc_release_obj(obj);
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
|
if (resultset && !multirow) {
|
||||||
|
/* Fetch the first resultset */
|
||||||
|
if (!acf_fetch(chan, "", buf, buf, len)) {
|
||||||
|
buf[0] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!bogus_chan) {
|
if (!bogus_chan) {
|
||||||
ast_autoservice_stop(chan);
|
ast_autoservice_stop(chan);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user