/* $%BEGINLICENSE%$ Copyright (C) 2008 MySQL AB, 2008 Sun Microsystems, Inc This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA $%ENDLICENSE%$ */ #include #include "lua-env.h" #include "glib-ext.h" #define C(x) x, sizeof(x) - 1 #define S(x) x->str, x->len #include "sql-tokenizer.h" static int proxy_tokenize_token_get(lua_State *L) { sql_token *token = *(sql_token **)luaL_checkself(L); size_t keysize; const char *key = luaL_checklstring(L, 2, &keysize); if (strleq(key, keysize, C("text"))) { lua_pushlstring(L, S(token->text)); return 1; } else if (strleq(key, keysize, C("token_id"))) { lua_pushinteger(L, token->token_id); return 1; } else if (strleq(key, keysize, C("token_name"))) { lua_pushstring(L, sql_token_get_name(token->token_id)); return 1; } else { luaL_error(L, "tokens[...] has no %s field", key); } return 0; } int sql_tokenizer_lua_token_getmetatable(lua_State *L) { static const struct luaL_reg methods[] = { { "__index", proxy_tokenize_token_get }, { NULL, NULL }, }; return proxy_getmetatable(L, methods); } static int proxy_tokenize_get(lua_State *L) { GPtrArray *tokens = *(GPtrArray **)luaL_checkself(L); int ndx = luaL_checkinteger(L, 2); sql_token *token; sql_token **token_p; if (tokens->len > G_MAXINT) { return 0; } /* lua uses 1 is starting index */ if (ndx < 1 || ndx > (int)tokens->len) { return 0; } token = tokens->pdata[ndx - 1]; token_p = lua_newuserdata(L, sizeof(token)); /* (sp += 1) */ *token_p = token; sql_tokenizer_lua_token_getmetatable(L); lua_setmetatable(L, -2); /* tie the metatable to the udata (sp -= 1) */ return 1; } static int proxy_tokenize_len(lua_State *L) { GPtrArray *tokens = *(GPtrArray **)luaL_checkself(L); lua_pushinteger(L, tokens->len); return 1; } static int proxy_tokenize_gc(lua_State *L) { GPtrArray *tokens = *(GPtrArray **)luaL_checkself(L); sql_tokens_free(tokens); return 0; } static int sql_tokenizer_lua_getmetatable(lua_State *L) { static const struct luaL_reg methods[] = { { "__index", proxy_tokenize_get }, { "__len", proxy_tokenize_len }, { "__gc", proxy_tokenize_gc }, { NULL, NULL }, }; return proxy_getmetatable(L, methods); } /** * split the SQL query into a stream of tokens */ int proxy_tokenize(lua_State *L) { size_t str_len; const char *str = luaL_checklstring(L, 1, &str_len); GPtrArray *tokens = sql_tokens_new(); GPtrArray **tokens_p; sql_tokenizer(tokens, str, str_len); tokens_p = lua_newuserdata(L, sizeof(tokens)); /* (sp += 1) */ *tokens_p = tokens; sql_tokenizer_lua_getmetatable(L); lua_setmetatable(L, -2); /* tie the metatable to the udata (sp -= 1) */ return 1; } /* ** Assumes the table is on top of the stack. */ static void set_info (lua_State *L) { lua_pushliteral (L, "_COPYRIGHT"); lua_pushliteral (L, "Copyright (C) 2008 MySQL AB, 2008 Sun Microsystems, Inc"); lua_settable (L, -3); lua_pushliteral (L, "_DESCRIPTION"); lua_pushliteral (L, "a simple tokenizer for mysql.*"); lua_settable (L, -3); lua_pushliteral (L, "_VERSION"); lua_pushliteral (L, "LuaMySQLTokenizer 0.1"); lua_settable (L, -3); } static const struct luaL_reg mysql_tokenizerlib[] = { {"tokenize", proxy_tokenize}, {NULL, NULL}, }; #if defined(_WIN32) # define LUAEXT_API __declspec(dllexport) #else # define LUAEXT_API extern #endif LUAEXT_API int luaopen_mysql_tokenizer (lua_State *L) { luaL_register (L, "tokenizer", mysql_tokenizerlib); set_info (L); return 1; }