Skip to content

Instantly share code, notes, and snippets.

Created January 4, 2013 01:58
Show Gist options
  • Save anonymous/4449280 to your computer and use it in GitHub Desktop.
Save anonymous/4449280 to your computer and use it in GitHub Desktop.
require './uuid'
require 'json'
class Store
def initialize(path)
@path = path
@objects = {}
end
def save(object)
object.id = UUID.create_random.to_s unless object.id
@objects[object.id] = object
file_path = File.join(@path, object.id)
File.open(file_path, 'w') do |file|
json_object = serialize(object)
json = json_object.to_json
file.write(json)
end
return object.id
end
def load(object_id)
if @objects[object_id]
@objects[object_id]
else
file_path = File.join(@path, object_id)
File.open(file_path, 'r') do |file|
return deserialize(file.read(), object_id)
end
end
end
def unload(object)
@objects.delete(object.id)
end
private
def serialize(object, primary=true)
if object.is_a?(String) \
|| object.is_a?(Integer) \
|| object.is_a?(Float) \
|| object.is_a?(TrueClass) \
|| object.is_a?(FalseClass) \
|| object.is_a?(NilClass)
return object
elsif primary == false
return { :ref => save(object) }
end
dictionary = {}
methods = object.public_methods(false)
methods.delete_if do |method|
method == :id || !(method.to_s =~ /^[a-zA-Z0-9\-]+$/)
end
methods.each do |method|
obj = object.send(method)
dictionary[method] = serialize(obj, false)
end
return { :object => dictionary }
end
def deserialize(blob, object_id)
json_object = JSON.parse(blob)
object = json_to_object json_object
object.id = object_id
object
end
def json_to_object(json)
if json.is_a?(String) \
|| json.is_a?(Integer) \
|| json.is_a?(Float) \
|| json.is_a?(TrueClass) \
|| json.is_a?(FalseClass) \
|| json.is_a?(NilClass)
return json
end
if json.is_a?(Hash)
if json.keys == ['object']
object = StoreObject.new
json['object'].each do |key, value|
if value.is_a?(Hash) && value.keys == ['ref']
object.send "#{key}=", Proxy.new(value['ref'], self)
else
object.send "#{key}=", json_to_object(value)
end
end
return object
else
return json
end
end
end
end
class StoreObject
def method_missing(name, *args)
if name.to_s.end_with? '='
instance_variable_set "@#{name.to_s.chomp '='}", args[0]
else
instance_variable_get "@#{name.to_s}"
end
end
end
class Proxy
def initialize(object_id, store)
@object_id = object_id
@store = store
end
def method_missing(name, *args)
obj = @store.load(@object_id)
obj.send(name, *args)
end
end
class Person
attr_accessor :id, :name, :age, :parent
def initialize(name, age, parent = nil)
self.name = name
self.age = age
self.parent = parent
end
end
store = Store.new('./foo')
#zoidberg = Person.new('Zoidberg', 18)
#store.save(zoidberg)
#
#ell = Person.new('Ell', 2, zoidberg)
#store.save(ell)
#
#sbi = Person.new('sbi', 800)
#store.save(sbi)
ell_id = '4d7d1979-b7b0-4a33-b263-217cb20d1400'
ell = store.load(ell_id)
puts ell.inspect
puts ell.parent.name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment