Permalink
Browse files

Clean up library by removing dependencies.

Allow backend to be instantiated before initializing hashback.
  • Loading branch information...
1 parent 4618661 commit 2deaf02e25f357391282bb6ff2688414d42e6511 @jsl committed Jul 4, 2009
Showing with 56 additions and 94 deletions.
  1. +12 −8 README.rdoc
  2. +13 −8 hashback.gemspec
  3. +2 −0 init.rb
  4. +0 −1 lib/hashback.rb
  5. +12 −33 lib/hashback/backend.rb
  6. +14 −13 lib/hashback/resource.rb
  7. +2 −30 spec/hashback/backend_spec.rb
  8. +1 −1 spec/hashback/resource_spec.rb
View
@@ -1,8 +1,8 @@
= HashBack
HashBack is a simple Object-hash mapping (OHM) system for Ruby. It allows for serializable classes to be saved,
-retrieved and deleted from any key-value store supported by {Moneta}[http://github.com/wycats/moneta/tree/master]
-(a unified interface to key-value systems).
+retrieved and deleted from any key-value store. It works particulary well with, but has no dependency on
+{Moneta}[http://github.com/wycats/moneta/tree/master] (a unified interface to key-value systems).
== Quick Start
@@ -21,7 +21,7 @@ UUIDs created by the assaf-uuid gem, so we'll include that as well.
Below we create a simple class that is serializable to HashBack.
class Elephant
- HashBack::Resource.setup(self, :uuid, 'Moneta::Memory')
+ HashBack::Resource.setup(self, :uuid, Moneta::Memory.new)
attr_accessor :uuid, :name
@@ -46,6 +46,12 @@ When you're sick of Dumbo and want to get rid of him:
Note that at this point the data is still available in the instance variables for Dumbo, but the persisted form of him is gone.
+== HashBack::Backend
+
+A lightweight class called HashBack::Backend is included with the distribution of this gem. This class wraps common Hash-like
+getter and setter methods with ones that include a namespace. This may be helpful to you if you're persisting many objects
+to the same backend data store. Please see the documentation for HashBack::Backend for more information.
+
== Detailed usage
Generally, HashBack should work with any class that can be serialized. You can decide which key-value storage system
@@ -57,7 +63,7 @@ follows:
require 'hashback'
class Foo
- HashBack::Resource.setup(self, :id, 'Moneta::Memcache', :server => 'localhost:1978')
+ HashBack::Resource.setup(self, :id, HashBack::Backend.new('Foo', Moneta::Memcache.new(:server => 'localhost:1978')))
end
This initializes a class with a backend storage in a Tokyo Tyrant server. The serialized forms of objects that are
@@ -77,13 +83,11 @@ together a lightweight implementation with methods for saving and accessing simi
The following features are not present in the current library, but may be useful:
* A system of callbacks
-* A system for associating objects, perhaps constrained to objects that have a 1 - 1 mapping (since it's not entirely
- intuitive what the structures or algorithms would be for mainting integrity with higher levels of mapping between
- objects).
+* A system for associating objects, perhaps constrained to objects that have a 1 - 1 mapping
== Feedback
-Please write the author if you have any questions or feedbacks about this library.
+Please write the author if you have any questions or feedback regarding this library.
== Author
View
@@ -1,11 +1,20 @@
Gem::Specification.new do |s|
s.name = "hashback"
- s.version = "0.0.2.5"
+ s.version = "0.0.3"
s.date = "2009-05-13"
- s.summary = "Generic tool for writing namespaced key-value data to a variety of hash-type systems"
+
+ s.summary = "Ruby Object-Hash Mapping system (OHM)"
+
+ s.description = <<-EOF
+ HashBack makes your ruby class persistent by adding methods which will save and retrieve it from a
+ backend key-value store. Useful when you have objects that should respond to #save and #fetch (as
+ a class method). Works well with the Moneta gem, which automatically serializes objects before they
+ are saved and after they are retrieved, but functions with any key-value storage system.
+ EOF
+
s.email = "justin@phq.org"
s.homepage = "http://github.com/jsl/hashback"
- s.description = "Wrapper around Moneta that facilitates using the key-value store as a backend for applications requiring namespacing"
+ s.description = "HashBack"
s.has_rdoc = true
s.authors = ["Justin Leitgeb"]
s.files = [
@@ -32,9 +41,5 @@ Gem::Specification.new do |s|
'--main', 'README.rdoc',
'--line-numbers',
'--inline-source'
- ]
-
- s.add_dependency("jsl-moneta")
- s.add_dependency("activesupport")
- s.add_dependency("assaf-uuid")
+ ]
end
View
@@ -1 +1,3 @@
+# In case we're used as a Rails plugin, load the library.
+
require 'hashback'
View
@@ -1,4 +1,3 @@
-require 'moneta'
require 'activesupport'
Dir[File.join(File.dirname(__FILE__), 'hashback', '*.rb')].each do |f|
View
@@ -1,54 +1,33 @@
module HashBack
- # Delegates methods to Moneta (a unified interface to key-value storage systems) after adding
- # a key for proper namespacing. Initializes and loads the proper Moneta class based on input
- # options, and delegates setting and retrieval to the Moneta class responsible for storage.
+ # Proxy class over a key-value storage object which adds a namespace to keys. Useful if you
+ # have a number of different things that are saving to the same object space. Of course, then
+ # you may want to consider just opening up new key-value stores. This class may safely be
+ # ignored if not needed by your application.
class Backend
- def initialize(namespace, moneta_klass, options = { })
+ # Backend accepts a namespace which will be added to all keys on retrieval and
+ # setting, and a backend that responds to Hash-like methods. Moneta classes
+ # see the Moneta gem) work well as the backends to this class.
+ def initialize(namespace, backend)
@namespace = namespace
- @options = options
- @moneta = initialize_moneta_klass(moneta_klass)
+ @backend = backend
end
def [](key)
- @moneta[key_name_for(key)]
+ @backend[key_name_for(key)]
end
def []=(key, value)
- @moneta[key_name_for(key)] = value
+ @backend[key_name_for(key)] = value
end
def delete(key)
- @moneta.delete(key_name_for(key))
+ @backend.delete(key_name_for(key))
end
private
- def initialize_moneta_klass(klass)
- require_moneta_library_for(klass)
- load_moneta_klass(klass)
- end
-
- def require_moneta_library_for(klass)
- require_klass(klass.to_s.gsub(/::/, '/').downcase)
- end
-
- def load_moneta_klass(klass)
- klass_const = klass.respond_to?(:constantize) ? klass.constantize : klass
- moneta = klass_const.new(@options)
-
- # The options hash would have messed up default Hash initialization to return an empty hash
- # when the key was not found. Revert this case by setting the default to nil if the object
- # responds to this method.
- moneta.default = nil if moneta.respond_to?(:default)
- moneta
- end
-
- def require_klass(klass)
- require klass
- end
-
def key_name_for(key)
[ @namespace, key ].join('-')
end
View
@@ -1,18 +1,17 @@
module HashBack
- # HashBack::Resource is an Object-Hash Mapping (OHM) tool for Ruby. It is able to map Ruby objects
- # to any of the backends supported by Moneta, a unified interface to key-value storage systems.
+ # HashBack::Resource is an Object-Hash Mapping (OHM) tool for Ruby. It uses a Hash-like object
+ # as the persistent resource, which can be given on HashBack::Resource initialization.
class Resource
# Configures the persistent backend for this object. Configuration options:
#
# * +source+ - the class to be persisted
# * +key_method+ - a symbol representing the method that will return a unique identifier
# for this object when called on the instance
- # * +moneta_klass+ - a String representation or class constant of the Moneta class used to store this object
- # * +moneta_options+ - an (optional) hash which is passed directly to the moneta backend for configuration
- def self.setup(source, key_method_sym, moneta_klass, moneta_options = {})
- source.__send__(:class_variable_set, :@@_backend, HashBack::Backend.new(source.to_s, moneta_klass, moneta_options))
+ # * +backend+ - a Hash-like Object (Moneta works well) for persisting this resource.
+ def self.setup(source, key_method_sym, backend)
+ source.__send__(:class_variable_set, :@@_backend, backend)
source.__send__(:class_variable_set, :@@_key_method_sym, key_method_sym)
source.__send__(:include, InstanceMethods)
@@ -23,25 +22,27 @@ module InstanceMethods
# Saves the serialized form of this object to the configured backend store.
def save
- _hashback_backend[_hashback_id_key] = self
+ hashback_backend[_hashback_id_key] = self
end
# Destroy the persisted copy of this object.
def destroy
- _hashback_backend.delete(_hashback_id_key)
+ hashback_backend.delete(_hashback_id_key)
end
- ## Methods we try to hide, because we're just sneaky like that.
-
- def _hashback_backend
+ # Convenience method for accessing the backend without having to get to the
+ # obscurely-named class variable in which it's stored.
+ def hashback_backend
self.class.__send__(:class_variable_get, :@@_backend)
end
-
+
+ ## Methods we try to hide, because we're just sneaky like that.
+
def _hashback_id_key
self.__send__(self.class.__send__(:class_variable_get, :@@_key_method_sym))
end
- private :_hashback_backend, :_hashback_id_key
+ private :_hashback_id_key
end
module ClassMethods
@@ -4,9 +4,7 @@
before do
@mock_moneta = mock('moneta')
@mock_moneta.stubs(:keys).returns(['keyname'])
- @moneta_klass = "Moneta::Memory"
- @b = HashBack::Backend.new('foo', @moneta_klass, { })
- @b.instance_variable_set(:@moneta, @mock_moneta)
+ @b = HashBack::Backend.new('foo', @mock_moneta)
@b.stubs(:key_name_for).returns('keyname')
end
@@ -31,31 +29,5 @@
@b.delete('foo')
end
end
- end
-
- describe "#initialize_moneta_klass" do
- it "should call require_moneta_library_for and load_moneta_klass" do
- b = HashBack::Backend.new('foo', @moneta_klass, { })
- b.expects(:require_moneta_library_for).with(@moneta_klass)
- b.expects(:load_moneta_klass).with(@moneta_klass)
- b.__send__(:initialize_moneta_klass, @moneta_klass)
- end
- end
-
- describe "#require_moneta_library_for" do
- it "should require the class given" do
- @b.expects(:require_klass).with('moneta/memory')
- @b.__send__(:require_moneta_library_for, "Moneta::Memory")
- end
- end
-
- describe "#load_moneta_klass" do
- it "should load the klass without error" do
- require 'moneta/memory'
-
- lambda {
- @b.__send__(:load_moneta_klass, "Moneta::Memory")
- }.should_not raise_error
- end
- end
+ end
end
@@ -3,7 +3,7 @@
require 'uuid'
class Orange
- HashBack::Resource.setup(self, :uuid, 'Moneta::Memory', { })
+ HashBack::Resource.setup(self, :uuid, { })
attr_accessor :uuid

0 comments on commit 2deaf02

Please sign in to comment.