Skip to content

Instantly share code, notes, and snippets.

@mosleymos
Forked from jdp/rdb2proto.py
Created November 3, 2023 17:19
Show Gist options
  • Select an option

  • Save mosleymos/0ceb77f7da7d548e54db84e91f575a8b to your computer and use it in GitHub Desktop.

Select an option

Save mosleymos/0ceb77f7da7d548e54db84e91f575a8b to your computer and use it in GitHub Desktop.

Revisions

  1. @jdp jdp created this gist Oct 10, 2013.
    133 changes: 133 additions & 0 deletions rdb2proto.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,133 @@
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-

    import calendar
    import sys

    import rdbtools


    def emit_protocol(*args):
    """Emit Redis unified protocol.
    """
    sys.stdout.write(u"*" + unicode(len(args)) + u"\r\n")
    for arg in args:
    sys.stdout.write(u"$" + unicode(len(unicode(arg))) + u"\r\n")
    sys.stdout.write(unicode(arg) + u"\r\n")


    def unix_timestamp(dt):
    return calendar.timegm(dt.utctimetuple())


    class ProtocolCallback(rdbtools.RdbCallback):
    def __init__(self):
    self.reset()

    def reset(self):
    self._expires = {}

    def set_expiry(self, key, dt):
    self._expires[key] = dt

    def get_expiry_seconds(self, key):
    if key in self._expires:
    return unix_timestamp(self._expires[key])
    return None

    def expires(self, key):
    return key in self._expires

    def pre_expiry(self, key, expiry):
    if expiry is not None:
    self.set_expiry(key, expiry)

    def post_expiry(self, key):
    if self.expires(key):
    self.expireat(key, self.get_expiry_seconds(key))

    def start_database(self, db_number):
    self.reset()
    self.select(db_number)

    # String handling

    def set(self, key, value, expiry, info):
    self.pre_expiry(key, expiry)
    emit_protocol('SET', key, value)
    self.post_expiry(key)

    # Hash handling

    def start_hash(self, key, length, expiry, info):
    self.pre_expiry(key, expiry)

    def hset(self, key, field, value):
    emit_protocol('HSET', key, field, value)

    def end_hash(self, key):
    self.post_expiry(key)

    # Set handling

    def start_set(self, key, cardinality, expiry, info):
    self.pre_expiry(key, expiry)

    def sadd(self, key, member):
    emit_protocol('SADD', key, member)

    def end_set(self, key):
    self.post_expiry(key)

    # List handling

    def start_list(self, key, length, expiry, info):
    self.pre_expiry(key, expiry)

    def rpush(self, key, value):
    emit_protocol('RPUSH', key, value)

    def end_list(self, key):
    self.post_expiry(key)

    # Sorted set handling

    def start_sorted_set(self, key, length, expiry, info):
    self.pre_expiry(key, expiry)

    def zadd(self, key, score, member):
    emit_protocol('ZADD', key, score, member)

    def end_sorted_set(self, key):
    self.post_expiry(key)

    # Other misc commands

    def select(self, db_number):
    emit_protocol('SELECT', db_number)

    def expireat(self, key, timestamp):
    emit_protocol('EXPIREAT', key, timestamp)


    if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument('-n', '--db', dest='dbs', action='append', type=int)
    parser.add_argument('-t', '--type', dest='types', action='append')
    parser.add_argument('-k', '--key', dest='keys')
    parser.add_argument('rdbfile')
    args = parser.parse_args()

    filters = {}
    if args.dbs:
    filters['dbs'] = args.dbs
    if args.types:
    filters['types'] = args.types
    if args.keys:
    filters['keys'] = args.keys

    callback = ProtocolCallback()
    parser = rdbtools.RdbParser(callback, filters=filters)
    parser.parse(args.rdbfile)