示例#1
0
 def multi(self):
     if self.explicit_transaction:
         raise RedisError('Cannot issue nested calls to MULTI')
     if self.command_stack:
         raise RedisError(
             'Commands without an initial WATCH have already been issued')
     self.explicit_transaction = True
示例#2
0
    def __init__(self,
                 ssl_keyfile=None,
                 ssl_certfile=None,
                 ssl_cert_reqs='required',
                 ssl_ca_certs=None,
                 **kwargs):
        if not ssl_available:
            raise RedisError("Python wasn't built with SSL support")

        super(SSLConnection, self).__init__(**kwargs)

        self.keyfile = ssl_keyfile
        self.certfile = ssl_certfile
        if ssl_cert_reqs is None:
            ssl_cert_reqs = ssl.CERT_NONE
        elif isinstance(ssl_cert_reqs, basestring):
            CERT_REQS = {
                'none': ssl.CERT_NONE,
                'optional': ssl.CERT_OPTIONAL,
                'required': ssl.CERT_REQUIRED
            }
            if ssl_cert_reqs not in CERT_REQS:
                raise RedisError(
                    "Invalid SSL Certificate Requirements Flag: %s" %
                    ssl_cert_reqs)
            ssl_cert_reqs = CERT_REQS[ssl_cert_reqs]
        self.cert_reqs = ssl_cert_reqs
        self.ca_certs = ssl_ca_certs
示例#3
0
 def multi(self):
     """
     Start a transactional block of the pipeline after WATCH commands are issued. End the transactional block with `execute`.
     """
     if self.explicit_transaction:
         raise RedisError('Cannot issue nested calls to MULTI')
     if self.command_stack:
         raise RedisError(
             'Commands without an initial WATCH have already been issued')
     self.explicit_transaction = True
示例#4
0
    def cluster_setslot(self, target_node, node_id, slot_id, state):
        """
        Bind an hash slot to a specific node

        :target_node: 'ClusterNode'
            The node to execute the command on
        """
        if state.upper() in ("IMPORTING", "NODE", "MIGRATING"):
            return self.execute_command(
                "CLUSTER SETSLOT", slot_id, state, node_id, target_nodes=target_node
            )
        elif state.upper() == "STABLE":
            raise RedisError('For "stable" state please use ' "cluster_setslot_stable")
        else:
            raise RedisError(f"Invalid slot state: {state}")
示例#5
0
    def zrevrangebyscore(self,
                         name,
                         max,
                         min,
                         start=None,
                         num=None,
                         withscores=False):
        """
        Return a range of values from the sorted set ``name`` with scores
        between ``min`` and ``max`` in descending order.

        If ``start`` and ``num`` are specified, then return a slice
        of the range.

        ``withscores`` indicates to return the scores along with the values.
        The return type is a list of (value, score) pairs
        """
        if (start is not None and num is None) or \
                (num is not None and start is None):
            raise RedisError("``start`` and ``num`` must both be specified")
        pieces = ['ZREVRANGEBYSCORE', name, max, min]
        if start is not None and num is not None:
            pieces.extend(['LIMIT', start, num])
        if withscores:
            pieces.append('withscores')
        return self.execute_command(*pieces, **{'withscores': withscores})
示例#6
0
    async def get_keys(self, *args: Any) -> Optional[Tuple[str, ...]]:
        if len(args) < 2:
            # The command has no keys in it
            return None

        try:
            command = self.commands[args[0]]
        except KeyError:
            # try to split the command name and to take only the main command
            # e.g. 'memory' for 'memory usage'
            args = args[0].split() + list(args[1:])
            cmd_name = args[0]
            if cmd_name not in self.commands:
                # We'll try to reinitialize the commands cache, if the engine
                # version has changed, the commands may not be current
                await self.initialize()
                if cmd_name not in self.commands:
                    raise RedisError(
                        f"{cmd_name.upper()} command doesn't exist in Redis commands"
                    )

            command = self.commands[cmd_name]

        if command == 1:
            return (args[1],)
        if command == 0:
            return None
        if command == -1:
            return await self._get_moveable_keys(*args)

        last_key_pos = command["last_key_pos"]
        if last_key_pos < 0:
            last_key_pos = len(args) + last_key_pos
        return args[command["first_key_pos"] : last_key_pos + 1 : command["step_count"]]
