class Redcord::Redis
Public Instance Methods
create_hash_returning_id(key, args, ttl:, index_attrs:, range_index_attrs:, custom_index_attrs:, hash_tag: nil)
click to toggle source
# File lib/redcord/redis.rb, line 20 def create_hash_returning_id(key, args, ttl:, index_attrs:, range_index_attrs:, custom_index_attrs:, hash_tag: nil) id = "#{SecureRandom.uuid}#{hash_tag}" custom_index_attrs_flat = custom_index_attrs.inject([]) do |result, (index_name, attrs)| result << index_name result << attrs.size result + attrs end run_script( :create_hash, keys: [id, hash_tag], argv: [key, ttl, index_attrs.size, range_index_attrs.size, custom_index_attrs_flat.size] + index_attrs + range_index_attrs + custom_index_attrs_flat + args.to_a.flatten, ) id end
delete_hash(model, id, index_attrs:, range_index_attrs:, custom_index_attrs:)
click to toggle source
# File lib/redcord/redis.rb, line 75 def delete_hash(model, id, index_attrs:, range_index_attrs:, custom_index_attrs:) custom_index_names = custom_index_attrs.keys run_script( :delete_hash, keys: [id, id.match(/\{.*\}$/)&.send(:[], 0)], argv: [model, index_attrs.size, range_index_attrs.size] + index_attrs + range_index_attrs + custom_index_names, ) end
find_by_attr( model, query_conditions, select_attrs: Set.new, index_attrs:, range_index_attrs:, custom_index_attrs: Array.new, hash_tag: nil, custom_index_name: nil )
click to toggle source
# File lib/redcord/redis.rb, line 96 def find_by_attr( model, query_conditions, select_attrs: Set.new, index_attrs:, range_index_attrs:, custom_index_attrs: Array.new, hash_tag: nil, custom_index_name: nil ) conditions = flatten_with_partial_sort(query_conditions.clone, custom_index_attrs) res = run_script( :find_by_attr, keys: [hash_tag], argv: [model, custom_index_name, index_attrs.size, range_index_attrs.size, custom_index_attrs.size, conditions.size] + index_attrs + range_index_attrs + custom_index_attrs + conditions + select_attrs.to_a.flatten ) # The Lua script will return this as a flattened array. # Convert the result into a hash of {id -> model hash} res_hash = res.each_slice(2) res_hash.map { |key, val| [key, val.each_slice(2).to_h] }.to_h end
find_by_attr_count( model, query_conditions, index_attrs:, range_index_attrs:, custom_index_attrs: Array.new, hash_tag: nil, custom_index_name: nil )
click to toggle source
# File lib/redcord/redis.rb, line 130 def find_by_attr_count( model, query_conditions, index_attrs:, range_index_attrs:, custom_index_attrs: Array.new, hash_tag: nil, custom_index_name: nil ) conditions = flatten_with_partial_sort(query_conditions.clone, custom_index_attrs) run_script( :find_by_attr_count, keys: [hash_tag], argv: [model, custom_index_name, index_attrs.size, range_index_attrs.size, custom_index_attrs.size] + index_attrs + range_index_attrs + custom_index_attrs + conditions ) end
scan_each_shard(key, count: 1000, &blk)
click to toggle source
# File lib/redcord/redis.rb, line 148 def scan_each_shard(key, count: 1000, &blk) clients = instance_variable_get(:@client) &.instance_variable_get(:@node) &.instance_variable_get(:@clients) &.values if clients.nil? scan_each(match: key, count: count, &blk) else clients.each do |client| cursor = 0 loop do cursor, keys = client.call([:scan, cursor, 'match', key, 'count', count]) keys.each(&blk) break if cursor == "0" end end end end
update_hash(model, id, args, ttl:, index_attrs:, range_index_attrs:, custom_index_attrs:, hash_tag:)
click to toggle source
# File lib/redcord/redis.rb, line 48 def update_hash(model, id, args, ttl:, index_attrs:, range_index_attrs:, custom_index_attrs:, hash_tag:) custom_index_attrs_flat = custom_index_attrs.inject([]) do |result, (index_name, attrs)| if !(args.keys.to_set & attrs.to_set).empty? result << index_name result << attrs.size result + attrs else result end end run_script( :update_hash, keys: [id, hash_tag], argv: [model, ttl, index_attrs.size, range_index_attrs.size, custom_index_attrs_flat.size] + index_attrs + range_index_attrs + custom_index_attrs_flat + args.to_a.flatten, ) end
Private Instance Methods
flatten_with_partial_sort(query_conditions, partial_order)
click to toggle source
# File lib/redcord/redis.rb, line 191 def flatten_with_partial_sort(query_conditions, partial_order) conditions = partial_order.inject([]) do |result, attr| if !query_conditions[attr].nil? result << attr << query_conditions.delete(attr) end result.flatten end conditions += query_conditions.to_a.flatten end
run_script(script_name, *args)
click to toggle source
# File lib/redcord/redis.rb, line 170 def run_script(script_name, *args) # Use EVAL when a redis shard has not loaded the script before hash_var_name = :"@script_sha_#{script_name}" hash = instance_variable_get(hash_var_name) begin return evalsha(hash, *args) if hash rescue Redis::CommandError => e if e.message != 'NOSCRIPT No matching script. Please use EVAL.' raise e end end script_content = Redcord::LuaScriptReader.read_lua_script(script_name.to_s) instance_variable_set(hash_var_name, Digest::SHA1.hexdigest(script_content)) self.eval(script_content, *args) end