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();