示例#7
0
    def zadd(self, name, *args, **kwargs):
        """
        NOTE: The order of arguments differs from that of the official ZADD
        command. For backwards compatability, this method accepts arguments
        in the form of name1, score1, name2, score2, while the official Redis
        documents expects score1, name1, score2, name2.
        If you're looking to use the standard syntax, consider using the
        StrictRedis class. See the API Reference section of the docs for more
        information.
        Set any number of element-name, score pairs to the key ``name``. Pairs
        can be specified in two ways:
        As *args, in the form of: name1, score1, name2, score2, ...
        or as **kwargs, in the form of: name1=score1, name2=score2, ...
        The following example would add four values to the 'my-key' key:
        redis.zadd('my-key', 'name1', 1.1, 'name2', 2.2, name3=3.3, name4=4.4)
        """
        pieces = []

        if args:
            if len(args) % 2 != 0:
                raise RedisError(
                    "ZADD requires an equal number of values and scores")
            pieces.extend(reversed(args))

        for pair in iteritems(kwargs):
            pieces.append(pair[1])
            pieces.append(pair[0])

        return self.execute_command('ZADD', name, *pieces)
示例#8
0
    def coerce_zadd_args(*args, **kwargs):
        """
        Take arguments attended by a zadd call, named or not, and return a flat list
        that can be used.
        A callback can be called with all "values" (as *args) if defined as the
        `values_callback` named argument. Real values will then be the result of
        this callback.
        """
        values_callback = kwargs.pop('values_callback', None)

        pieces = []
        if args:
            if len(args) % 2 != 0:
                raise RedisError("ZADD requires an equal number of "
                                 "values and scores")
            pieces.extend(args)

        for pair in iteritems(kwargs):
            pieces.append(pair[1])
            pieces.append(pair[0])

        values = pieces[1::2]
        if values_callback:
            values = values_callback(*values)

        scores = pieces[0::2]

        pieces = []
        for z in zip(scores, values):
            pieces.extend(z)

        return pieces
示例#9
0
    def sort(self,
             name,
             start=None,
             num=None,
             by=None,
             get=None,
             desc=False,
             alpha=False,
             store=None):
        """
        Sort and return the list, set or sorted set at ``name``.

        ``start`` and ``num`` allow for paging through the sorted data

        ``by`` allows using an external key to weight and sort the items.
            Use an "*" to indicate where in the key the item value is located

        ``get`` allows for returning items from external keys rather than the
            sorted data itself.  Use an "*" to indicate where int he key
            the item value is located

        ``desc`` allows for reversing the sort

        ``alpha`` allows for sorting lexicographically rather than numerically

        ``store`` allows for storing the result of the sort into
            the key ``store``
        """
        if (start is not None and num is None) or \
                (num is not None and start is None):
            raise RedisError("``start`` and ``num`` must both be specified")

        pieces = [name]
        if by is not None:
            pieces.append('BY')
            pieces.append(by)
        if start is not None and num is not None:
            pieces.append('LIMIT')
            pieces.append(start)
            pieces.append(num)
        if get is not None:
            # If get is a string assume we want to get a single value.
            # Otherwise assume it's an interable and we want to get multiple
            # values. We can't just iterate blindly because strings are
            # iterable.
            if isinstance(get, basestring):
                pieces.append('GET')
                pieces.append(get)
            else:
                for g in get:
                    pieces.append('GET')
                    pieces.append(g)
        if desc:
            pieces.append('DESC')
        if alpha:
            pieces.append('ALPHA')
        if store is not None:
            pieces.append('STORE')
            pieces.append(store)
        return self.execute_command('SORT', *pieces)
示例#10
0
def load_redis_engine():
    redis_url = urlparse.urlparse(settings.REDISTOGO_URL)
    if redis_url.scheme == "redis":
        engine = RedisEngine(host=redis_url.hostname,
                             port=redis_url.port,
                             password=redis_url.password)
        try:
            info = engine.client.info()
            if "db0" in info:
                nb_keys = info["db0"]["keys"]
            else:
                nb_keys = 0
            print "Conn. Redis server, %s keys stored." % nb_keys
            return engine
        except ConnectionError:
            if settings.DEBUG:
                raise ConnectionError("Redis Server is not reachable.")
            else:
                return None
    else:
        if settings.DEBUG:
            raise RedisError("Redis Server '%s' URL is not valid." %
                             settings.REDISTOGO_URL)
        else:
            return None
