Skip to content

Instantly share code, notes, and snippets.

@erikogan
Created December 13, 2014 19:49
Show Gist options
  • Save erikogan/a3fd06ae9634aa1256ff to your computer and use it in GitHub Desktop.
Save erikogan/a3fd06ae9634aa1256ff to your computer and use it in GitHub Desktop.
A script to dump/load (Lita) data from/to Redis URLs and/or files
#!/usr/bin/env ruby
require 'redis'
require 'csv'
# require 'json'
require 'oj'
# require 'byebug'
class Extractor
def initialize(from_url, to_url)
@from = from_url =~ /:/ ? Redis.new(url: from_url) : FromFile.new(from_url)
@to = to_url =~ /:/ ? Redis.new(url: to_url) : ToFile.new(to_url)
end
def run
if @to.respond_to?(:flushdb)
@to.flushdb
end
if @from.respond_to?(:replay)
@from.replay(@to)
else
@from.keys.sort.each do |key|
type = @from.type(key)
puts "#{type.upcase} :: #{key}"
self.send(type, key)
end
end
end
private
def string(key)
@to[key] = @from[key]
end
def set(key)
mem = @from.smembers(key)
@to.sadd(key, mem)
end
def list(key)
mem = @from.lrange(key, 0, -1)
@to.rpush(key, mem)
end
def hash(key)
data = @from.hgetall(key)
data.each {|k,v| @to.hset(key, k, v) }
end
def zset(key)
@from.zrange(key, 0, -1, withscores: true).each do |(k, score)|
@to.zadd(key, score, k)
end
end
class FromFile
def initialize(filename)
@file = CSV.open(filename, col_sep: "\t")
end
def replay(to)
@file.each do |(cmd, key, *args)|
puts "#{cmd.upcase} :: #{key} :: #{args.inspect}"
# Fun, random fact: JSON.parse("foo".to_json) :: JSON::ParserError: 746: unexpected token at '"foo"'
to.send(cmd, key, *(args.map {|x| Oj.load(x)}))
end
end
end
class ToFile
def initialize(filename)
@file = CSV.open(filename, 'w', col_sep: "\t")
end
def []=(key, value)
write('set', key, value)
end
def set(key, value)
self[key] = value
end
def sadd(key, value)
write('sadd', key, value)
end
def rpush(key, value)
write('sadd', key, value)
end
def hset(hash, key, value)
write('hset', hash, key, value)
end
def zadd(key, score, value)
write('zadd', key, score, value)
end
MISSING_VALUE = "\0MISSING/VALUE\0"
def write(cmd, key, first, second = MISSING_VALUE)
# See above for why Oj over built-in JSON
# @file << [cmd, key, first.to_json, (second == MISSING_VALUE ? nil : second.to_json)].compact
@file << [cmd, key, Oj.dump(first), (second == MISSING_VALUE ? nil : Oj.dump(second))].compact
end
end
end
ex = Extractor.new(*ARGV)
ex.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment