Beispiel #1
0
    async def rename(self, src, dst):
        """
        Rename key ``src`` to ``dst``

        Cluster impl:
            This operation is no longer atomic because each key must be querried
            then set in separate calls because they maybe will change cluster node
        """
        if src == dst:
            raise ResponseError("source and destination objects are the same")

        data = await self.dump(src)

        if data is None:
            raise ResponseError("no such key")

        ttl = await self.pttl(src)

        if ttl is None or ttl < 1:
            ttl = 0

        await self.delete(dst)
        await self.restore(dst, ttl, data)
        await self.delete(src)

        return True
Beispiel #2
0
 def parse_error(self, response):
     "Parse an error response"
     error_code = response.split(' ')[0]
     if error_code in self.EXCEPTION_CLASSES:
         response = response[len(error_code) + 1:]
         exception_class = self.EXCEPTION_CLASSES[error_code]
         if isinstance(exception_class, dict):
             exception_class = exception_class.get(response, ResponseError)
         return exception_class(response)
     return ResponseError(response)
Beispiel #3
0
 def mock_register(cls, redis):
     raise ResponseError()
Beispiel #4
0
    async def _execute_transaction(self, connection, commands, raise_on_error):
        cmds = chain([(('MULTI', ), {})], commands, [(('EXEC', ), {})])
        all_cmds = connection.pack_commands([args for args, _ in cmds])
        await connection.send_packed_command(all_cmds)
        errors = []

        # parse off the response for MULTI
        # NOTE: we need to handle ResponseErrors here and continue
        # so that we read all the additional command messages from
        # the socket
        try:
            await self.parse_response(connection, '_')
        except ResponseError:
            errors.append((0, sys.exc_info()[1]))

        # and all the other commands
        for i, command in enumerate(commands):
            try:
                await self.parse_response(connection, '_')
            except ResponseError:
                ex = sys.exc_info()[1]
                self.annotate_exception(ex, i + 1, command[0])
                errors.append((i, ex))

        # parse the EXEC.
        try:
            response = await self.parse_response(connection, '_')
        except ExecAbortError:
            if self.explicit_transaction:
                await self.immediate_execute_command('DISCARD')
            if errors:
                raise errors[0][1]
            raise sys.exc_info()[1]

        if response is None:
            raise WatchError("Watched variable changed.")

        # put any parse errors into the response
        for i, e in errors:
            response.insert(i, e)

        if len(response) != len(commands):
            self.connection.disconnect()
            raise ResponseError("Wrong number of response items from "
                                "pipeline execution")

        # find any errors in the response and raise if necessary
        if raise_on_error:
            self.raise_first_error(commands, response)

        # We have to run response callbacks manually
        data = []
        for r, cmd in zip(response, commands):
            if not isinstance(r, Exception):
                args, options = cmd
                command_name = args[0]
                if command_name in self.response_callbacks:
                    callback = self.response_callbacks[command_name]
                    r = callback(r, **options)
                    # typing.Awaitable is not available in Python3.5
                    # so use inspect.isawaitable instead
                    # according to issue https://github.com/NoneGG/aredis/issues/77
                    if inspect.isawaitable(response):
                        r = await r
            data.append(r)
        return data