示例#11
0
    def zadd(self, *args, **kwargs):
        """
        Parse args and kwargs to check values to pass them through the
        from_python method.
        We pass the parsed args/kwargs as args in the super call, to avoid
        doing the same calculation on kwargs one more time.
        """
        pieces = []
        if args:
            if len(args) % 2 != 0:
                raise RedisError("ZADD requires an equal number of "
                                 "values and scores")
            pieces.extend(args)
        for pair in kwargs.iteritems():
            pieces.append(pair[1])
            pieces.append(pair[0])

        values = self.from_python(pieces[1::2])
        scores = pieces[0::2]

        pieces = []
        for z in zip(scores, values):
            pieces.extend(z)

        return super(M2MSortedSetField, self).zadd(*pieces)
示例#12
0
    def __init__(self, socket_read_size):
        if not HIREDIS_AVAILABLE:
            raise RedisError("Hiredis is not installed")
        self.socket_read_size = socket_read_size

        if HIREDIS_USE_BYTE_BUFFER:
            self._buffer = bytearray(socket_read_size)
示例#13
0
 def shutdown(self):
     "Shutdown the server"
     try:
         self.execute_command('SHUTDOWN')
     except ConnectionError:
         # a ConnectionError here is expected
         return
     raise RedisError("SHUTDOWN seems to have failed.")
示例#14
0
    def mset(self, *args, **kwargs):
        if args:
            if len(args) != 1 or not isinstance(args[0], dict):
                raise RedisError('MSET requires **kwargs or a single dict arg')
            kwargs.update(args[0])

        mapping = {self.appendKeys(key): value for key, value in iteritems(kwargs)}
        return self.redis.mset(mapping)
示例#15
0
    def test_on_redis_errors_raises_RedisError(self, Queue):
        """On Redis connection errors, exceptions subclasses of `RedisError` will be raised."""
        Queue.all.side_effect = RedisError('Connection error')

        with self.assertRaises(RedisError):
            get_jobs_by_queue()

        Queue.all.assert_called_once_with()
示例#16
0
    def test_on_redis_errors_raises_RedisError(self, Queue):
        """On Redis connection errors, exceptions subclasses of `RedisError` will be raised."""
        type(Queue.return_value).count = PropertyMock(
            side_effect=RedisError('Connection error'))

        with self.assertRaises(RedisError):
            get_queue_jobs('queue_name')

        Queue.assert_called_once_with('queue_name')
示例#17
0
    def cluster_setslot(
        self, target_node: "TargetNodesT", node_id: str, slot_id: int, state: str
    ) -> ResponseT:
        """
        Bind an hash slot to a specific node

        :target_node: 'ClusterNode'
            The node to execute the command on

        For more information see https://redis.io/commands/cluster-setslot
        """
        if state.upper() in ("IMPORTING", "NODE", "MIGRATING"):
            return self.execute_command(
                "CLUSTER SETSLOT", slot_id, state, node_id, target_nodes=target_node
            )
        elif state.upper() == "STABLE":
            raise RedisError('For "stable" state please use ' "cluster_setslot_stable")
        else:
            raise RedisError(f"Invalid slot state: {state}")
示例#18
0
def DefaultSelector(sock):
    "Return the best selector for the platform"
    global _DEFAULT_SELECTOR
    if _DEFAULT_SELECTOR is None:
        if has_selector('poll'):
            _DEFAULT_SELECTOR = PollSelector
        elif hasattr(select, 'select'):
            _DEFAULT_SELECTOR = SelectSelector
        else:
            raise RedisError('Platform does not support any selectors')
    return _DEFAULT_SELECTOR(sock)
示例#19
0
 def cluster_setslot(self, node_id, slot_id, state, bind_to_node_id=None):
     """Bind an hash slot to a specific node"""
     if state.upper() in ('IMPORTING', 'MIGRATING',
                          'NODE') and node_id is not None:
         return self.execute_command('CLUSTER SETSLOT', slot_id,
                                     Token(state), node_id)
     elif state.upper() == 'STABLE':
         return self.execute_command('CLUSTER SETSLOT', slot_id,
                                     Token('STABLE'))
     else:
         raise RedisError('Invalid slot state: {0}'.format(state))
示例#20
0
def acquire_lock(lock, degrade_gracefully, **kwargs):
    acquired = False
    try:
        acquired = lock.acquire(**kwargs)
    except RedisError:
        if degrade_gracefully:
            lock = None
        else:
            raise
    if lock and not acquired and not degrade_gracefully:
        raise RedisError("Unable to acquire lock")
    return lock
