def _update_tables(self, thing_id, key, olddata, newdata): def find_datatype(value): if isinstance(value, common.Text): return 'text' elif isinstance(value, common.Reference): return 'ref' elif isinstance(value, bool): return 'boolean' elif isinstance(value, float): return 'float' elif isinstance(value, int): return 'int' else: return 'str' def do_action(f, typekey, thing_id, name, value, ordering=None): if isinstance(value, list): for i, v in enumerate(value): do_action(f, typekey, thing_id, name, v, i) elif isinstance(value, dict): for k, v in value.items(): do_action(f, typekey, thing_id, name + '.' + k, v, ordering) else: datatype = find_datatype(value) if datatype == 'ref': value = self.get_metadata(value) value = value and value.id elif datatype == 'str': value = value[:2048] # truncate long strings elif isinstance(value, bool): value = "ft"[int(value)] # convert boolean to 't' or 'f' table = self.schema.find_table(typekey, datatype, name) if table: type_id = self.get_metadata(typekey).id pid = self.get_property_id(type_id, name, create=True) assert pid is not None f(table, thing_id, pid, value, ordering) def action_delete(table, thing_id, key_id, value, ordering): self.db.delete(table, where='thing_id=$thing_id AND key_id=$key_id', vars=locals()) def action_insert(table, thing_id, key_id, value, ordering): self.db.insert(table, seqname=False, thing_id=thing_id, key_id=key_id, value=value, ordering=ordering) old_type = (olddata and olddata['type']) or None new_type = newdata['type'] def _coerce(d): if isinstance(d, dict) and 'key' in d: return d['key'] else: return d old_type = _coerce(old_type) new_type = _coerce(new_type) for k in ['id', 'key', 'type', 'last_modified', 'created', 'revision']: olddata.pop(k, None) newdata.pop(k, None) removed, unchanged, added = common.dict_diff(olddata, newdata) if old_type != new_type: removed = olddata.keys() added = newdata.keys() for k in removed: do_action(action_delete, old_type, thing_id, k, olddata[k]) for k in added: do_action(action_insert, new_type, thing_id, k, newdata[k])