mod_lua: add Dbh:query_rows

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
This commit is contained in:
Aron Podrigal 2024-01-30 06:21:47 -06:00
parent 7ed261b27b
commit a5426b36ca
4 changed files with 96 additions and 0 deletions

View File

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

View 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) {

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

View 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},