webmcp
changeset 384:3fffd1ae5a68
New implementation of (proxy) write access to fields of JSON object in a special column
author | jbe |
---|---|
date | Mon Nov 16 22:19:55 2015 +0100 (2015-11-16) |
parents | f0ac171edf62 |
children | ea3a8c6509ba |
files | libraries/mondelefant/mondelefant_native.c |
line diff
1.1 --- a/libraries/mondelefant/mondelefant_native.c Mon Nov 16 21:18:56 2015 +0100 1.2 +++ b/libraries/mondelefant/mondelefant_native.c Mon Nov 16 22:19:55 2015 +0100 1.3 @@ -1478,7 +1478,7 @@ 1.4 if (lua_type(L, 2) != LUA_TSTRING || lua_tostring(L, 2)[0] == '_') { 1.5 return 0; 1.6 } 1.7 - // value of "_class" attribute or default class:on stack position 3: 1.8 + // value of "_class" attribute or default class on stack position 3: 1.9 lua_settop(L, 2); 1.10 lua_getfield(L, 1, "_class"); // 3 1.11 if (!lua_toboolean(L, 3)) { 1.12 @@ -1494,8 +1494,8 @@ 1.13 // different lookup for lists and objects: 1.14 if (result_type && !strcmp(result_type, "object")) { // object 1.15 lua_settop(L, 3); 1.16 + // try inherited attributes, methods or getter functions: 1.17 lua_pushvalue(L, 3); // 4 1.18 - // try inherited attributes, methods or getter functions: 1.19 while (lua_toboolean(L, 4)) { 1.20 lua_getfield(L, 4, "object"); // 5 1.21 lua_pushvalue(L, 2); // 6 1.22 @@ -1620,7 +1620,8 @@ 1.23 lua_rawset(L, 1); 1.24 return 1; 1.25 } 1.26 - // get value of "_class" attribute, or default class, when unset: 1.27 + // value of "_class" attribute or default class on stack position 4: 1.28 + lua_settop(L, 3); 1.29 lua_getfield(L, 1, "_class"); // 4 1.30 if (!lua_toboolean(L, 4)) { 1.31 lua_settop(L, 3); 1.32 @@ -1636,76 +1637,94 @@ 1.33 if (result_type && !strcmp(result_type, "object")) { // objects 1.34 lua_settop(L, 4); 1.35 // try object setter functions: 1.36 - while (lua_toboolean(L, 4)) { 1.37 - lua_getfield(L, 4, "object_set"); // 5 1.38 - lua_pushvalue(L, 2); // 6 1.39 - lua_gettable(L, 5); // 6 1.40 - if (lua_toboolean(L, 6)) { 1.41 - lua_pushvalue(L, 1); // 7 1.42 - lua_pushvalue(L, 3); // 8 1.43 + lua_pushvalue(L, 4); // 5 1.44 + while (lua_toboolean(L, 5)) { 1.45 + lua_getfield(L, 5, "object_set"); // 6 1.46 + lua_pushvalue(L, 2); // 7 1.47 + lua_gettable(L, 6); // 7 1.48 + if (lua_toboolean(L, 7)) { 1.49 + lua_pushvalue(L, 1); // 8 1.50 + lua_pushvalue(L, 3); // 9 1.51 lua_call(L, 2, 0); 1.52 return 0; 1.53 } 1.54 - lua_settop(L, 4); 1.55 - lua_pushliteral(L, "prototype"); // 5 1.56 - lua_rawget(L, 4); // 5 1.57 - lua_replace(L, 4); 1.58 + lua_settop(L, 5); 1.59 + lua_pushliteral(L, "prototype"); // 6 1.60 + lua_rawget(L, 5); // 6 1.61 + lua_replace(L, 5); 1.62 } 1.63 - lua_settop(L, 3); 1.64 + lua_settop(L, 4); 1.65 + lua_getfield(L, 1, "_data"); // _data table on stack position 5 1.66 // check, if a object reference is changed: 1.67 - lua_pushcfunction(L, mondelefant_class_get_reference); // 4 1.68 - lua_getfield(L, 1, "_class"); // 5 1.69 - lua_pushvalue(L, 2); // 6 1.70 - lua_call(L, 2, 1); // 4 1.71 - if (!lua_isnil(L, 4)) { 1.72 + lua_pushcfunction(L, mondelefant_class_get_reference); // 6 1.73 + lua_pushvalue(L, 4); // 7 1.74 + lua_pushvalue(L, 2); // 8 1.75 + lua_call(L, 2, 1); // 6 1.76 + if (!lua_isnil(L, 6)) { 1.77 // store object in _ref table (use false for nil): // TODO: use special object instead of false 1.78 - lua_getfield(L, 1, "_ref"); // 5 1.79 - lua_pushvalue(L, 2); // 6 1.80 - if (lua_isnil(L, 3)) lua_pushboolean(L, 0); // 7 1.81 - else lua_pushvalue(L, 3); // 7 1.82 - lua_settable(L, 5); 1.83 - lua_settop(L, 4); 1.84 + lua_getfield(L, 1, "_ref"); // 7 1.85 + lua_pushvalue(L, 2); // 8 1.86 + if (lua_isnil(L, 3)) lua_pushboolean(L, 0); // 9 1.87 + else lua_pushvalue(L, 3); // 9 1.88 + lua_settable(L, 7); 1.89 + lua_settop(L, 6); 1.90 // delete referencing key from _data table: 1.91 - lua_getfield(L, 4, "this_key"); // 5 1.92 - if (lua_isnil(L, 5)) { 1.93 + lua_getfield(L, 6, "this_key"); // 7 1.94 + if (lua_isnil(L, 7)) { 1.95 return luaL_error(L, "Missing 'this_key' entry in model reference."); 1.96 } 1.97 - lua_getfield(L, 1, "_data"); // 6 1.98 + lua_pushvalue(L, 7); // 8 1.99 + lua_pushnil(L); // 9 1.100 + lua_settable(L, 5); 1.101 + lua_getfield(L, 1, "_dirty"); // 8 1.102 + lua_pushvalue(L, 7); // 9 1.103 + lua_pushboolean(L, 1); // 10 1.104 + lua_settable(L, 8); 1.105 + return 0; 1.106 + } 1.107 + lua_settop(L, 5); 1.108 + // check proxy access to document in special column: 1.109 + lua_getfield(L, 4, "document_column"); // 6 1.110 + if (lua_toboolean(L, 6)) { 1.111 + lua_getfield(L, 1, "_column_info"); // 7 1.112 + lua_pushvalue(L, 2); // 8 1.113 + lua_gettable(L, 7); // 8 1.114 + if (lua_toboolean(L, 8)) { 1.115 + lua_settop(L, 6); 1.116 + lua_gettable(L, 5); // 6 1.117 + if (lua_isnil(L, 6)) { 1.118 + return luaL_error(L, "Cannot write to document column: document is nil"); 1.119 + } 1.120 + lua_pushvalue(L, 2); // 7 1.121 + lua_pushvalue(L, 3); // 8 1.122 + lua_settable(L, 6); 1.123 + return 0; 1.124 + } 1.125 + } 1.126 + lua_settop(L, 5); 1.127 + // store value in data field info: 1.128 + lua_pushvalue(L, 2); // 6 1.129 + lua_pushvalue(L, 3); // 7 1.130 + lua_settable(L, 5); 1.131 + lua_settop(L, 4); 1.132 + // mark field as dirty (needs to be UPDATEd on save): 1.133 + lua_getfield(L, 1, "_dirty"); // 5 1.134 + lua_pushvalue(L, 2); // 6 1.135 + lua_pushboolean(L, 1); // 7 1.136 + lua_settable(L, 5); 1.137 + lua_settop(L, 4); 1.138 + // reset reference cache, if neccessary: 1.139 + lua_pushcfunction(L, 1.140 + mondelefant_class_get_foreign_key_reference_name 1.141 + ); // 5 1.142 + lua_pushvalue(L, 4); // 6 1.143 + lua_pushvalue(L, 2); // 7 1.144 + lua_call(L, 2, 1); // 5 1.145 + if (!lua_isnil(L, 5)) { 1.146 + lua_getfield(L, 1, "_ref"); // 6 1.147 lua_pushvalue(L, 5); // 7 1.148 lua_pushnil(L); // 8 1.149 lua_settable(L, 6); 1.150 - lua_settop(L, 5); 1.151 - lua_getfield(L, 1, "_dirty"); // 6 1.152 - lua_pushvalue(L, 5); // 7 1.153 - lua_pushboolean(L, 1); // 8 1.154 - lua_settable(L, 6); 1.155 - return 0; 1.156 - } 1.157 - lua_settop(L, 3); 1.158 - // store value in data field info: 1.159 - lua_getfield(L, 1, "_data"); // 4 1.160 - lua_pushvalue(L, 2); // 5 1.161 - lua_pushvalue(L, 3); // 6 1.162 - lua_settable(L, 4); 1.163 - lua_settop(L, 3); 1.164 - // mark field as dirty (needs to be UPDATEd on save): 1.165 - lua_getfield(L, 1, "_dirty"); // 4 1.166 - lua_pushvalue(L, 2); // 5 1.167 - lua_pushboolean(L, 1); // 6 1.168 - lua_settable(L, 4); 1.169 - lua_settop(L, 3); 1.170 - // reset reference cache, if neccessary: 1.171 - lua_pushcfunction(L, 1.172 - mondelefant_class_get_foreign_key_reference_name 1.173 - ); // 4 1.174 - lua_getfield(L, 1, "_class"); // 5 1.175 - lua_pushvalue(L, 2); // 6 1.176 - lua_call(L, 2, 1); // 4 1.177 - if (!lua_isnil(L, 4)) { 1.178 - lua_getfield(L, 1, "_ref"); // 5 1.179 - lua_pushvalue(L, 4); // 6 1.180 - lua_pushnil(L); // 7 1.181 - lua_settable(L, 5); 1.182 } 1.183 return 0; 1.184 } else { // non-objects (i.e. lists)