@ -98,11 +98,67 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
< / syntax >
< description >
< para > This function acts in the same way as REALTIME ( . . . . ) does , except that
it destroys matched record in RT engine . < / para >
it destroys the matched record in the RT engine . < / para >
< / description >
< / function >
< function name = " REALTIME_FIELD " language = " en_US " >
< synopsis >
RealTime query function .
< / synopsis >
< syntax >
< parameter name = " family " required = " true " / >
< parameter name = " fieldmatch " required = " true " / >
< parameter name = " value " required = " true " / >
< parameter name = " fieldname " required = " true " / >
< / syntax >
< description >
< para > This function retrieves a single item , < replaceable > fieldname < / replaceable >
from the RT engine , where < replaceable > fieldmatch < / replaceable > contains the value
< replaceable > value < / replaceable > . When written to , the REALTIME_FIELD ( ) function
performs identically to the REALTIME ( ) function . < / para >
< / description >
< / function >
< function name = " REALTIME_HASH " language = " en_US " >
< synopsis >
RealTime query function .
< / synopsis >
< syntax >
< parameter name = " family " required = " true " / >
< parameter name = " fieldmatch " required = " true " / >
< parameter name = " value " required = " true " / >
< / syntax >
< description >
< para > This function retrieves a single record from the RT engine , where
< replaceable > fieldmatch < / replaceable > contains the value
< replaceable > value < / replaceable > and formats the output suitably , such that
it can be assigned to the HASH ( ) function . The HASH ( ) function then provides
a suitable method for retrieving each field value of the record . < / para >
< / description >
< / function >
* * */
AST_THREADSTORAGE ( buf1 ) ;
AST_THREADSTORAGE ( buf2 ) ;
AST_THREADSTORAGE ( buf3 ) ;
static char * hash_escape ( struct ast_str * * str , const char * value )
{
int len ;
ast_str_reset ( * str ) ;
if ( ( * str ) - > len < ( len = strlen ( value ) * 2 + 1 ) ) {
ast_str_make_space ( str , len ) ;
}
for ( ; * value ; value + + ) {
if ( * value = = ' , ' | | * value = = ' \\ ' ) {
( * str ) - > str [ ( * str ) - > used + + ] = ' \\ ' ;
}
( * str ) - > str [ ( * str ) - > used + + ] = * value ;
}
( * str ) - > str [ ( * str ) - > used ] = ' \0 ' ;
return ( * str ) - > str ;
}
static int function_realtime_read ( struct ast_channel * chan , const char * cmd , char * data , char * buf , size_t len )
{
struct ast_variable * var , * head ;
@ -169,7 +225,7 @@ static int function_realtime_write(struct ast_channel *chan, const char *cmd, ch
) ;
if ( ast_strlen_zero ( data ) ) {
ast_log ( LOG_WARNING , " Syntax: REALTIME (family,fieldmatch,value,newcol) - missing argument!\n " ) ;
ast_log ( LOG_WARNING , " Syntax: %s (family,fieldmatch,value,newcol) - missing argument!\n " , cmd ) ;
return - 1 ;
}
@ -190,6 +246,82 @@ static int function_realtime_write(struct ast_channel *chan, const char *cmd, ch
return 0 ;
}
static int realtimefield_read ( struct ast_channel * chan , const char * cmd , char * data , char * buf , size_t len )
{
struct ast_variable * var , * head ;
struct ast_str * escapebuf = ast_str_thread_get ( & buf1 , 16 ) ;
struct ast_str * fields = ast_str_thread_get ( & buf2 , 16 ) ;
struct ast_str * values = ast_str_thread_get ( & buf3 , 16 ) ;
int first ;
enum { rtfield , rthash } which ;
AST_DECLARE_APP_ARGS ( args ,
AST_APP_ARG ( family ) ;
AST_APP_ARG ( fieldmatch ) ;
AST_APP_ARG ( value ) ;
AST_APP_ARG ( fieldname ) ;
) ;
if ( ! strcmp ( cmd , " REALTIME_FIELD " ) ) {
which = rtfield ;
} else {
which = rthash ;
}
if ( ast_strlen_zero ( data ) ) {
ast_log ( LOG_WARNING , " Syntax: %s(family,fieldmatch,value%s) - missing argument! \n " , cmd , which = = rtfield ? " ,fieldname " : " " ) ;
return - 1 ;
}
AST_STANDARD_APP_ARGS ( args , data ) ;
if ( ( which = = rtfield & & args . argc ! = 4 ) | | ( which = = rthash & & args . argc ! = 3 ) ) {
ast_log ( LOG_WARNING , " Syntax: %s(family,fieldmatch,value%s) - missing argument! \n " , cmd , which = = rtfield ? " ,fieldname " : " " ) ;
return - 1 ;
}
if ( chan ) {
ast_autoservice_start ( chan ) ;
}
if ( ! ( head = ast_load_realtime_all ( args . family , args . fieldmatch , args . value , SENTINEL ) ) ) {
if ( chan ) {
ast_autoservice_stop ( chan ) ;
}
return - 1 ;
}
ast_str_reset ( fields ) ;
ast_str_reset ( values ) ;
for ( var = head ; var ; var = var - > next ) {
if ( which = = rtfield ) {
ast_debug ( 1 , " Comparing %s to %s \n " , var - > name , args . fieldname ) ;
if ( ! strcasecmp ( var - > name , args . fieldname ) ) {
ast_debug ( 1 , " Match! Value is %s \n " , var - > value ) ;
ast_copy_string ( buf , var - > value , len ) ;
break ;
}
} else if ( which = = rthash ) {
ast_debug ( 1 , " Setting hash key %s to value %s \n " , var - > name , var - > value ) ;
ast_str_append ( & fields , 0 , " %s%s " , first ? " " : " , " , hash_escape ( & escapebuf , var - > name ) ) ;
ast_str_append ( & values , 0 , " %s%s " , first ? " " : " , " , hash_escape ( & escapebuf , var - > value ) ) ;
first = 0 ;
}
}
ast_variables_destroy ( head ) ;
if ( which = = rthash ) {
pbx_builtin_setvar_helper ( chan , " ~ODBCFIELDS~ " , fields - > str ) ;
ast_copy_string ( buf , values - > str , len ) ;
}
if ( chan ) {
ast_autoservice_stop ( chan ) ;
}
return 0 ;
}
static int function_realtime_store ( struct ast_channel * chan , const char * cmd , char * data , const char * value )
{
int res = 0 ;
@ -302,6 +434,17 @@ struct ast_custom_function realtime_function = {
. write = function_realtime_write ,
} ;
struct ast_custom_function realtimefield_function = {
. name = " REALTIME_FIELD " ,
. read = realtimefield_read ,
. write = function_realtime_write ,
} ;
struct ast_custom_function realtimehash_function = {
. name = " REALTIME_HASH " ,
. read = realtimefield_read ,
} ;
struct ast_custom_function realtime_store_function = {
. name = " REALTIME_STORE " ,
. write = function_realtime_store ,
@ -318,6 +461,8 @@ static int unload_module(void)
res | = ast_custom_function_unregister ( & realtime_function ) ;
res | = ast_custom_function_unregister ( & realtime_store_function ) ;
res | = ast_custom_function_unregister ( & realtime_destroy_function ) ;
res | = ast_custom_function_unregister ( & realtimefield_function ) ;
res | = ast_custom_function_unregister ( & realtimehash_function ) ;
return res ;
}
@ -327,6 +472,8 @@ static int load_module(void)
res | = ast_custom_function_register ( & realtime_function ) ;
res | = ast_custom_function_register ( & realtime_store_function ) ;
res | = ast_custom_function_register ( & realtime_destroy_function ) ;
res | = ast_custom_function_register ( & realtimefield_function ) ;
res | = ast_custom_function_register ( & realtimehash_function ) ;
return res ;
}