Skip to content

Instantly share code, notes, and snippets.

@pricees
Created September 7, 2012 18:30
Show Gist options
  • Save pricees/3668404 to your computer and use it in GitHub Desktop.
Save pricees/3668404 to your computer and use it in GitHub Desktop.
Ss::PersistentJhash
#
# Public: This class uses Rubys native hash data type for immediate data manipulation. This serializes the data to JSON where it is stored into a Redis backend for persistence.
# It contains a namespace and a rd_key, it will store the data as JSON into "[namespace]:[key]"
#
# Assumes REDIS = Redis.new (redis connection)
#
# Examples
#
# foo = PersistentJhash.new
# foo.namespace
# # => "persistent_jhash"
# foo.rd_key
# # => "persistent_jhash"
#
# bar = PersistentJhash.new(ns: "ss:bar")
# bar.namespace
# # => "ss:bar"
# bar.rd_key
# # => "bar"
#
# baz = PersistentJhash.new(rk: "another_key")
# baz.namespace
# # => "persistent_jhash"
# baz.rd_key
# # => "another_key"
#
# foo = PersistentJhash.new(rk: :test)
# # => {}
# foo + { name: "Joe", favorite_numbers: [ 1, 2, 3 ] }
# # => { name: "Joe", favorite_numbers: [ 1, 2, 3 ] }
# foo.save
# # => saved to "persistent_jhash:test"
#
# foo = PersistentJhash.new(rk: :test)
# # => {}
# foo.load_data
# # => { name: "Joe", favorite_numbers: [ 1, 2, 3 ] }
module Ss
class PersistentJhash < Hash
def initialize(params = {})
ns, rk = params[:ns], params[:rk]
self.namespace = ns.to_s if ns
self.rd_key = rk.to_s if rk
end
alias_method :+, :merge
def load_data
replace JSON.parse(conn[rd_key])
end
def save
conn[rd_key] = to_json
self
end
def namespace
@namespace ||= ns(self.class.to_s)
end
def rd_key
@rd_key ||= namespace.split(/:/).last
end
def reset
@conn = nil
end
private
attr_writer :namespace, :rd_key
# snakecase, double-colons to single-colons
# ns("Ss::PersistentJhash")
# # => "ss:persistent_jhash"
def ns(str)
str.gsub(/::/, ':').
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').
tr("-", "_").
downcase
end
def raw
conn[rd_key]
end
def conn
@conn ||= Redis::Namespace.new(namespace, :redis => REDIS)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment