webmcp
changeset 375:fb98b17056e5
Proper support for mutable data types (JSON objects/arrays) in table columns
author | jbe |
---|---|
date | Sat Nov 14 15:44:53 2015 +0100 (2015-11-14) |
parents | 11ef7ab67e43 |
children | 4bcedf32b089 |
files | libraries/mondelefant/mondelefant.lua libraries/mondelefant/mondelefant_atom_connector.lua libraries/mondelefant/mondelefant_native.c |
line diff
1.1 --- a/libraries/mondelefant/mondelefant.lua Sat Nov 14 14:15:31 2015 +0100 1.2 +++ b/libraries/mondelefant/mondelefant.lua Sat Nov 14 15:44:53 2015 +0100 1.3 @@ -1091,7 +1091,7 @@ 1.4 if self._new then 1.5 local fields = {sep = ", "} 1.6 local values = {sep = ", "} 1.7 - for key, dummy in pairs(self._dirty or {}) do 1.8 + for key in pairs(self._dirty or {}) do 1.9 add(fields, {'"$"', {key}}) 1.10 add(values, {'?', self[key]}) 1.11 end 1.12 @@ -1130,8 +1130,16 @@ 1.13 self._new = false 1.14 else 1.15 local command_sets = {sep = ", "} 1.16 - for key, dummy in pairs(self._dirty or {}) do 1.17 - add(command_sets, {'"$" = ?', {key}, self[key]}) 1.18 + for key, mutability_state in pairs(self._dirty or {}) do 1.19 + if 1.20 + mutability_state == true or ( 1.21 + verify_mutability_state and 1.22 + verify_mutability_state(self[key], mutability_state) 1.23 + ) 1.24 + then 1.25 + add(command_sets, {'"$" = ?', {key}, self[key]}) 1.26 + self._dirty[key] = true -- always dirty in case of later error 1.27 + end 1.28 end 1.29 if #command_sets >= 1 then 1.30 local primary_key_compare = {sep = " AND "} 1.31 @@ -1161,6 +1169,12 @@ 1.32 end 1.33 end 1.34 end 1.35 + for key in pairs(self._dirty or {}) do 1.36 + if save_mutability_state then 1.37 + self._dirty[key] = 1.38 + save_mutability_state and save_mutability_state(self[key]) or nil 1.39 + end 1.40 + end 1.41 return nil 1.42 end 1.43 --//--
2.1 --- a/libraries/mondelefant/mondelefant_atom_connector.lua Sat Nov 14 14:15:31 2015 +0100 2.2 +++ b/libraries/mondelefant/mondelefant_atom_connector.lua Sat Nov 14 15:44:53 2015 +0100 2.3 @@ -188,13 +188,10 @@ 2.4 end 2.5 2.6 function mondelefant.verify_mutability_state(value, state) 2.7 - if state and tostring(value) ~= state then 2.8 - return true 2.9 - else 2.10 - return false 2.11 - end 2.12 + return tostring(value) ~= state 2.13 end 2.14 2.15 + 2.16 return _M 2.17 2.18
3.1 --- a/libraries/mondelefant/mondelefant_native.c Sat Nov 14 14:15:31 2015 +0100 3.2 +++ b/libraries/mondelefant/mondelefant_native.c Sat Nov 14 15:44:53 2015 +0100 3.3 @@ -1141,7 +1141,9 @@ 3.4 // get output converter to stack position 4: 3.5 lua_getfield(L, 1, "output_converter"); 3.6 // get mutability state saver to stack position 5: 3.7 - lua_getfield(L, 1, "save_mutability_state"); 3.8 + lua_getfield(L, LUA_REGISTRYINDEX, MONDELEFANT_MODULE_REGKEY); 3.9 + lua_getfield(L, -1, "save_mutability_state"); 3.10 + lua_replace(L, -2); 3.11 // apply output converters and fill "_data" table according to column names: 3.12 for (command_idx = 0; command_idx < command_count; command_idx++) { 3.13 int mode; 3.14 @@ -1163,19 +1165,27 @@ 3.15 for (row = 0; row < rows; row++) { 3.16 lua_rawgeti(L, 6, row+1); // row at stack position 8 3.17 lua_getfield(L, 8, "_data"); // _data table at stack position 9 3.18 + lua_getfield(L, 8, "_dirty"); // _dirty table at stack position 10 3.19 for (col = 0; col < cols; col++) { 3.20 - lua_rawgeti(L, 7, col+1); // this column info at position 10 3.21 - lua_getfield(L, 10, "field_name"); // 11 3.22 + lua_rawgeti(L, 7, col+1); // this column info at position 11 3.23 + lua_getfield(L, 11, "field_name"); // 12 3.24 if (lua_toboolean(L, 4)) { 3.25 lua_pushvalue(L, 4); // output-converter 3.26 lua_pushvalue(L, 1); // connection 3.27 lua_rawgeti(L, 8, col+1); // raw-value 3.28 - lua_pushvalue(L, 10); // this column info 3.29 - lua_call(L, 3, 1); // converted value at position 12 3.30 + lua_pushvalue(L, 11); // this column info 3.31 + lua_call(L, 3, 1); // converted value at position 13 3.32 } else { 3.33 - lua_rawgeti(L, 8, col+1); // raw-value at position 12 3.34 + lua_rawgeti(L, 8, col+1); // raw-value at position 13 3.35 } 3.36 - lua_pushvalue(L, 12); // 13 3.37 + if (lua_toboolean(L, 5)) { // handle mutable values? 3.38 + lua_pushvalue(L, 12); // copy of field name 3.39 + lua_pushvalue(L, 5); // mutability state saver function 3.40 + lua_pushvalue(L, 13); // copy of value 3.41 + lua_call(L, 1, 1); // calculated mutability state of value 3.42 + lua_rawset(L, 10); // store mutability state in _dirty table 3.43 + } 3.44 + lua_pushvalue(L, 13); // 14 3.45 lua_rawseti(L, 8, col+1); 3.46 lua_rawset(L, 9); 3.47 lua_settop(L, 9); 3.48 @@ -1184,19 +1194,27 @@ 3.49 } 3.50 } else { 3.51 lua_getfield(L, 6, "_data"); // _data table at stack position 8 3.52 + lua_getfield(L, 6, "_dirty"); // _dirty table at stack position 9 3.53 for (col = 0; col < cols; col++) { 3.54 - lua_rawgeti(L, 7, col+1); // this column info at position 9 3.55 - lua_getfield(L, 9, "field_name"); // 10 3.56 + lua_rawgeti(L, 7, col+1); // this column info at position 10 3.57 + lua_getfield(L, 10, "field_name"); // 11 3.58 if (lua_toboolean(L, 4)) { 3.59 lua_pushvalue(L, 4); // output-converter 3.60 lua_pushvalue(L, 1); // connection 3.61 lua_rawgeti(L, 6, col+1); // raw-value 3.62 - lua_pushvalue(L, 9); // this column info 3.63 - lua_call(L, 3, 1); // converted value at position 11 3.64 + lua_pushvalue(L, 10); // this column info 3.65 + lua_call(L, 3, 1); // converted value at position 12 3.66 } else { 3.67 - lua_rawgeti(L, 6, col+1); // raw-value at position 11 3.68 + lua_rawgeti(L, 6, col+1); // raw-value at position 12 3.69 } 3.70 - lua_pushvalue(L, 11); // 12 3.71 + if (lua_toboolean(L, 5)) { // handle mutable values? 3.72 + lua_pushvalue(L, 11); // copy of field name 3.73 + lua_pushvalue(L, 5); // mutability state saver function 3.74 + lua_pushvalue(L, 12); // copy of value 3.75 + lua_call(L, 1, 1); // calculated mutability state of value 3.76 + lua_rawset(L, 9); // store mutability state in _dirty table 3.77 + } 3.78 + lua_pushvalue(L, 12); // 13 3.79 lua_rawseti(L, 6, col+1); 3.80 lua_rawset(L, 8); 3.81 lua_settop(L, 8);