scalar function to be called ** callback params: context, values... */
| 969 | /* scalar function to be called |
| 970 | ** callback params: context, values... */ |
| 971 | static void db_sql_normal_function(sqlite3_context *context, int argc, sqlite3_value **argv) { |
| 972 | sdb_func *func = (sdb_func*)sqlite3_user_data(context); |
| 973 | lua_State *L = func->db->L; |
| 974 | int n; |
| 975 | lcontext *ctx; |
| 976 | |
| 977 | int top = lua_gettop(L); |
| 978 | |
| 979 | /* ensure there is enough space in the stack */ |
| 980 | lua_checkstack(L, argc + 3); |
| 981 | |
| 982 | lua_rawgeti(L, LUA_REGISTRYINDEX, func->fn_step); /* function to call */ |
| 983 | |
| 984 | if (!func->aggregate) { |
| 985 | ctx = lsqlite_make_context(L); /* push context - used to set results */ |
| 986 | } |
| 987 | else { |
| 988 | /* reuse context userdata value */ |
| 989 | void *p = sqlite3_aggregate_context(context, 1); |
| 990 | /* i think it is OK to use assume that using a light user data |
| 991 | ** as an entry on LUA REGISTRY table will be unique */ |
| 992 | lua_pushlightuserdata(L, p); |
| 993 | lua_rawget(L, LUA_REGISTRYINDEX); /* context table */ |
| 994 | |
| 995 | if (lua_isnil(L, -1)) { /* not yet created? */ |
| 996 | lua_pop(L, 1); |
| 997 | ctx = lsqlite_make_context(L); |
| 998 | lua_pushlightuserdata(L, p); |
| 999 | lua_pushvalue(L, -2); |
| 1000 | lua_rawset(L, LUA_REGISTRYINDEX); |
| 1001 | } |
| 1002 | else |
| 1003 | ctx = lsqlite_getcontext(L, -1); |
| 1004 | } |
| 1005 | |
| 1006 | /* push params */ |
| 1007 | for (n = 0; n < argc; ++n) { |
| 1008 | db_push_value(L, argv[n]); |
| 1009 | } |
| 1010 | |
| 1011 | /* set context */ |
| 1012 | ctx->ctx = context; |
| 1013 | |
| 1014 | if (lua_pcall(L, argc + 1, 0, 0)) { |
| 1015 | const char *errmsg = lua_tostring(L, -1); |
| 1016 | int size = lua_strlen(L, -1); |
| 1017 | sqlite3_result_error(context, errmsg, size); |
| 1018 | } |
| 1019 | |
| 1020 | /* invalidate context */ |
| 1021 | ctx->ctx = NULL; |
| 1022 | |
| 1023 | if (!func->aggregate) { |
| 1024 | luaL_unref(L, LUA_REGISTRYINDEX, ctx->ud); |
| 1025 | } |
| 1026 | |
| 1027 | lua_settop(L, top); |
| 1028 | } |
nothing calls this directly
no test coverage detected