示例#21
0
    async def bitpos(cls, key, bit, start=None, end=None):
        """
        Return the position of the first bit set to 1 or 0 in a string.
        ``start`` and ``end`` difines search range. The range is interpreted
        as a range of bytes and not a range of bits, so start=0 and end=2
        means to look at the first three bytes.
        """
        key = cls.__coll__ + key
        if bit not in (0, 1):
            raise RedisError('bit must be 0 or 1')
        params = [key, bit]

        start is not None and params.append(start)

        if start is not None and end is not None:
            params.append(end)
        elif start is None and end is not None:
            raise RedisError("start argument is not set, "
                             "when end is specified")

        return await cls.Execute('BITPOS', *params)
示例#22
0
    def get_keys(self, redis_conn, *args):
        """
        Get the keys from the passed command.

        NOTE: Due to a bug in redis<7.0, this function does not work properly
        for EVAL or EVALSHA when the `numkeys` arg is 0.
         - issue: https://github.com/redis/redis/issues/9493
         - fix: https://github.com/redis/redis/pull/9733

        So, don't use this function with EVAL or EVALSHA.
        """
        if len(args) < 2:
            # The command has no keys in it
            return None

        cmd_name = args[0].lower()
        if cmd_name not in self.commands:
            # try to split the command name and to take only the main command,
            # e.g. 'memory' for 'memory usage'
            cmd_name_split = cmd_name.split()
            cmd_name = cmd_name_split[0]
            if cmd_name in self.commands:
                # save the splitted command to args
                args = cmd_name_split + list(args[1:])
            else:
                # We'll try to reinitialize the commands cache, if the engine
                # version has changed, the commands may not be current
                self.initialize(redis_conn)
                if cmd_name not in self.commands:
                    raise RedisError(
                        f"{cmd_name.upper()} command doesn't exist in Redis commands"
                    )

        command = self.commands.get(cmd_name)
        if "movablekeys" in command["flags"]:
            keys = self._get_moveable_keys(redis_conn, *args)
        elif "pubsub" in command["flags"]:
            keys = self._get_pubsub_keys(*args)
        else:
            if (command["step_count"] == 0 and command["first_key_pos"] == 0
                    and command["last_key_pos"] == 0):
                # The command doesn't have keys in it
                return None
            last_key_pos = command["last_key_pos"]
            if last_key_pos < 0:
                last_key_pos = len(args) - abs(last_key_pos)
            keys_pos = list(
                range(command["first_key_pos"], last_key_pos + 1,
                      command["step_count"]))
            keys = [args[pos] for pos in keys_pos]

        return keys
示例#23
0
 def bitcount(self, key, start=None, end=None):
     """
     Returns the count of set bits in the value of ``key``.  Optional
     ``start`` and ``end`` paramaters indicate which bytes to consider
     """
     params = [key]
     if start is not None and end is not None:
         params.append(start)
         params.append(end)
     elif (start is not None and end is None) or \
             (end is not None and start is None):
         raise RedisError("Both start and end must be specified")
     return self.Execute('BITCOUNT', *params)
示例#24
0
    def mset(self, *args, **kwargs):
        """
        Sets key/values based on a mapping. Mapping can be supplied as a single
        dictionary argument or as kwargs.

        Cluster impl: Itterate over all items and do SET on each (k,v) pair
        """
        if args:
            if len(args) != 1 or not isinstance(args[0], dict):
                raise RedisError('MSET requires **kwargs or a single dict arg')
            kwargs.update(args[0])
        for pair in iteritems(kwargs):
            self.set(pair[0], pair[1])
        return True
示例#25
0
 def validate(self, attr):
     uuid = attr.get("image_code_id")
     image_code_test = attr.get("text")
     cur = get_redis_connection("code")
     image_code = cur.get("image_code_%s" % uuid)
     try:
         cur.delete("image_code_%s" % uuid)
     except RedisError as e:
         logger.error(e)
     if not image_code:
         raise RedisError("验证码已过期!")
     if image_code.decode().lower() != image_code_test.lower():
         return Response("验证码错误!", status=400)
     return attr
示例#26
0
    def cluster_failover(self, node_id, option=None):
        """
        Forces a slave to perform a manual failover of its master

        Sends to specefied node
        """
        if option:
            if option.upper() not in ['FORCE', 'TAKEOVER']:
                raise RedisError(
                    'Invalid option for CLUSTER FAILOVER command: {0}'.format(
                        option))
            else:
                return self.execute_command('CLUSTER FAILOVER',
                                            option,
                                            node_id=node_id)
        else:
            return self.execute_command('CLUSTER FAILOVER', node_id=node_id)
