Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
 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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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