# HG changeset patch # User jbe # Date 1447512293 -3600 # Node ID fb98b17056e5a255a1003f1038a3dfe8d38aca12 # Parent 11ef7ab67e43bed1758c2f403a5ce9e378926f68 Proper support for mutable data types (JSON objects/arrays) in table columns diff -r 11ef7ab67e43 -r fb98b17056e5 libraries/mondelefant/mondelefant.lua --- a/libraries/mondelefant/mondelefant.lua Sat Nov 14 14:15:31 2015 +0100 +++ b/libraries/mondelefant/mondelefant.lua Sat Nov 14 15:44:53 2015 +0100 @@ -1091,7 +1091,7 @@ if self._new then local fields = {sep = ", "} local values = {sep = ", "} - for key, dummy in pairs(self._dirty or {}) do + for key in pairs(self._dirty or {}) do add(fields, {'"$"', {key}}) add(values, {'?', self[key]}) end @@ -1130,8 +1130,16 @@ self._new = false else local command_sets = {sep = ", "} - for key, dummy in pairs(self._dirty or {}) do - add(command_sets, {'"$" = ?', {key}, self[key]}) + for key, mutability_state in pairs(self._dirty or {}) do + if + mutability_state == true or ( + verify_mutability_state and + verify_mutability_state(self[key], mutability_state) + ) + then + add(command_sets, {'"$" = ?', {key}, self[key]}) + self._dirty[key] = true -- always dirty in case of later error + end end if #command_sets >= 1 then local primary_key_compare = {sep = " AND "} @@ -1161,6 +1169,12 @@ end end end + for key in pairs(self._dirty or {}) do + if save_mutability_state then + self._dirty[key] = + save_mutability_state and save_mutability_state(self[key]) or nil + end + end return nil end --//-- diff -r 11ef7ab67e43 -r fb98b17056e5 libraries/mondelefant/mondelefant_atom_connector.lua --- a/libraries/mondelefant/mondelefant_atom_connector.lua Sat Nov 14 14:15:31 2015 +0100 +++ b/libraries/mondelefant/mondelefant_atom_connector.lua Sat Nov 14 15:44:53 2015 +0100 @@ -188,13 +188,10 @@ end function mondelefant.verify_mutability_state(value, state) - if state and tostring(value) ~= state then - return true - else - return false - end + return tostring(value) ~= state end + return _M diff -r 11ef7ab67e43 -r fb98b17056e5 libraries/mondelefant/mondelefant_native.c --- a/libraries/mondelefant/mondelefant_native.c Sat Nov 14 14:15:31 2015 +0100 +++ b/libraries/mondelefant/mondelefant_native.c Sat Nov 14 15:44:53 2015 +0100 @@ -1141,7 +1141,9 @@ // get output converter to stack position 4: lua_getfield(L, 1, "output_converter"); // get mutability state saver to stack position 5: - lua_getfield(L, 1, "save_mutability_state"); + lua_getfield(L, LUA_REGISTRYINDEX, MONDELEFANT_MODULE_REGKEY); + lua_getfield(L, -1, "save_mutability_state"); + lua_replace(L, -2); // apply output converters and fill "_data" table according to column names: for (command_idx = 0; command_idx < command_count; command_idx++) { int mode; @@ -1163,19 +1165,27 @@ for (row = 0; row < rows; row++) { lua_rawgeti(L, 6, row+1); // row at stack position 8 lua_getfield(L, 8, "_data"); // _data table at stack position 9 + lua_getfield(L, 8, "_dirty"); // _dirty table at stack position 10 for (col = 0; col < cols; col++) { - lua_rawgeti(L, 7, col+1); // this column info at position 10 - lua_getfield(L, 10, "field_name"); // 11 + lua_rawgeti(L, 7, col+1); // this column info at position 11 + lua_getfield(L, 11, "field_name"); // 12 if (lua_toboolean(L, 4)) { lua_pushvalue(L, 4); // output-converter lua_pushvalue(L, 1); // connection lua_rawgeti(L, 8, col+1); // raw-value - lua_pushvalue(L, 10); // this column info - lua_call(L, 3, 1); // converted value at position 12 + lua_pushvalue(L, 11); // this column info + lua_call(L, 3, 1); // converted value at position 13 } else { - lua_rawgeti(L, 8, col+1); // raw-value at position 12 + lua_rawgeti(L, 8, col+1); // raw-value at position 13 } - lua_pushvalue(L, 12); // 13 + if (lua_toboolean(L, 5)) { // handle mutable values? + lua_pushvalue(L, 12); // copy of field name + lua_pushvalue(L, 5); // mutability state saver function + lua_pushvalue(L, 13); // copy of value + lua_call(L, 1, 1); // calculated mutability state of value + lua_rawset(L, 10); // store mutability state in _dirty table + } + lua_pushvalue(L, 13); // 14 lua_rawseti(L, 8, col+1); lua_rawset(L, 9); lua_settop(L, 9); @@ -1184,19 +1194,27 @@ } } else { lua_getfield(L, 6, "_data"); // _data table at stack position 8 + lua_getfield(L, 6, "_dirty"); // _dirty table at stack position 9 for (col = 0; col < cols; col++) { - lua_rawgeti(L, 7, col+1); // this column info at position 9 - lua_getfield(L, 9, "field_name"); // 10 + lua_rawgeti(L, 7, col+1); // this column info at position 10 + lua_getfield(L, 10, "field_name"); // 11 if (lua_toboolean(L, 4)) { lua_pushvalue(L, 4); // output-converter lua_pushvalue(L, 1); // connection lua_rawgeti(L, 6, col+1); // raw-value - lua_pushvalue(L, 9); // this column info - lua_call(L, 3, 1); // converted value at position 11 + lua_pushvalue(L, 10); // this column info + lua_call(L, 3, 1); // converted value at position 12 } else { - lua_rawgeti(L, 6, col+1); // raw-value at position 11 + lua_rawgeti(L, 6, col+1); // raw-value at position 12 } - lua_pushvalue(L, 11); // 12 + if (lua_toboolean(L, 5)) { // handle mutable values? + lua_pushvalue(L, 11); // copy of field name + lua_pushvalue(L, 5); // mutability state saver function + lua_pushvalue(L, 12); // copy of value + lua_call(L, 1, 1); // calculated mutability state of value + lua_rawset(L, 9); // store mutability state in _dirty table + } + lua_pushvalue(L, 12); // 13 lua_rawseti(L, 6, col+1); lua_rawset(L, 8); lua_settop(L, 8);