diff --git a/src/mod/languages/mod_lua/freeswitch.i b/src/mod/languages/mod_lua/freeswitch.i index 501b50fb48..96a5f8c722 100644 --- a/src/mod/languages/mod_lua/freeswitch.i +++ b/src/mod/languages/mod_lua/freeswitch.i @@ -61,6 +61,11 @@ %include "typemaps.i" %apply int *OUTPUT { int *len }; +%typemap(out) DbhQueryRowsReturn { + SWIG_arg += result; +} + + /** * tell swig to grok everything defined in these header files and * build all sorts of c wrappers and lua shadows of the c wrappers. @@ -115,6 +120,7 @@ class Dbh { bool connected(); bool test_reactive(char *test_sql, char *drop_sql = NULL, char *reactive_sql = NULL); bool query(char *sql, SWIGLUA_FN lua_fun); + DbhQueryRowsReturn query_rows(lua_State* L, char *sql); int affected_rows(); char *last_error(); void clear_error(); diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index 5d89aa28f9..2affbf7e88 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -482,6 +482,62 @@ bool Dbh::query(char *sql, SWIGLUA_FN lua_fun) return false; } +struct query_callback_data { + lua_State *L; + int stack_index; + int *row_num; +}; + +int query2_callback(void *pArg, int argc, char **argv, char **columnNames) +{ + struct query_callback_data *data = (struct query_callback_data *) pArg; + lua_State *tL = data->L; + lua_createtable(tL, 0, argc); + for (int i = 0; i < argc; i++) { + lua_pushstring(tL, argv[i]); + lua_setfield(tL, -2, switch_str_nil(columnNames[i])); + } + lua_rawseti(tL, data->stack_index + 2, (*data->row_num)++); + return 0; +} + +DbhQueryRowsReturn Dbh::query_rows(lua_State* L, char *sql) +{ + int stack_index = lua_gettop(L); + clear_error(); + lua_pushboolean(L, 0); // result success error: stack_index + 1 + lua_newtable(L); // the rows: stack_index + 2 + lua_pushnil(L); // error message if any: stack_index + 3 + + if (zstr(sql)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing SQL query.\n"); + lua_pushstring(L, "Missing SQL query."); + lua_replace(L, stack_index + 3); + return 3; + } + + if (dbh) { + int index = 1; + struct query_callback_data pData = {L, stack_index, &index}; + + if (switch_cache_db_execute_sql_callback(dbh, sql, query2_callback, &pData, &err) == SWITCH_STATUS_SUCCESS) { + // no errors + lua_pushboolean(L, 1); + lua_replace(L, stack_index + 1); + } else { + lua_pushstring(L, !zstr(err) ? err : "Failed to execute sql query"); + lua_replace(L, stack_index + 3); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DBH NOT Connected.\n"); + lua_pushstring(L, "DBH NOT Connected."); + lua_replace(L, stack_index + 3); + } + + return 3; +} + + int Dbh::affected_rows() { if (dbh) { diff --git a/src/mod/languages/mod_lua/freeswitch_lua.h b/src/mod/languages/mod_lua/freeswitch_lua.h index c357916607..0cd1a64c32 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.h +++ b/src/mod/languages/mod_lua/freeswitch_lua.h @@ -28,6 +28,7 @@ typedef struct{ #define SWIGLUA_TABLE_GET(fn) {lua_pushvalue(fn.L,fn.idx);} +typedef int DbhQueryRowsReturn; namespace LUA { class Session:public CoreSession { @@ -76,6 +77,7 @@ namespace LUA { bool connected(); bool test_reactive(char *test_sql, char *drop_sql = NULL, char *reactive_sql = NULL); bool query(char *sql, SWIGLUA_FN lua_fun); + DbhQueryRowsReturn query_rows(lua_State* L, char *sql); int affected_rows(); char *last_error(); void clear_error(); diff --git a/src/mod/languages/mod_lua/mod_lua_wrap.cpp b/src/mod/languages/mod_lua/mod_lua_wrap.cpp index 93ba825557..15babcfe12 100644 --- a/src/mod/languages/mod_lua/mod_lua_wrap.cpp +++ b/src/mod/languages/mod_lua/mod_lua_wrap.cpp @@ -9720,6 +9720,37 @@ fail: } +static int _wrap_Dbh_query_rows(lua_State* L) { + int SWIG_arg = 0; + LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; + lua_State *arg2 = (lua_State *) 0 ; + char *arg3 = (char *) 0 ; + DbhQueryRowsReturn result; + + arg2 = L; + SWIG_check_num_args("LUA::Dbh::query_rows",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("LUA::Dbh::query_rows",1,"LUA::Dbh *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("LUA::Dbh::query_rows",2,"char *"); + + if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_LUA__Dbh,0))){ + SWIG_fail_ptr("Dbh_query_rows",1,SWIGTYPE_p_LUA__Dbh); + } + + arg3 = (char *)lua_tostring(L, 2); + result = (arg1)->query_rows(arg2,arg3); + { + SWIG_arg += result; + } + return SWIG_arg; + + if(0) SWIG_fail; + +fail: + lua_error(L); + return SWIG_arg; +} + + static int _wrap_Dbh_affected_rows(lua_State* L) { int SWIG_arg = 0; LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; @@ -9839,6 +9870,7 @@ static swig_lua_method swig_Dbh_methods[]= { { "connected", _wrap_Dbh_connected}, { "test_reactive", _wrap_Dbh_test_reactive}, { "query", _wrap_Dbh_query}, + { "query_rows", _wrap_Dbh_query_rows}, { "affected_rows", _wrap_Dbh_affected_rows}, { "last_error", _wrap_Dbh_last_error}, { "clear_error", _wrap_Dbh_clear_error},