Beispiel #1
0
 def __init__(self, defaults: Dict = None):
     self.defaults = {
         datetime: lambda x: TimeUtils.to_timestamp(x),
         date: lambda x: TimeUtils.to_timestamp(x),
         UUID: lambda x: x.hex,
         set: lambda x: list(x),
         DictObject: lambda x: x.to_dict(),
     }
     self.defaults.update(defaults or {})
Beispiel #2
0
 def process(self, value):
     if isinstance(value, (int, float)):
         return (value, None)
     elif isinstance(value, datetime):
         return (TimeUtils.to_timestamp(value), None)
     elif isinstance(value, date):
         return (time.mktime(value.timetuple()), None)
     else:
         return (None, UNRECOGNIZED_VALUE)
Beispiel #3
0
class NumericIndex(RangeIndex):
    custom_serializers = {
        UUID: lambda x: int(x.hex, 16),
        datetime: lambda x: TimeUtils.to_timestamp(x),
        bool: lambda x: int(x),
    }

    def upsert(self, _id, value, pipe=None):
        redis = pipe if pipe is not None else self.redis
        ser = self.custom_serializers.get(value.__class__)
        value = ser(value) if ser else value

        redis.zrem(self.name, _id)
        redis.zadd(self.name, {_id: value})

    def delete(self, _id, pipe=None):
        redis = pipe if pipe is not None else self.redis
        redis.zrem(self.name, _id)

    def delete_many(self, _ids, pipe=None):
        if isinstance(_ids, GeneratorType):
            _ids = tuple(_ids)
        if _ids:
            redis = pipe if pipe is not None else self.redis
            redis.zrem(self.name, *_ids)

    def search(self,
               lower=None,
               upper=None,
               include_lower=True,
               include_upper=False,
               offset=None,
               limit=None,
               pipe=None):
        if lower is not None:
            lower = '({}'.format(lower) if not include_lower else lower
        else:
            lower = '-inf'

        if upper is not None:
            upper = '({}'.format(upper) if not include_upper else upper
        else:
            upper = '+inf'

        if limit is not None and offset is None:
            offset = 0

        redis = pipe if pipe is not None else self.redis

        return [
            v.split(self.DELIM_BYTES)[-1] for v in redis.zrangebyscore(
                self.name, lower, upper, start=offset, num=limit)
        ]
Beispiel #4
0
    def build_response_message(self, message: Message,
                               source: Dict) -> Message:
        """
        Recursively bind each value in a source dict to the corresponding
        attribute in a grpc Message object, resulting in the prepared response
        message, ready to be sent back to the client.
        """
        if source is None:
            return None

        for k, v in source.items():
            if v is None:
                # protobufs don't understand null values
                continue

            # TODO: move conversion logic into adapters
            if isinstance(v, (date, datetime)):
                ts = TimeUtils.to_timestamp(v)
                setattr(message, k, ts)
            elif isinstance(getattr(message, k), Message):
                sub_message = getattr(message, k)
                assert isinstance(v, dict)
                self.build_response_message(sub_message, v)
            elif isinstance(v, dict):
                json_str = self.json.encode(v)
                setattr(message, k, json_str)
            elif isinstance(v, (list, tuple, set)):
                list_field = getattr(message, k)
                sub_message_type_name = ('{}Schema'.format(k.title().replace(
                    '_', '')))
                sub_message_type = getattr(message, sub_message_type_name,
                                           None)
                if sub_message_type:
                    list_field.extend(
                        self.build_response_message(sub_message_type(), v_i)
                        for v_i in v)
                else:
                    v_prime = [
                        x if not isinstance(x, dict) else self.json.encode(x)
                        for x in v
                    ]
                    list_field.extend(v_prime)
            else:
                setattr(message, k, v)

        return message
Beispiel #5
0
 def on_generate(self, **kwargs):
     return TimeUtils.to_timestamp(
         self.faker.date_time_this_year(tzinfo=pytz.utc))