]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
mod_lua: add Dbh:query_rows
authorAron Podrigal <aronp@guaranteedplus.com>
Tue, 30 Jan 2024 12:21:47 +0000 (06:21 -0600)
committerAron Podrigal <aronp@guaranteedplus.com>
Tue, 14 Jan 2025 22:51:29 +0000 (16:51 -0600)
The added method, query_rows, allows the retrieval of rows from a database without the need for a callback function, it fetches the rows and returns 3 arguments as show below.

```lua
local success, rows, err = dbh:query_rows(sql)
```

This function performs better with large number of rows. Test results below 50k rows returned.

dbh:query(sql, callback) - 0.335949 seconds
dbh:query_rows(sql) - 0.253178 seconds

src/mod/languages/mod_lua/freeswitch.i
src/mod/languages/mod_lua/freeswitch_lua.cpp
src/mod/languages/mod_lua/freeswitch_lua.h
src/mod/languages/mod_lua/mod_lua_wrap.cpp

index 501b50fb48f7145b7eebc57b79ab661c5a1de817..96a5f8c72275802ae2dc3eedfc8cca4673874ed9 100644 (file)
 %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();
index 5d89aa28f9445b3cf5d68a7e5ebc54715bdf3dae..2affbf7e883724b021b163a484ed18225814c9f9 100644 (file)
@@ -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) {
index c357916607a2209929cc710d68fc19e68345c734..0cd1a64c32659c836a07b8d634ed095c484be381 100644 (file)
@@ -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();
index 93ba825557f781bccdc172445852186646c8e7ac..15babcfe121adabeba73cd536a6a6cfe04ad6d55 100644 (file)
@@ -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},