Module: Valkey::Utils
- Included in:
- Valkey
- Defined in:
- lib/valkey/utils.rb
Overview
Valkey Utils module
This module provides utility functions for transforming and processing data structures commonly used in Valkey commands.
It includes methods for converting values to boolean, hash, or float, as well as methods for handling specific Valkey command responses.
Constant Summary collapse
- Boolify =
lambda { |value| return value if value.is_a?(TrueClass) || value.is_a?(FalseClass) value != 0 unless value.nil? }
- BoolifySet =
lambda { |value| case value when "OK" true when nil false else value end }
- Hashify =
lambda { |value| if value.respond_to?(:each_slice) value.each_slice(2).to_h else value end }
- Pairify =
lambda { |value| if value.respond_to?(:each_slice) value.each_slice(2).to_a else value 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) value.each_slice(2).map(&FloatifyPair) }
- 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.transform_values { |entries| HashifyStreamEntries.call(entries) } end }
- HashifyStreamEntries =
lambda { |reply| return [] if reply.nil? return [] if !reply.is_a?(Array) || reply.empty? # Reply format: [[entry_id, [field1, value1, field2, value2, ...]], ...] # Match redis-rb: return flat arrays [["id", ["field", "value", ...]], ...] # Check if first element is a pair [entry_id, values_array] first_elem = reply.first if first_elem.is_a?(Array) && first_elem.length == 2 # Already in pair format: [[entry_id, [fields...]], ...] reply.compact.map do |entry_id, values| # Return flat array format like redis-rb, not hash values_array = if values.nil? [] elsif values.is_a?(Array) values else [] end [entry_id, values_array] end else # Flat array format: [entry_id1, [field1, value1, ...], entry_id2, [field2, value2, ...], ...] reply.compact.each_slice(2).map do |entry_id, values| # Return flat array format like redis-rb, not hash values_array = if values.nil? [] elsif values.is_a?(Array) values else [] end [entry_id, values_array] end end }
- HashifyStreamAutoclaim =
lambda { |reply| { 'next' => reply[0], 'entries' => if reply[1].nil? [] elsif reply[1].is_a?(Array) # Reply[1] is already an array of entries: [[id, [field, value, ...]], ...] # Use HashifyStreamEntries to convert them properly HashifyStreamEntries.call(reply[1]) else [] 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..].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 }
Class Method Summary collapse
-
.parse_redis_url(url) ⇒ Hash
Parse Redis URL format: redis://[:password@]host[/db] Also supports: rediss:// (SSL).
Class Method Details
.parse_redis_url(url) ⇒ Hash
Parse Redis URL format: redis://[:password@]host[/db] Also supports: rediss:// (SSL)
218 219 220 221 222 223 224 225 226 227 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/valkey/utils.rb', line 218 def self.parse_redis_url(url) return {} unless url.is_a?(String) && !url.empty? # Match redis:// or rediss:// URLs # Format: redis[s]://[username:password@]host[:port][/db][?param=value] # Supports: redis://host, redis://user:pass@host, redis://:pass@host # The regex handles: # - No auth: redis://host... # - Username and password: redis://user:pass@host... # - Password only: redis://:pass@host... match = url.match(%r{\A(redis|rediss)://(?:([^:@]*):([^@]+)@)?([^:/]+)(?::(\d+))?(?:/(\d+))?(?:\?.*)?\z}) return {} unless match scheme = match[1] username = match[2] password = match[3] host = match[4] port = match[5]&.to_i db = match[6]&.to_i ssl = scheme == "rediss" result = { host: host, port: port || 6379, ssl: ssl } result[:username] = username if username && !username.empty? result[:password] = password if password && !password.empty? result[:db] = db if db result end |