示例#27
0
文件: client.py 项目: tcpavel/tweeql
    def sort(self,
             name,
             start=None,
             num=None,
             by=None,
             get=None,
             desc=False,
             alpha=False,
             store=None):
        """
        Sort and return the list, set or sorted set at ``name``.
        
        ``start`` and ``num`` allow for paging through the sorted data
        
        ``by`` allows using an external key to weight and sort the items.
            Use an "*" to indicate where in the key the item value is located
            
        ``get`` allows for returning items from external keys rather than the
            sorted data itself.  Use an "*" to indicate where int he key
            the item value is located
            
        ``desc`` allows for reversing the sort
        
        ``alpha`` allows for sorting lexicographically rather than numerically
        
        ``store`` allows for storing the result of the sort into 
            the key ``store``
        """
        if (start is not None and num is None) or \
                (num is not None and start is None):
            raise RedisError("``start`` and ``num`` must both be specified")

        pieces = [name]
        if by is not None:
            pieces.append('BY %s' % by)
        if start is not None and num is not None:
            pieces.append('LIMIT %s %s' % (start, num))
        if get is not None:
            pieces.append('GET %s' % get)
        if desc:
            pieces.append('DESC')
        if alpha:
            pieces.append('ALPHA')
        if store is not None:
            pieces.append('STORE %s' % store)
        return self.format_inline('SORT', *pieces)
示例#28
0
文件: parser.py 项目: Vi-l-uc/TeleBot
    def get_keys(self, redis_conn, *args):
        """
        Get the keys from the passed command
        """
        if len(args) < 2:
            # The command has no keys in it
            return None

        cmd_name = args[0].lower()
        if cmd_name not in self.commands:
            # try to split the command name and to take only the main command,
            # e.g. 'memory' for 'memory usage'
            cmd_name_split = cmd_name.split()
            cmd_name = cmd_name_split[0]
            if cmd_name in self.commands:
                # save the splitted command to args
                args = cmd_name_split + list(args[1:])
            else:
                # We'll try to reinitialize the commands cache, if the engine
                # version has changed, the commands may not be current
                self.initialize(redis_conn)
                if cmd_name not in self.commands:
                    raise RedisError(
                        f"{cmd_name.upper()} command doesn't exist in Redis commands"
                    )

        command = self.commands.get(cmd_name)
        if "movablekeys" in command["flags"]:
            keys = self._get_moveable_keys(redis_conn, *args)
        elif "pubsub" in command["flags"]:
            keys = self._get_pubsub_keys(*args)
        else:
            if (command["step_count"] == 0 and command["first_key_pos"] == 0
                    and command["last_key_pos"] == 0):
                # The command doesn't have keys in it
                return None
            last_key_pos = command["last_key_pos"]
            if last_key_pos < 0:
                last_key_pos = len(args) - abs(last_key_pos)
            keys_pos = list(
                range(command["first_key_pos"], last_key_pos + 1,
                      command["step_count"]))
            keys = [args[pos] for pos in keys_pos]

        return keys
示例#29
0
 def execute_command(self, *args, **options):
     """
     重写该命令,主要是为了检测Redis命令的长度
     最长不能超过128字节,防止代码Bug导致Key特别长
     """
     # 有些key直接传递的整形等,可以直接忽略
     if len(args) > 2 and isinstance(args[1], str):
         # 第一个参数为Redis的命令,第二个参数为key名字
         redis_command_key = args[1]
         try:
             command_key_length = len(redis_command_key)
             if command_key_length > 128:
                 raise RedisError(
                     "redis key is too long, please fix: %s-%s" %
                     (redis_command_key, command_key_length))
         except RedisError:
             pass
     return super(CustomRedis, self).execute_command(*args, **options)
示例#30
0
    def cluster_failover(self, target_node, option=None):
        """
        Forces a slave to perform a manual failover of its master
        Sends to specified node

        :target_node: 'ClusterNode'
            The node to execute the command on
        """
        if option:
            if option.upper() not in ["FORCE", "TAKEOVER"]:
                raise RedisError(
                    f"Invalid option for CLUSTER FAILOVER command: {option}"
                )
            else:
                return self.execute_command(
                    "CLUSTER FAILOVER", option, target_nodes=target_node
                )
        else:
            return self.execute_command("CLUSTER FAILOVER", target_nodes=target_node)