# HG changeset patch # User jbe # Date 1447708795 -3600 # Node ID 3fffd1ae5a68596b511f330fdd3809313e326225 # Parent f0ac171edf62ecc1fdfe45ca55351a251caa2075 New implementation of (proxy) write access to fields of JSON object in a special column diff -r f0ac171edf62 -r 3fffd1ae5a68 libraries/mondelefant/mondelefant_native.c --- a/libraries/mondelefant/mondelefant_native.c Mon Nov 16 21:18:56 2015 +0100 +++ b/libraries/mondelefant/mondelefant_native.c Mon Nov 16 22:19:55 2015 +0100 @@ -1478,7 +1478,7 @@ if (lua_type(L, 2) != LUA_TSTRING || lua_tostring(L, 2)[0] == '_') { return 0; } - // value of "_class" attribute or default class:on stack position 3: + // value of "_class" attribute or default class on stack position 3: lua_settop(L, 2); lua_getfield(L, 1, "_class"); // 3 if (!lua_toboolean(L, 3)) { @@ -1494,8 +1494,8 @@ // different lookup for lists and objects: if (result_type && !strcmp(result_type, "object")) { // object lua_settop(L, 3); + // try inherited attributes, methods or getter functions: lua_pushvalue(L, 3); // 4 - // try inherited attributes, methods or getter functions: while (lua_toboolean(L, 4)) { lua_getfield(L, 4, "object"); // 5 lua_pushvalue(L, 2); // 6 @@ -1620,7 +1620,8 @@ lua_rawset(L, 1); return 1; } - // get value of "_class" attribute, or default class, when unset: + // value of "_class" attribute or default class on stack position 4: + lua_settop(L, 3); lua_getfield(L, 1, "_class"); // 4 if (!lua_toboolean(L, 4)) { lua_settop(L, 3); @@ -1636,76 +1637,94 @@ if (result_type && !strcmp(result_type, "object")) { // objects lua_settop(L, 4); // try object setter functions: - while (lua_toboolean(L, 4)) { - lua_getfield(L, 4, "object_set"); // 5 - lua_pushvalue(L, 2); // 6 - lua_gettable(L, 5); // 6 - if (lua_toboolean(L, 6)) { - lua_pushvalue(L, 1); // 7 - lua_pushvalue(L, 3); // 8 + lua_pushvalue(L, 4); // 5 + while (lua_toboolean(L, 5)) { + lua_getfield(L, 5, "object_set"); // 6 + lua_pushvalue(L, 2); // 7 + lua_gettable(L, 6); // 7 + if (lua_toboolean(L, 7)) { + lua_pushvalue(L, 1); // 8 + lua_pushvalue(L, 3); // 9 lua_call(L, 2, 0); return 0; } - lua_settop(L, 4); - lua_pushliteral(L, "prototype"); // 5 - lua_rawget(L, 4); // 5 - lua_replace(L, 4); + lua_settop(L, 5); + lua_pushliteral(L, "prototype"); // 6 + lua_rawget(L, 5); // 6 + lua_replace(L, 5); } - lua_settop(L, 3); + lua_settop(L, 4); + lua_getfield(L, 1, "_data"); // _data table on stack position 5 // check, if a object reference is changed: - lua_pushcfunction(L, mondelefant_class_get_reference); // 4 - lua_getfield(L, 1, "_class"); // 5 - lua_pushvalue(L, 2); // 6 - lua_call(L, 2, 1); // 4 - if (!lua_isnil(L, 4)) { + lua_pushcfunction(L, mondelefant_class_get_reference); // 6 + lua_pushvalue(L, 4); // 7 + lua_pushvalue(L, 2); // 8 + lua_call(L, 2, 1); // 6 + if (!lua_isnil(L, 6)) { // store object in _ref table (use false for nil): // TODO: use special object instead of false - lua_getfield(L, 1, "_ref"); // 5 - lua_pushvalue(L, 2); // 6 - if (lua_isnil(L, 3)) lua_pushboolean(L, 0); // 7 - else lua_pushvalue(L, 3); // 7 - lua_settable(L, 5); - lua_settop(L, 4); + lua_getfield(L, 1, "_ref"); // 7 + lua_pushvalue(L, 2); // 8 + if (lua_isnil(L, 3)) lua_pushboolean(L, 0); // 9 + else lua_pushvalue(L, 3); // 9 + lua_settable(L, 7); + lua_settop(L, 6); // delete referencing key from _data table: - lua_getfield(L, 4, "this_key"); // 5 - if (lua_isnil(L, 5)) { + lua_getfield(L, 6, "this_key"); // 7 + if (lua_isnil(L, 7)) { return luaL_error(L, "Missing 'this_key' entry in model reference."); } - lua_getfield(L, 1, "_data"); // 6 + lua_pushvalue(L, 7); // 8 + lua_pushnil(L); // 9 + lua_settable(L, 5); + lua_getfield(L, 1, "_dirty"); // 8 + lua_pushvalue(L, 7); // 9 + lua_pushboolean(L, 1); // 10 + lua_settable(L, 8); + return 0; + } + lua_settop(L, 5); + // check proxy access to document in special column: + lua_getfield(L, 4, "document_column"); // 6 + if (lua_toboolean(L, 6)) { + lua_getfield(L, 1, "_column_info"); // 7 + lua_pushvalue(L, 2); // 8 + lua_gettable(L, 7); // 8 + if (lua_toboolean(L, 8)) { + lua_settop(L, 6); + lua_gettable(L, 5); // 6 + if (lua_isnil(L, 6)) { + return luaL_error(L, "Cannot write to document column: document is nil"); + } + lua_pushvalue(L, 2); // 7 + lua_pushvalue(L, 3); // 8 + lua_settable(L, 6); + return 0; + } + } + lua_settop(L, 5); + // store value in data field info: + lua_pushvalue(L, 2); // 6 + lua_pushvalue(L, 3); // 7 + lua_settable(L, 5); + lua_settop(L, 4); + // mark field as dirty (needs to be UPDATEd on save): + lua_getfield(L, 1, "_dirty"); // 5 + lua_pushvalue(L, 2); // 6 + lua_pushboolean(L, 1); // 7 + lua_settable(L, 5); + lua_settop(L, 4); + // reset reference cache, if neccessary: + lua_pushcfunction(L, + mondelefant_class_get_foreign_key_reference_name + ); // 5 + lua_pushvalue(L, 4); // 6 + lua_pushvalue(L, 2); // 7 + lua_call(L, 2, 1); // 5 + if (!lua_isnil(L, 5)) { + lua_getfield(L, 1, "_ref"); // 6 lua_pushvalue(L, 5); // 7 lua_pushnil(L); // 8 lua_settable(L, 6); - lua_settop(L, 5); - lua_getfield(L, 1, "_dirty"); // 6 - lua_pushvalue(L, 5); // 7 - lua_pushboolean(L, 1); // 8 - lua_settable(L, 6); - return 0; - } - lua_settop(L, 3); - // store value in data field info: - lua_getfield(L, 1, "_data"); // 4 - lua_pushvalue(L, 2); // 5 - lua_pushvalue(L, 3); // 6 - lua_settable(L, 4); - lua_settop(L, 3); - // mark field as dirty (needs to be UPDATEd on save): - lua_getfield(L, 1, "_dirty"); // 4 - lua_pushvalue(L, 2); // 5 - lua_pushboolean(L, 1); // 6 - lua_settable(L, 4); - lua_settop(L, 3); - // reset reference cache, if neccessary: - lua_pushcfunction(L, - mondelefant_class_get_foreign_key_reference_name - ); // 4 - lua_getfield(L, 1, "_class"); // 5 - lua_pushvalue(L, 2); // 6 - lua_call(L, 2, 1); // 4 - if (!lua_isnil(L, 4)) { - lua_getfield(L, 1, "_ref"); // 5 - lua_pushvalue(L, 4); // 6 - lua_pushnil(L); // 7 - lua_settable(L, 5); } return 0; } else { // non-objects (i.e. lists)