Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit eec47acdccf8ad02b4f4844943c8009242060124 0 parents
@jsl authored
2  .gitignore
@@ -0,0 +1,2 @@
+tmp/*
+*.gem
20 LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2007 Justin S. Leitgeb
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 README.rdoc
@@ -0,0 +1,8 @@
+= HashBack
+
+Provides a general interface over Moneta which allows namespacing of key values and the requirement of correct
+Moneta backend class.
+
+== Author
+
+Justin S. Leitgeb, <justin@phq.org>
25 Rakefile
@@ -0,0 +1,25 @@
+require 'rubygems'
+require 'spec'
+
+require 'rake'
+require 'spec/rake/spectask'
+require 'rake/rdoctask'
+
+desc 'Test the plugin.'
+Spec::Rake::SpecTask.new(:spec) do |t|
+ t.spec_opts = ["--format", "specdoc", "--colour"]
+ t.libs << 'lib'
+ t.verbose = true
+end
+
+desc "Run all the tests"
+task :default => :spec
+
+desc 'Generate documentation for the hashback plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'HashBack'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
27 hashback.gemspec
@@ -0,0 +1,27 @@
+Gem::Specification.new do |s|
+ s.name = "hashback"
+ s.version = "0.0.1"
+ s.date = "2009-05-13"
+ s.summary = "Generic tool for writing namespaced key-value data to a variety of hash-type systems"
+ 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.has_rdoc = true
+ s.authors = ["Justin Leitgeb"]
+ s.files = [
+ "Rakefile",
+ "hashback.gemspec",
+ "init.rb",
+ "LICENSE",
+ "README.rdoc",
+ "Rakefile",
+ "lib/hashback.rb",
+ "lib/hashback/backend.rb"
+ ]
+ s.test_files = [
+ "spec/hashback/backend_spec.rb",
+ "spec/hashback_spec.rb",
+ "spec/spec_helper.rb"
+ ]
+ s.add_dependency("wycats-moneta", ["> 0.0.0"])
+end
1  init.rb
@@ -0,0 +1 @@
+require 'hashback'
1  lib/hashback.rb
@@ -0,0 +1 @@
+require File.expand_path(File.join(File.dirname(__FILE__), %w[hashback backend] ))
50 lib/hashback/backend.rb
@@ -0,0 +1,50 @@
+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.
+ class Backend
+
+ def initialize(namespace, moneta_klass, options = { })
+ @namespace = namespace
+ @options = options
+ @cache = initialize_cache_klass(moneta_klass)
+ end
+
+ def [](key)
+ @cache[key_name_for(key)]
+ end
+
+ def []=(key, value)
+ @cache[key_name_for(key)] = value
+ end
+
+ def delete(key)
+ @cache.delete(key_name_for(key))
+ end
+
+ private
+
+ def initialize_cache_klass(cache_klass)
+ require_moneta_library_for(cache_klass)
+ klass_const = cache_klass.respond_to?(:constantize) ? cache_klass.constantize : cache_klass
+ klass_const.new(@options)
+ end
+
+ def require_moneta_library_for(cache_klass)
+ require_klass(cache_klass.to_s.gsub(/::/, '/').downcase)
+ end
+
+ def require_klass(klass)
+ require klass
+ end
+
+ def key_name_for(key)
+ [ @namespace, key ].join('-')
+ end
+
+ def table_name_from(archived_attribute)
+ archived_attribute.instance.class.table_name
+ end
+ end
+end
33 spec/hashback/backend_spec.rb
@@ -0,0 +1,33 @@
+require File.join(File.dirname(__FILE__), %w[ .. spec_helper ])
+
+describe HashBack::Backend do
+ before do
+ @moneta = mock('moneta')
+ HashBack::Backend.any_instance.stubs(:initialize_cache_klass).returns(@moneta)
+ @b = HashBack::Backend.new('foo', 'MonetaKlass', { })
+ @b.stubs(:key_name_for).returns('keyname')
+ end
+
+ describe "methods proxied to backend" do
+ describe "#[]" do
+ it "should call the backend with the key name" do
+ @moneta.expects(:[]).with('keyname')
+ @b['keyname']
+ end
+ end
+
+ describe "#[]=" do
+ it "should call the backend with the key name and value" do
+ @moneta.expects(:[]=).with('keyname', 'value')
+ @b['keyname'] = 'value'
+ end
+ end
+
+ describe "#delete" do
+ it "should call delete for this key name on the backend" do
+ @moneta.expects(:delete).with('keyname')
+ @b.delete('foo')
+ end
+ end
+ end
+end
4 spec/hashback_spec.rb
@@ -0,0 +1,4 @@
+require File.join(File.dirname(__FILE__), 'spec_helper')
+
+describe HashBack do
+end
9 spec/spec_helper.rb
@@ -0,0 +1,9 @@
+require 'rubygems'
+require 'mocha'
+require 'spec'
+
+Spec::Runner.configure do |config|
+ config.mock_with(:mocha)
+end
+
+require File.join(File.dirname(__FILE__), %w[.. init])
Please sign in to comment.
Something went wrong with that request. Please try again.