# HG changeset patch # User jbe # Date 1452364176 -3600 # Node ID 04692707527036401bd6a7802b15456870aaf4b1 # Parent 0dff5e2f659cbf776414e5a65362bb93d34b3eca Proxy table to directly access column-values of a database row (e.g. if document_column is set or for reserved method names) diff -r 0dff5e2f659c -r 046927075270 libraries/mondelefant/mondelefant_native.autodoc.lua --- a/libraries/mondelefant/mondelefant_native.autodoc.lua Sat Jan 09 17:32:30 2016 +0100 +++ b/libraries/mondelefant/mondelefant_native.autodoc.lua Sat Jan 09 19:29:36 2016 +0100 @@ -331,3 +331,15 @@ -- static int mondelefant_class_get_reference(lua_State *L) --//-- + +--[[-- +.columns -- proxy table mapping column names to their values + +This attribute can be used to access column values directly (helpful if :document_column is set). Currently pairs(...) and ipairs(...) are not implemented on this proxy table. + +--]]-- +-- implemented in mondelefant_native.c as +-- static const struct luaL_Reg mondelefant_columns_mt_functions[] +-- +--//-- + diff -r 0dff5e2f659c -r 046927075270 libraries/mondelefant/mondelefant_native.c --- a/libraries/mondelefant/mondelefant_native.c Sat Jan 09 17:32:30 2016 +0100 +++ b/libraries/mondelefant/mondelefant_native.c Sat Jan 09 19:29:36 2016 +0100 @@ -23,6 +23,14 @@ #define MONDELEFANT_CLASS_MT_REGKEY (MONDELEFANT_REGKEY "class") // registry key of default prototype for models/classes: #define MONDELEFANT_CLASS_PROTO_REGKEY (MONDELEFANT_REGKEY "class_proto") +// registry key of meta-table for column proxy: +#define MONDELEFANT_COLUMNS_MT_REGKEY (MONDELEFANT_REGKEY "columns") +// table (lightuserdata) key to store result object in column proxy: +// (address of struct used as unique reference) +#define MONDELEFANT_COLUMNS_RESULT_LUKEY ((void *)&mondelefant_columns_result_lukey_dummy) + +// dummy variable for MONDELEFANT_COLUMNS_RESULT_LUKEY reference: +char mondelefant_columns_result_lukey_dummy; // C-structure for database connection userdata: typedef struct { @@ -573,7 +581,13 @@ lua_setfield(L, 2, "_dirty"); lua_newtable(L); // 3 lua_setfield(L, 2, "_ref"); // nil=no info, false=nil, else table - // return created database result object: + // create column proxy (field "columns" in result object): + lua_newtable(L); // 3 + luaL_setmetatable(L, MONDELEFANT_COLUMNS_MT_REGKEY); + lua_pushvalue(L, 2); // 4 + lua_rawsetp(L, 3, MONDELEFANT_COLUMNS_RESULT_LUKEY); + lua_setfield(L, 2, "columns"); + // return created database result object (from stack position 2): return 1; } @@ -1825,6 +1839,33 @@ } } +// meta-method "__index" of column proxy: +static int mondelefant_columns_index(lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); + lua_rawgetp(L, 1, MONDELEFANT_COLUMNS_RESULT_LUKEY); // 3 + lua_getfield(L, 3, "_data"); // 4 + lua_pushvalue(L, 2); // 5 + lua_gettable(L, 4); // 5 + return 1; +} + +// meta-method "__newindex" of column proxy: +static int mondelefant_columns_newindex(lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 3); + lua_rawgetp(L, 1, MONDELEFANT_COLUMNS_RESULT_LUKEY); // 4 + lua_getfield(L, 4, "_data"); // 5 + lua_getfield(L, 4, "_dirty"); // 6 + lua_pushvalue(L, 2); + lua_pushvalue(L, 3); + lua_settable(L, 5); + lua_pushvalue(L, 2); + lua_pushboolean(L, 1); + lua_settable(L, 6); + return 0; +} + // meta-method "__index" of classes (models): static int mondelefant_class_index(lua_State *L) { // perform lookup in prototype: @@ -1888,7 +1929,7 @@ {NULL, NULL} }; -// registration information for methods of database result lists/objects: +// registration information for meta-methods of classes (models): static const struct luaL_Reg mondelefant_class_mt_functions[] = { {"__index", mondelefant_class_index}, {NULL, NULL} @@ -1913,9 +1954,21 @@ {NULL, NULL} }; +// registration information for meta-methods of column proxy: +static const struct luaL_Reg mondelefant_columns_mt_functions[] = { + {"__index", mondelefant_columns_index}, + {"__newindex", mondelefant_columns_newindex}, + {NULL, NULL} +}; + // luaopen function to initialize/register library: int luaopen_mondelefant_native(lua_State *L) { lua_settop(L, 0); + + lua_newtable(L); // meta-table for columns proxy + luaL_setfuncs(L, mondelefant_columns_mt_functions, 0); + lua_setfield(L, LUA_REGISTRYINDEX, MONDELEFANT_COLUMNS_MT_REGKEY); + lua_newtable(L); // module at stack position 1 luaL_setfuncs(L, mondelefant_module_functions, 0);