Expose the query classifier through the luafilter
The luafilter exposes two of the main functions provided by the query classifier API; the type and operation classification. The functions can be used by the Lua script with minimal overhead as the current query being executed is stored only as a pointer. The functions should only be called inside the `routeQuery` entry point of a Lua script.
This commit is contained in:
parent
8562a5138c
commit
be1b868938
@ -42,10 +42,6 @@ The entry points for the Lua script expect the following signatures:
|
||||
|
||||
- This function first loads the session script and executes in on a global
|
||||
level. After this, the newSession function in the Lua scripts is called.
|
||||
There is a single C function exported as a global variable for the session
|
||||
script named id_gen. The id_gen function returns an integer that is unique
|
||||
for this service only. This function is only accessible to the session
|
||||
level scripts.
|
||||
|
||||
- `nil closeSession()` - session is closed
|
||||
|
||||
@ -73,3 +69,27 @@ The entry points for the Lua script expect the following signatures:
|
||||
|
||||
These functions, if found in the script, will be called whenever a call to the
|
||||
matching entry point is made.
|
||||
|
||||
### Functions Exposed by the Luafilter
|
||||
|
||||
The luafilter exposes three functions that can be called from the Lua script.
|
||||
|
||||
- `string lua_qc_get_type()`
|
||||
|
||||
- Returns the type of the current query being executed as a string. The values
|
||||
are the string versions of the query types defined in _query_classifier.h_
|
||||
are separated by vertical bars (`|`).
|
||||
|
||||
This function can only be called from the `routeQuery` entry point.
|
||||
|
||||
- `string lua_qc_get_operation()`
|
||||
|
||||
- Returns the current operation type as a string. The values are defined in
|
||||
_query_classifier.h_.
|
||||
|
||||
This function can only be called from the `routeQuery` entry point.
|
||||
|
||||
- `number id_gen()`
|
||||
|
||||
- This function generates unique integers that can be used to distinct
|
||||
sessions from each other.
|
||||
|
@ -36,17 +36,19 @@
|
||||
* or diagnostic being made for the session script.
|
||||
*/
|
||||
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <maxscale/debug.h>
|
||||
#include <maxscale/log_manager.h>
|
||||
#include <maxscale/cdefs.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <string.h>
|
||||
#include <maxscale/filter.h>
|
||||
#include <maxscale/session.h>
|
||||
#include <maxscale/modutil.h>
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
#include <maxscale/alloc.h>
|
||||
#include <maxscale/debug.h>
|
||||
#include <maxscale/filter.h>
|
||||
#include <maxscale/log_manager.h>
|
||||
#include <maxscale/modutil.h>
|
||||
#include <maxscale/query_classifier.h>
|
||||
#include <maxscale/session.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
|
||||
MODULE_INFO info =
|
||||
{
|
||||
@ -126,6 +128,45 @@ static int id_gen(lua_State* state)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lua_qc_get_type(lua_State* state)
|
||||
{
|
||||
int ibuf = lua_upvalueindex(1);
|
||||
GWBUF *buf = *((GWBUF**)lua_touserdata(state, ibuf));
|
||||
|
||||
if (buf)
|
||||
{
|
||||
uint32_t type = qc_get_type(buf);
|
||||
char *mask = qc_typemask_to_string(type);
|
||||
lua_pushstring(state, mask);
|
||||
MXS_FREE(mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushliteral(state, "");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lua_qc_get_operation(lua_State* state)
|
||||
{
|
||||
int ibuf = lua_upvalueindex(1);
|
||||
GWBUF *buf = *((GWBUF**)lua_touserdata(state, ibuf));
|
||||
|
||||
if (buf)
|
||||
{
|
||||
qc_query_op_t op = qc_get_operation(buf);
|
||||
const char *opstring = qc_op_to_string(op);
|
||||
lua_pushstring(state, opstring);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushliteral(state, "");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Lua filter instance.
|
||||
*/
|
||||
@ -144,6 +185,7 @@ typedef struct
|
||||
{
|
||||
SESSION* session;
|
||||
lua_State* lua_state;
|
||||
GWBUF* current_query;
|
||||
SPINLOCK lock;
|
||||
DOWNSTREAM down;
|
||||
UPSTREAM up;
|
||||
@ -290,9 +332,20 @@ static void * newSession(FILTER *instance, SESSION *session)
|
||||
}
|
||||
else
|
||||
{
|
||||
/** Expose an ID generation function */
|
||||
lua_pushcfunction(my_session->lua_state, id_gen);
|
||||
lua_setglobal(my_session->lua_state, "id_gen");
|
||||
|
||||
/** Expose a part of the query classifier API */
|
||||
lua_pushlightuserdata(my_session->lua_state, &my_session->current_query);
|
||||
lua_pushcclosure(my_session->lua_state, lua_qc_get_type, 1);
|
||||
lua_setglobal(my_session->lua_state, "lua_qc_get_type");
|
||||
|
||||
lua_pushlightuserdata(my_session->lua_state, &my_session->current_query);
|
||||
lua_pushcclosure(my_session->lua_state, lua_qc_get_operation, 1);
|
||||
lua_setglobal(my_session->lua_state, "lua_qc_get_operation");
|
||||
|
||||
/** Call the newSession entry point */
|
||||
lua_getglobal(my_session->lua_state, "newSession");
|
||||
if (lua_pcall(my_session->lua_state, 0, 0, 0))
|
||||
{
|
||||
@ -475,6 +528,10 @@ static int routeQuery(FILTER *instance, void *session, GWBUF *queue)
|
||||
if (fullquery && my_session->lua_state)
|
||||
{
|
||||
spinlock_acquire(&my_session->lock);
|
||||
|
||||
/** Store the current query being processed */
|
||||
my_session->current_query = queue;
|
||||
|
||||
lua_getglobal(my_session->lua_state, "routeQuery");
|
||||
lua_pushlstring(my_session->lua_state, fullquery, strlen(fullquery));
|
||||
if (lua_pcall(my_session->lua_state, 1, 1, 0))
|
||||
@ -497,6 +554,9 @@ static int routeQuery(FILTER *instance, void *session, GWBUF *queue)
|
||||
route = lua_toboolean(my_session->lua_state, -1);
|
||||
}
|
||||
}
|
||||
|
||||
my_session->current_query = NULL;
|
||||
|
||||
spinlock_release(&my_session->lock);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user