def connect_all(self, data, query): """Applys all connects specified in the query to data. >>> p = WriteQueryProcessor(None, None) >>> data = {'a': 'foo', 'b': ['foo', 'bar']} >>> query = {'a': {'connect': 'update', 'value': 'bar'}, 'b': {'connect': 'insert', 'value': 'foobar'}} >>> p.connect_all(data, query) {'a': 'bar', 'b': ['foo', 'bar', 'foobar']} >>> query = {'a': {'connect': 'update', 'value': 'bar'}, 'b': {'connect': 'delete', 'value': 'foo'}} >>> p.connect_all(data, query) {'a': 'bar', 'b': ['bar']} >>> query = {'a': {'connect': 'update', 'value': 'bar'}, 'b': {'connect': 'update_list', 'value': ['foo', 'foobar']}} >>> p.connect_all(data, query) {'a': 'bar', 'b': ['foo', 'foobar']} """ import copy data = copy.deepcopy(data) for k, v in query.items(): if isinstance(v, dict): if 'connect' in v: if 'key' in v: value = v['key'] and common.Reference(v['key']) else: value = v['value'] self.connect(data, k, v['connect'], value) return data
def process_value(self, value, property, prefix=""): unique = property.get('unique', True) expected_type = property.expected_type.key at = {"key": self.key, "property": prefix + property.name} if isinstance(value, list): if unique is True: raise common.BadData( message='expected atom, found list', at=at, value=value ) p = web.storage(property.copy()) p.unique = True return [self.process_value(v, p) for v in value] if unique is False: raise common.BadData( message='expected list, found atom', at=at, value=value ) type_found = common.find_type(value) if expected_type in common.primitive_types: # string can be converted to any type and int can be converted to float try: if type_found == '/type/string' and expected_type != '/type/string': value = common.primitive_types[expected_type](value) elif type_found == '/type/int' and expected_type == '/type/float': value = float(value) except ValueError as e: raise common.BadData(message=str(e), at=at, value=value) elif property.expected_type.kind == 'embeddable': if isinstance(value, dict): return self.process_data( value, property.expected_type, prefix=at['property'] + "." ) else: raise common.TypeMismatch(expected_type, type_found, at=at, value=value) else: if type_found == '/type/string': value = common.Reference(value) type_found = common.find_type(value) if type_found == '/type/object': type_found = self.get_type(value) # type is not found only when the thing id not found. if type_found is None: raise common.NotFound(key=text_type(value), at=at) if expected_type != type_found: raise common.BadData( message='expected %s, found %s' % (property.expected_type.key, type_found), at=at, value=value, ) return value
def remove_connects(self, query): for k, v in query.items(): if isinstance(v, dict) and 'connect' in v: if 'key' in v: value = v['key'] and common.Reference(v['key']) else: value = v['value'] query[k] = value return query
def process_data(self, d, type, old_data=None, prefix=""): for k, v in d.items(): if v is None or v == [] or web.safeunicode(v).strip() == '': del d[k] else: if old_data and old_data.get(k) == v: continue p = self.get_property(type, k) if p: d[k] = self.process_value(v, p, prefix=prefix) else: d[k] = v if type: d['type'] = common.Reference(type.key) return d
def process_data(self, d, type, old_data=None, prefix=""): for k, v in list(d.items()): # Avoid dictionary changed size during iteration if v in (None, []) or web.safeunicode(v).strip() == '': del d[k] else: if old_data and old_data.get(k) == v: continue p = self.get_property(type, k) if p: d[k] = self.process_value(v, p, prefix=prefix) else: d[k] = v if type: d['type'] = common.Reference(type.key) return d