Module: Redis::Commands

Includes:
Bitmaps, Cluster, Geo, Hashes, HyperLogLog, Json, Keys, Lists, Pubsub, Scripting, Search, Server, Sets, SortedSets, Streams, Strings, Transactions, Connection
Included in:
Redis, PipelinedConnection
Defined in:
lib/redis/commands.rb,
lib/redis/commands/geo.rb,
lib/redis/commands/keys.rb,
lib/redis/commands/sets.rb,
lib/redis/commands/lists.rb,
lib/redis/commands/hashes.rb,
lib/redis/commands/pubsub.rb,
lib/redis/commands/server.rb,
lib/redis/commands/bitmaps.rb,
lib/redis/commands/cluster.rb,
lib/redis/commands/streams.rb,
lib/redis/commands/strings.rb,
lib/redis/commands/scripting.rb,
lib/redis/commands/connection.rb,
lib/redis/commands/sorted_sets.rb,
lib/redis/commands/modules/json.rb,
lib/redis/commands/transactions.rb,
lib/redis/commands/hyper_log_log.rb,
lib/redis/commands/modules/search.rb,
lib/redis/commands/modules/search/field.rb,
lib/redis/commands/modules/search/index.rb,
lib/redis/commands/modules/search/query.rb,
lib/redis/commands/modules/search/hybrid.rb,
lib/redis/commands/modules/search/result.rb,
lib/redis/commands/modules/search/schema.rb,
lib/redis/commands/modules/search/dialect.rb,
lib/redis/commands/modules/search/aggregation.rb,
lib/redis/commands/modules/search/miscellaneous.rb,
lib/redis/commands/modules/search/index_definition.rb

Defined Under Namespace

Modules: Bitmaps, Cluster, Connection, Geo, Hashes, HyperLogLog, Json, Keys, Lists, Pubsub, Scripting, Search, Server, Sets, SortedSets, Streams, Strings, Transactions

Constant Summary collapse

Boolify =

Commands returning 1 for true and 0 for false may be executed in a pipeline where the method call will return nil. Propagate the nil instead of falsely returning false.

lambda { |value|
  value != 0 unless value.nil?
}
BoolifySet =
lambda { |value|
  case value
  when "OK"
    true
  when nil
    false
  else
    value
  end
}
Hashify =
lambda { |value|
  if value.is_a?(Hash) # RESP3 already returns a map
    value
  elsif value.respond_to?(:each_slice) # RESP2 flat [k, v, k, v, ...]
    value.each_slice(2).to_h
  else
    value
  end
}
Pairify =
lambda { |value|
  return value unless value.respond_to?(:each_slice)

  if value.first.is_a?(Array) # RESP3 already returns [[k, v], ...]
    value
  else # RESP2 flat [k, v, k, v, ...]
    value.each_slice(2).to_a
  end
}
Floatify =
lambda { |value|
  case value
  when "inf"
    Float::INFINITY
  when "-inf"
    -Float::INFINITY
  when String
    Float(value)
  else
    value
  end
}
FloatifyPair =
lambda { |(first, score)|
  [first, Floatify.call(score)]
}
FloatifyPairs =
lambda { |value|
  return value unless value.respond_to?(:each_slice)

  if value.first.is_a?(Array) # RESP3 already returns [[member, score], ...]
    # Scores arrive as native doubles, so the pairs are already in the final shape and
    # re-mapping would only re-allocate identical arrays. Floatify only transforms Strings, so
    # unless a score came back as one (it shouldn't under RESP3) return the parser's array as-is.
    value.first.last.is_a?(String) ? value.map(&FloatifyPair) : value
  else # RESP2 flat [member, score, member, score, ...]
    value.each_slice(2).map(&FloatifyPair)
  end
}
HashifyInfo =
lambda { |reply|
  lines = reply.split("\r\n").grep_v(/^(#|$)/)
  lines.map! { |line| line.split(':', 2) }
  lines.compact!
  lines.to_h
}
HashifyStreams =
lambda { |reply|
  case reply
  when nil
    {}
  else
    reply.map { |key, entries| [key, HashifyStreamEntries.call(entries)] }.to_h
  end
}
HashifyStreamEntries =
lambda { |reply|
  reply.compact.map do |entry_id, values|
    [entry_id, values&.each_slice(2)&.to_h]
  end
}
HashifyStreamAutoclaim =
lambda { |reply|
  {
    'next' => reply[0],
    'entries' => reply[1].compact.map do |entry, values|
      [entry, values.each_slice(2)&.to_h]
    end
  }
}
HashifyStreamAutoclaimJustId =
lambda { |reply|
  {
    'next' => reply[0],
    'entries' => reply[1]
  }
}
HashifyStreamPendings =
lambda { |reply|
  {
    'size' => reply[0],
    'min_entry_id' => reply[1],
    'max_entry_id' => reply[2],
    'consumers' => reply[3].nil? ? {} : reply[3].to_h
  }
}
HashifyStreamPendingDetails =
lambda { |reply|
  reply.map do |arr|
    {
      'entry_id' => arr[0],
      'consumer' => arr[1],
      'elapsed' => arr[2],
      'count' => arr[3]
    }
  end
}
HashifyClusterNodeInfo =
lambda { |str|
  arr = str.split(' ')
  {
    'node_id' => arr[0],
    'ip_port' => arr[1],
    'flags' => arr[2].split(','),
    'master_node_id' => arr[3],
    'ping_sent' => arr[4],
    'pong_recv' => arr[5],
    'config_epoch' => arr[6],
    'link_state' => arr[7],
    'slots' => arr[8].nil? ? nil : Range.new(*arr[8].split('-'))
  }
}
HashifyClusterSlots =
lambda { |reply|
  reply.map do |arr|
    first_slot, last_slot = arr[0..1]
    master = { 'ip' => arr[2][0], 'port' => arr[2][1], 'node_id' => arr[2][2] }
    replicas = arr[3..-1].map { |r| { 'ip' => r[0], 'port' => r[1], 'node_id' => r[2] } }
    {
      'start_slot' => first_slot,
      'end_slot' => last_slot,
      'master' => master,
      'replicas' => replicas
    }
  end
}
HashifyClusterNodes =
lambda { |reply|
  reply.split(/[\r\n]+/).map { |str| HashifyClusterNodeInfo.call(str) }
}
HashifyClusterSlaves =
lambda { |reply|
  reply.map { |str| HashifyClusterNodeInfo.call(str) }
}
Noop =
->(reply) { reply }

Constants included from Search

Search::DEFAULT_DIALECT

Constants included from Json

Json::NumincrbyNormalize, Json::TypeNormalize

Instance Method Summary collapse

Methods included from Transactions

#discard, #exec, #multi, #unwatch, #watch

Methods included from Strings

#append, #decr, #decrby, #get, #getdel, #getex, #getrange, #getset, #incr, #incrby, #incrbyfloat, #mapped_mget, #mapped_mset, #mapped_msetnx, #mget, #mset, #msetnx, #psetex, #set, #setex, #setnx, #setrange, #strlen

Methods included from Streams

#xack, #xadd, #xautoclaim, #xclaim, #xdel, #xgroup, #xinfo, #xlen, #xpending, #xrange, #xread, #xreadgroup, #xrevrange, #xtrim

Methods included from SortedSets

#bzmpop, #bzpopmax, #bzpopmin, #zadd, #zcard, #zcount, #zdiff, #zdiffstore, #zincrby, #zinter, #zinterstore, #zlexcount, #zmpop, #zmscore, #zpopmax, #zpopmin, #zrandmember, #zrange, #zrangebylex, #zrangebyscore, #zrangestore, #zrank, #zrem, #zremrangebyrank, #zremrangebyscore, #zrevrange, #zrevrangebylex, #zrevrangebyscore, #zrevrank, #zscan, #zscan_each, #zscore, #zunion, #zunionstore

Methods included from Sets

#sadd, #sadd?, #scard, #sdiff, #sdiffcard, #sdiffstore, #sinter, #sinterstore, #sismember, #smembers, #smismember, #smove, #spop, #srandmember, #srem, #srem?, #sscan, #sscan_each, #sunion, #sunioncard, #sunionstore

Methods included from Server

#bgrewriteaof, #bgsave, #client, #config, #dbsize, #debug, #flushall, #flushdb, #info, #lastsave, #monitor, #save, #shutdown, #slaveof, #slowlog, #sync, #time

Methods included from Search

#create_index, #ft_aggregate, #ft_aliasadd, #ft_aliasdel, #ft_aliaslist, #ft_aliasupdate, #ft_alter, #ft_config_get, #ft_config_set, #ft_create, #ft_cursor_del, #ft_cursor_read, #ft_dictadd, #ft_dictdel, #ft_dictdump, #ft_dropindex, #ft_explain, #ft_hybrid_search, #ft_info, #ft_profile, #ft_search, #ft_spellcheck, #ft_sugadd, #ft_sugdel, #ft_sugget, #ft_suglen, #ft_syndump, #ft_synupdate, #ft_tagvals

Methods included from Scripting

#eval, #evalsha, #script

Methods included from Pubsub

#psubscribe, #psubscribe_with_timeout, #publish, #pubsub, #punsubscribe, #spublish, #ssubscribe, #ssubscribe_with_timeout, #subscribe, #subscribe_with_timeout, #subscribed?, #sunsubscribe, #unsubscribe

Methods included from Json

#json_arrappend, #json_arrindex, #json_arrinsert, #json_arrlen, #json_arrpop, #json_arrtrim, #json_clear, #json_debug_memory, #json_del, #json_forget, #json_get, #json_merge, #json_mget, #json_mset, #json_numincrby, #json_objkeys, #json_objlen, #json_set, #json_strappend, #json_strlen, #json_toggle, #json_type

Methods included from Lists

#blmove, #blmovem, #blmpop, #blpop, #brpop, #brpoplpush, #lindex, #linsert, #llen, #lmove, #lmovem, #lmpop, #lpop, #lpush, #lpushx, #lrange, #lrem, #lset, #ltrim, #rpop, #rpoplpush, #rpush, #rpushx

Methods included from Keys

#copy, #del, #dump, #exists, #exists?, #expire, #expireat, #expiretime, #keys, #migrate, #move, #object, #persist, #pexpire, #pexpireat, #pexpiretime, #pttl, #randomkey, #rename, #renamenx, #restore, #scan, #scan_each, #sort, #ttl, #type, #unlink

Methods included from HyperLogLog

#pfadd, #pfcount, #pfmerge

Methods included from Hashes

#hdel, #hexists, #hexpire, #hget, #hgetall, #himport_discard, #himport_discard_all, #himport_prepare, #himport_set, #hincrby, #hincrbyfloat, #hkeys, #hlen, #hmget, #hmset, #hpexpire, #hpttl, #hrandfield, #hscan, #hscan_each, #hset, #hsetnx, #httl, #hvals, #mapped_hmget, #mapped_hmset

Methods included from Geo

#geoadd, #geodist, #geohash, #geopos, #georadius, #georadiusbymember, #geosearch, #geosearchstore

Methods included from Connection

drivers

Methods included from Cluster

#asking, #cluster

Methods included from Bitmaps

#bitcount, #bitop, #bitpos, #getbit, #setbit

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*command) ⇒ Object (private)

rubocop:disable Style/MissingRespondToMissing



255
256
257
# File 'lib/redis/commands.rb', line 255

def method_missing(*command) # rubocop:disable Style/MissingRespondToMissing
  send_command(command)
end

Instance Method Details

#call(*command, &block) ⇒ Object

Sends a command to Redis and returns its reply.

Replies are converted to Ruby objects according to the RESP protocol, so you can expect a Ruby array, integer or nil when Redis sends one. Higher level transformations, such as converting an array of pairs into a Ruby hash, are up to consumers.

Redis error replies are raised as Ruby exceptions.



219
220
221
# File 'lib/redis/commands.rb', line 219

def call(*command, &block)
  send_command(command, &block)
end

#sentinel(subcommand, *args) ⇒ Array<String>, ...

Interact with the sentinel command (masters, master, slaves, failover)

Parameters:

  • subcommand (String)

    e.g. masters, master, slaves

  • args (Array<String>)

    depends on subcommand

Returns:

  • (Array<String>, Hash<String, String>, String)

    depends on subcommand



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/redis/commands.rb', line 228

def sentinel(subcommand, *args)
  subcommand = subcommand.to_s.downcase
  send_command([:sentinel, subcommand] + args) do |reply|
    case subcommand
    when "get-master-addr-by-name"
      reply
    else
      case reply
      when Array
        if reply.empty?
          reply # empty list (e.g. sentinels/slaves with no entries) stays []; don't Hashify to {}
        else
          case reply[0]
          when Array then reply.map(&Hashify) # RESP2: list of flat [k, v, ...] arrays
          when Hash then reply                 # RESP3: list of maps (already hashes)
          else Hashify.call(reply)             # RESP2: a single flat [k, v, ...] array
          end
        end
      else
        reply # RESP3 single map, or a scalar reply
      end
    end
  end
end