webmcp
changeset 436:1dbbe4c62f08
Methods :create_object() and :create_list() ignore any additional table argument; "_class" attribute is always set; "_col" proxy respects foreign keys
author | jbe |
---|---|
date | Wed Jan 20 20:43:23 2016 +0100 (2016-01-20) |
parents | f704f35923e2 |
children | b4aac2bdc33d |
files | libraries/mondelefant/mondelefant_native.autodoc.lua libraries/mondelefant/mondelefant_native.c |
line diff
1.1 --- a/libraries/mondelefant/mondelefant_native.autodoc.lua Sat Jan 16 04:44:16 2016 +0100 1.2 +++ b/libraries/mondelefant/mondelefant_native.autodoc.lua Wed Jan 20 20:43:23 2016 +0100 1.3 @@ -96,7 +96,7 @@ 1.4 db_list = -- database result being an empty list 1.5 <db_handle>:create_list() 1.6 1.7 -Creates an empty database result representing a list. The used meta-table is "result_metatable". The attribute "_connection" is set to the database handle, and the attribute "_type" is set to "list". 1.8 +Creates an empty database result representing a list. The used meta-table is "result_metatable". The attribute "_connection" is set to the database handle, and the attribute "_type" is set to "list". The attribute "_class" is initialized to the default class prototype "class_prototype" of the module. 1.9 1.10 --]]-- 1.11 -- implemented in mondelefant_native.c as 1.12 @@ -108,7 +108,7 @@ 1.13 db_object = -- database result being an empty object (row) 1.14 <db_handle>:create_object() 1.15 1.16 -Creates an empty database result representing an object (row). The used meta-table is "result_metatable". The attribute "_connection" is set to the database handle, and the attribute "_type" is set to "object". Additionally the attributes "_data", "_dirty" and "_ref" are initialized with an empty table. TODO: Documentation of _data, _dirty and _ref. 1.17 +Creates an empty database result representing an object (row). The used meta-table is "result_metatable". The attribute "_connection" is set to the database handle, and the attribute "_type" is set to "object". The attribute "_class" is initialized to the default class prototype "class_prototype" of the module. Additionally the attribute "_col" is set to a proxy table, and the attributes "_data", "_dirty" and "_ref" are initialized with an empty table. TODO: Documentation of _data, _dirty and _ref. 1.18 1.19 --]]-- 1.20 -- implemented in mondelefant_native.c as
2.1 --- a/libraries/mondelefant/mondelefant_native.c Sat Jan 16 04:44:16 2016 +0100 2.2 +++ b/libraries/mondelefant/mondelefant_native.c Wed Jan 20 20:43:23 2016 +0100 2.3 @@ -534,14 +534,9 @@ 2.4 static int mondelefant_conn_create_list(lua_State *L) { 2.5 // ensure that first argument is a database connection: 2.6 luaL_checkudata(L, 1, MONDELEFANT_CONN_MT_REGKEY); 2.7 - // if no second argument is given, use an empty table: 2.8 - if (lua_isnoneornil(L, 2)) { 2.9 - lua_settop(L, 1); 2.10 - lua_newtable(L); // 2 2.11 - } else { 2.12 - luaL_checktype(L, 2, LUA_TTABLE); 2.13 - lua_settop(L, 2); 2.14 - } 2.15 + // create new table on stack position 2: 2.16 + lua_settop(L, 1); 2.17 + lua_newtable(L); // 2 2.18 // set meta-table for database result lists/objects: 2.19 luaL_setmetatable(L, MONDELEFANT_RESULT_MT_REGKEY); 2.20 // set "_connection" attribute to self: 2.21 @@ -550,6 +545,9 @@ 2.22 // set "_type" attribute to string "list": 2.23 lua_pushliteral(L, "list"); // 3 2.24 lua_setfield(L, 2, "_type"); 2.25 + // set "_class" attribute to default class: 2.26 + lua_getfield(L, LUA_REGISTRYINDEX, MONDELEFANT_CLASS_PROTO_REGKEY); // 3 2.27 + lua_setfield(L, 2, "_class"); 2.28 // return created database result list: 2.29 return 1; 2.30 } 2.31 @@ -558,14 +556,9 @@ 2.32 static int mondelefant_conn_create_object(lua_State *L) { 2.33 // ensure that first argument is a database connection: 2.34 luaL_checkudata(L, 1, MONDELEFANT_CONN_MT_REGKEY); 2.35 - // if no second argument is given, use an empty table: 2.36 - if (lua_isnoneornil(L, 2)) { 2.37 - lua_settop(L, 1); 2.38 - lua_newtable(L); // 2 2.39 - } else { 2.40 - luaL_checktype(L, 2, LUA_TTABLE); 2.41 - lua_settop(L, 2); 2.42 - } 2.43 + // create new table on stack position 2: 2.44 + lua_settop(L, 1); 2.45 + lua_newtable(L); // 2 2.46 // set meta-table for database result lists/objects: 2.47 luaL_setmetatable(L, MONDELEFANT_RESULT_MT_REGKEY); 2.48 // set "_connection" attribute to self: 2.49 @@ -574,6 +567,9 @@ 2.50 // set "_type" attribute to string "object": 2.51 lua_pushliteral(L, "object"); // 3 2.52 lua_setfield(L, 2, "_type"); // "object" or "list" 2.53 + // set "_class" attribute to default class: 2.54 + lua_getfield(L, LUA_REGISTRYINDEX, MONDELEFANT_CLASS_PROTO_REGKEY); // 3 2.55 + lua_setfield(L, 2, "_class"); 2.56 // create empty tables for "_data", "_dirty" and "_ref" attributes: 2.57 lua_newtable(L); // 3 2.58 lua_setfield(L, 2, "_data"); 2.59 @@ -1596,13 +1592,9 @@ 2.60 if (lua_type(L, 2) != LUA_TSTRING || lua_tostring(L, 2)[0] == '_') { 2.61 return 0; 2.62 } 2.63 - // value of "_class" attribute or default class on stack position 3: 2.64 + // class on stack position 3: 2.65 lua_settop(L, 2); 2.66 lua_getfield(L, 1, "_class"); // 3 2.67 - if (!lua_toboolean(L, 3)) { 2.68 - lua_settop(L, 2); 2.69 - lua_getfield(L, LUA_REGISTRYINDEX, MONDELEFANT_CLASS_PROTO_REGKEY); // 3 2.70 - } 2.71 // get value of "_type" attribute: 2.72 lua_getfield(L, 1, "_type"); // 4 2.73 result_type = lua_tostring(L, 4); 2.74 @@ -1734,13 +1726,9 @@ 2.75 lua_rawset(L, 1); 2.76 return 1; 2.77 } 2.78 - // value of "_class" attribute or default class on stack position 4: 2.79 + // class on stack position 4: 2.80 lua_settop(L, 3); 2.81 lua_getfield(L, 1, "_class"); // 4 2.82 - if (!lua_toboolean(L, 4)) { 2.83 - lua_settop(L, 3); 2.84 - lua_getfield(L, LUA_REGISTRYINDEX, MONDELEFANT_CLASS_PROTO_REGKEY); // 4 2.85 - } 2.86 // get value of "_type" attribute: 2.87 lua_getfield(L, 1, "_type"); // 5 2.88 result_type = lua_tostring(L, 5); 2.89 @@ -1845,6 +1833,37 @@ 2.90 luaL_checktype(L, 1, LUA_TTABLE); 2.91 lua_settop(L, 2); 2.92 lua_rawgetp(L, 1, MONDELEFANT_COLUMNS_RESULT_LUKEY); // 3 2.93 + // try primary keys of referenced objects: 2.94 + lua_pushcfunction(L, 2.95 + mondelefant_class_get_foreign_key_reference_name 2.96 + ); // 4 2.97 + lua_getfield(L, 3, "_class"); // 5 2.98 + lua_pushvalue(L, 2); // 6 2.99 + lua_call(L, 2, 1); // 4 2.100 + if (!lua_isnil(L, 4)) { 2.101 + // reference name at stack position 4 2.102 + lua_pushcfunction(L, mondelefant_class_get_reference); // 5 2.103 + lua_getfield(L, 3, "_class"); // 6 2.104 + lua_pushvalue(L, 4); // 7 2.105 + lua_call(L, 2, 1); // reference info at stack position 5 2.106 + lua_getfield(L, 3, "_ref"); // 6 2.107 + lua_getfield(L, 5, "ref"); // 7 2.108 + lua_gettable(L, 6); // 7 2.109 + if (!lua_isnil(L, 7)) { 2.110 + if (lua_toboolean(L, 7)) { 2.111 + lua_getfield(L, 5, "that_key"); // 8 2.112 + if (lua_isnil(L, 8)) { 2.113 + return luaL_error(L, "Missing 'that_key' entry in model reference."); 2.114 + } 2.115 + lua_gettable(L, 7); // 8 2.116 + } else { 2.117 + lua_pushnil(L); 2.118 + } 2.119 + return 1; 2.120 + } 2.121 + } 2.122 + lua_settop(L, 3); 2.123 + // if not successful, use _data table: 2.124 lua_getfield(L, 3, "_data"); // 4 2.125 lua_pushvalue(L, 2); // 5 2.126 lua_gettable(L, 4); // 5 2.127 @@ -1856,6 +1875,21 @@ 2.128 luaL_checktype(L, 1, LUA_TTABLE); 2.129 lua_settop(L, 3); 2.130 lua_rawgetp(L, 1, MONDELEFANT_COLUMNS_RESULT_LUKEY); // 4 2.131 + // reset reference cache, if neccessary: 2.132 + lua_pushcfunction(L, 2.133 + mondelefant_class_get_foreign_key_reference_name 2.134 + ); // 5 2.135 + lua_getfield(L, 4, "_class"); // 6 2.136 + lua_pushvalue(L, 2); // 7 2.137 + lua_call(L, 2, 1); // 5 2.138 + if (!lua_isnil(L, 5)) { 2.139 + lua_getfield(L, 4, "_ref"); // 6 2.140 + lua_pushvalue(L, 5); // 7 2.141 + lua_pushnil(L); // 8 2.142 + lua_settable(L, 6); 2.143 + } 2.144 + lua_settop(L, 4); 2.145 + // set _data and _dirty: 2.146 lua_getfield(L, 4, "_data"); // 5 2.147 lua_getfield(L, 4, "_dirty"); // 6 2.148 lua_pushvalue(L, 2);