module Oxblood::Protocol

Constants

ARRAY
BULK_STRING
COMMAND_HEADER
EMPTY_ARRAY
EMPTY_ARRAY_RESPONSE
EMPTY_BULK_STRING_RESPONSE
EMPTY_STRING
ERROR
INTEGER
NULL_ARRAY_RESPONSE
NULL_BULK_STRING_RESPONSE
ParserError
RError
SIMPLE_STRING
SerializerError
TERMINATOR

Public Class Methods

build_command(command = nil, *args) click to toggle source

Serialize command to string according to Redis Protocol @note Redis don't support nested arrays @note Written in non-idiomatic ruby without error handling due to

performance reasons

@see www.redis.io/topics/protocol#sending-commands-to-a-redis-server

@raise [SerializerError] if unable to serialize given command

@param [#to_s] command name @param [Array] args array consisting of command arguments

@return [String] serialized command

# File lib/oxblood/protocol.rb, line 102
def build_command(command = nil, *args)
  return EMPTY_ARRAY_RESPONSE if command.nil?

  result = append!(command, COMMAND_HEADER.dup)
  size = 1
  args.each do |c|
    if Array === c
      c.each do |e|
        append!(e, result)
        size += 1
      end
    else
      append!(c, result)
      size += 1
    end
  end

  result.insert(1, size.to_s)
end
parse(io) click to toggle source

Parse redis response @see redis.io/topics/protocol @raise [ParserError] if unable to parse response @param [#read, gets] io IO or IO-like object to read from @return [String, RError, Integer, Array]

# File lib/oxblood/protocol.rb, line 52
def parse(io)
  line = io.gets(TERMINATOR)

  case line[0]
  when SIMPLE_STRING
    line[1..-3]
  when ERROR
    RError.new(line[1..-3])
  when INTEGER
    line[1..-3].to_i
  when BULK_STRING
    return if line == NULL_BULK_STRING_RESPONSE

    body_length = line[1..-1].to_i

    case body_length
    when -1 then nil
    when 0 then
      # discard CRLF
      io.read(2)
      EMPTY_STRING
    else
      # string length plus CRLF
      body = io.read(body_length + 2)
      body[0..-3]
    end
  when ARRAY
    return if line == NULL_ARRAY_RESPONSE
    return EMPTY_ARRAY if line == EMPTY_ARRAY_RESPONSE

    size = line[1..-1].to_i

    Array.new(size) { parse(io) }
  else
    raise ParserError.new('Unsupported response type')
  end
end

Private Class Methods

append!(elem, command) click to toggle source
# File lib/oxblood/protocol.rb, line 124
def append!(elem, command)
  elem = elem.to_s
  command << BULK_STRING
  command << elem.bytesize.to_s
  command << TERMINATOR
  command << elem
  command << TERMINATOR
end