jsl-hashback 0.0.2.5 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +12 -8
- data/hashback.gemspec +13 -8
- data/init.rb +2 -0
- data/lib/hashback.rb +0 -1
- data/lib/hashback/backend.rb +12 -33
- data/lib/hashback/resource.rb +14 -13
- data/spec/hashback/backend_spec.rb +2 -30
- metadata +5 -34
data/README.rdoc
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
= HashBack
|
2
2
|
|
3
3
|
HashBack is a simple Object-hash mapping (OHM) system for Ruby. It allows for serializable classes to be saved,
|
4
|
-
retrieved and deleted from any key-value store
|
5
|
-
(a unified interface to key-value systems).
|
4
|
+
retrieved and deleted from any key-value store. It works particulary well with, but has no dependency on
|
5
|
+
{Moneta}[http://github.com/wycats/moneta/tree/master] (a unified interface to key-value systems).
|
6
6
|
|
7
7
|
== Quick Start
|
8
8
|
|
@@ -21,7 +21,7 @@ UUIDs created by the assaf-uuid gem, so we'll include that as well.
|
|
21
21
|
Below we create a simple class that is serializable to HashBack.
|
22
22
|
|
23
23
|
class Elephant
|
24
|
-
HashBack::Resource.setup(self, :uuid,
|
24
|
+
HashBack::Resource.setup(self, :uuid, Moneta::Memory.new)
|
25
25
|
|
26
26
|
attr_accessor :uuid, :name
|
27
27
|
|
@@ -46,6 +46,12 @@ When you're sick of Dumbo and want to get rid of him:
|
|
46
46
|
|
47
47
|
Note that at this point the data is still available in the instance variables for Dumbo, but the persisted form of him is gone.
|
48
48
|
|
49
|
+
== HashBack::Backend
|
50
|
+
|
51
|
+
A lightweight class called HashBack::Backend is included with the distribution of this gem. This class wraps common Hash-like
|
52
|
+
getter and setter methods with ones that include a namespace. This may be helpful to you if you're persisting many objects
|
53
|
+
to the same backend data store. Please see the documentation for HashBack::Backend for more information.
|
54
|
+
|
49
55
|
== Detailed usage
|
50
56
|
|
51
57
|
Generally, HashBack should work with any class that can be serialized. You can decide which key-value storage system
|
@@ -57,7 +63,7 @@ follows:
|
|
57
63
|
require 'hashback'
|
58
64
|
|
59
65
|
class Foo
|
60
|
-
HashBack::Resource.setup(self, :id, 'Moneta::Memcache
|
66
|
+
HashBack::Resource.setup(self, :id, HashBack::Backend.new('Foo', Moneta::Memcache.new(:server => 'localhost:1978')))
|
61
67
|
end
|
62
68
|
|
63
69
|
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
|
|
77
83
|
The following features are not present in the current library, but may be useful:
|
78
84
|
|
79
85
|
* A system of callbacks
|
80
|
-
* A system for associating objects, perhaps constrained to objects that have a 1 - 1 mapping
|
81
|
-
intuitive what the structures or algorithms would be for mainting integrity with higher levels of mapping between
|
82
|
-
objects).
|
86
|
+
* A system for associating objects, perhaps constrained to objects that have a 1 - 1 mapping
|
83
87
|
|
84
88
|
== Feedback
|
85
89
|
|
86
|
-
Please write the author if you have any questions or
|
90
|
+
Please write the author if you have any questions or feedback regarding this library.
|
87
91
|
|
88
92
|
== Author
|
89
93
|
|
data/hashback.gemspec
CHANGED
@@ -1,11 +1,20 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "hashback"
|
3
|
-
s.version = "0.0.
|
3
|
+
s.version = "0.0.3"
|
4
4
|
s.date = "2009-05-13"
|
5
|
-
|
5
|
+
|
6
|
+
s.summary = "Ruby Object-Hash Mapping system (OHM)"
|
7
|
+
|
8
|
+
s.description = <<-EOF
|
9
|
+
HashBack makes your ruby class persistent by adding methods which will save and retrieve it from a
|
10
|
+
backend key-value store. Useful when you have objects that should respond to #save and #fetch (as
|
11
|
+
a class method). Works well with the Moneta gem, which automatically serializes objects before they
|
12
|
+
are saved and after they are retrieved, but functions with any key-value storage system.
|
13
|
+
EOF
|
14
|
+
|
6
15
|
s.email = "justin@phq.org"
|
7
16
|
s.homepage = "http://github.com/jsl/hashback"
|
8
|
-
s.description = "
|
17
|
+
s.description = "HashBack"
|
9
18
|
s.has_rdoc = true
|
10
19
|
s.authors = ["Justin Leitgeb"]
|
11
20
|
s.files = [
|
@@ -32,9 +41,5 @@ Gem::Specification.new do |s|
|
|
32
41
|
'--main', 'README.rdoc',
|
33
42
|
'--line-numbers',
|
34
43
|
'--inline-source'
|
35
|
-
]
|
36
|
-
|
37
|
-
s.add_dependency("jsl-moneta")
|
38
|
-
s.add_dependency("activesupport")
|
39
|
-
s.add_dependency("assaf-uuid")
|
44
|
+
]
|
40
45
|
end
|
data/init.rb
CHANGED
data/lib/hashback.rb
CHANGED
data/lib/hashback/backend.rb
CHANGED
@@ -1,54 +1,33 @@
|
|
1
1
|
module HashBack
|
2
2
|
|
3
|
-
#
|
4
|
-
# a
|
5
|
-
#
|
3
|
+
# Proxy class over a key-value storage object which adds a namespace to keys. Useful if you
|
4
|
+
# have a number of different things that are saving to the same object space. Of course, then
|
5
|
+
# you may want to consider just opening up new key-value stores. This class may safely be
|
6
|
+
# ignored if not needed by your application.
|
6
7
|
class Backend
|
7
8
|
|
8
|
-
|
9
|
+
# Backend accepts a namespace which will be added to all keys on retrieval and
|
10
|
+
# setting, and a backend that responds to Hash-like methods. Moneta classes
|
11
|
+
# see the Moneta gem) work well as the backends to this class.
|
12
|
+
def initialize(namespace, backend)
|
9
13
|
@namespace = namespace
|
10
|
-
@
|
11
|
-
@moneta = initialize_moneta_klass(moneta_klass)
|
14
|
+
@backend = backend
|
12
15
|
end
|
13
16
|
|
14
17
|
def [](key)
|
15
|
-
@
|
18
|
+
@backend[key_name_for(key)]
|
16
19
|
end
|
17
20
|
|
18
21
|
def []=(key, value)
|
19
|
-
@
|
22
|
+
@backend[key_name_for(key)] = value
|
20
23
|
end
|
21
24
|
|
22
25
|
def delete(key)
|
23
|
-
@
|
26
|
+
@backend.delete(key_name_for(key))
|
24
27
|
end
|
25
28
|
|
26
29
|
private
|
27
30
|
|
28
|
-
def initialize_moneta_klass(klass)
|
29
|
-
require_moneta_library_for(klass)
|
30
|
-
load_moneta_klass(klass)
|
31
|
-
end
|
32
|
-
|
33
|
-
def require_moneta_library_for(klass)
|
34
|
-
require_klass(klass.to_s.gsub(/::/, '/').downcase)
|
35
|
-
end
|
36
|
-
|
37
|
-
def load_moneta_klass(klass)
|
38
|
-
klass_const = klass.respond_to?(:constantize) ? klass.constantize : klass
|
39
|
-
moneta = klass_const.new(@options)
|
40
|
-
|
41
|
-
# The options hash would have messed up default Hash initialization to return an empty hash
|
42
|
-
# when the key was not found. Revert this case by setting the default to nil if the object
|
43
|
-
# responds to this method.
|
44
|
-
moneta.default = nil if moneta.respond_to?(:default)
|
45
|
-
moneta
|
46
|
-
end
|
47
|
-
|
48
|
-
def require_klass(klass)
|
49
|
-
require klass
|
50
|
-
end
|
51
|
-
|
52
31
|
def key_name_for(key)
|
53
32
|
[ @namespace, key ].join('-')
|
54
33
|
end
|
data/lib/hashback/resource.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module HashBack
|
2
2
|
|
3
|
-
# HashBack::Resource is an Object-Hash Mapping (OHM) tool for Ruby. It
|
4
|
-
#
|
3
|
+
# HashBack::Resource is an Object-Hash Mapping (OHM) tool for Ruby. It uses a Hash-like object
|
4
|
+
# as the persistent resource, which can be given on HashBack::Resource initialization.
|
5
5
|
class Resource
|
6
6
|
|
7
7
|
# Configures the persistent backend for this object. Configuration options:
|
@@ -9,10 +9,9 @@ module HashBack
|
|
9
9
|
# * +source+ - the class to be persisted
|
10
10
|
# * +key_method+ - a symbol representing the method that will return a unique identifier
|
11
11
|
# for this object when called on the instance
|
12
|
-
# * +
|
13
|
-
|
14
|
-
|
15
|
-
source.__send__(:class_variable_set, :@@_backend, HashBack::Backend.new(source.to_s, moneta_klass, moneta_options))
|
12
|
+
# * +backend+ - a Hash-like Object (Moneta works well) for persisting this resource.
|
13
|
+
def self.setup(source, key_method_sym, backend)
|
14
|
+
source.__send__(:class_variable_set, :@@_backend, backend)
|
16
15
|
source.__send__(:class_variable_set, :@@_key_method_sym, key_method_sym)
|
17
16
|
|
18
17
|
source.__send__(:include, InstanceMethods)
|
@@ -23,25 +22,27 @@ module HashBack
|
|
23
22
|
|
24
23
|
# Saves the serialized form of this object to the configured backend store.
|
25
24
|
def save
|
26
|
-
|
25
|
+
hashback_backend[_hashback_id_key] = self
|
27
26
|
end
|
28
27
|
|
29
28
|
# Destroy the persisted copy of this object.
|
30
29
|
def destroy
|
31
|
-
|
30
|
+
hashback_backend.delete(_hashback_id_key)
|
32
31
|
end
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
def
|
33
|
+
# Convenience method for accessing the backend without having to get to the
|
34
|
+
# obscurely-named class variable in which it's stored.
|
35
|
+
def hashback_backend
|
37
36
|
self.class.__send__(:class_variable_get, :@@_backend)
|
38
37
|
end
|
39
|
-
|
38
|
+
|
39
|
+
## Methods we try to hide, because we're just sneaky like that.
|
40
|
+
|
40
41
|
def _hashback_id_key
|
41
42
|
self.__send__(self.class.__send__(:class_variable_get, :@@_key_method_sym))
|
42
43
|
end
|
43
44
|
|
44
|
-
private :
|
45
|
+
private :_hashback_id_key
|
45
46
|
end
|
46
47
|
|
47
48
|
module ClassMethods
|
@@ -4,9 +4,7 @@ describe HashBack::Backend do
|
|
4
4
|
before do
|
5
5
|
@mock_moneta = mock('moneta')
|
6
6
|
@mock_moneta.stubs(:keys).returns(['keyname'])
|
7
|
-
@
|
8
|
-
@b = HashBack::Backend.new('foo', @moneta_klass, { })
|
9
|
-
@b.instance_variable_set(:@moneta, @mock_moneta)
|
7
|
+
@b = HashBack::Backend.new('foo', @mock_moneta)
|
10
8
|
@b.stubs(:key_name_for).returns('keyname')
|
11
9
|
end
|
12
10
|
|
@@ -31,31 +29,5 @@ describe HashBack::Backend do
|
|
31
29
|
@b.delete('foo')
|
32
30
|
end
|
33
31
|
end
|
34
|
-
end
|
35
|
-
|
36
|
-
describe "#initialize_moneta_klass" do
|
37
|
-
it "should call require_moneta_library_for and load_moneta_klass" do
|
38
|
-
b = HashBack::Backend.new('foo', @moneta_klass, { })
|
39
|
-
b.expects(:require_moneta_library_for).with(@moneta_klass)
|
40
|
-
b.expects(:load_moneta_klass).with(@moneta_klass)
|
41
|
-
b.__send__(:initialize_moneta_klass, @moneta_klass)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe "#require_moneta_library_for" do
|
46
|
-
it "should require the class given" do
|
47
|
-
@b.expects(:require_klass).with('moneta/memory')
|
48
|
-
@b.__send__(:require_moneta_library_for, "Moneta::Memory")
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
describe "#load_moneta_klass" do
|
53
|
-
it "should load the klass without error" do
|
54
|
-
require 'moneta/memory'
|
55
|
-
|
56
|
-
lambda {
|
57
|
-
@b.__send__(:load_moneta_klass, "Moneta::Memory")
|
58
|
-
}.should_not raise_error
|
59
|
-
end
|
60
|
-
end
|
32
|
+
end
|
61
33
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsl-hashback
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Leitgeb
|
@@ -11,38 +11,9 @@ cert_chain: []
|
|
11
11
|
|
12
12
|
date: 2009-05-13 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
|
17
|
-
type: :runtime
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: "0"
|
24
|
-
version:
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: activesupport
|
27
|
-
type: :runtime
|
28
|
-
version_requirement:
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: "0"
|
34
|
-
version:
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: assaf-uuid
|
37
|
-
type: :runtime
|
38
|
-
version_requirement:
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
40
|
-
requirements:
|
41
|
-
- - ">="
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
version: "0"
|
44
|
-
version:
|
45
|
-
description: Wrapper around Moneta that facilitates using the key-value store as a backend for applications requiring namespacing
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: HashBack
|
46
17
|
email: justin@phq.org
|
47
18
|
executables: []
|
48
19
|
|
@@ -89,7 +60,7 @@ rubyforge_project:
|
|
89
60
|
rubygems_version: 1.2.0
|
90
61
|
signing_key:
|
91
62
|
specification_version: 2
|
92
|
-
summary:
|
63
|
+
summary: Ruby Object-Hash Mapping system (OHM)
|
93
64
|
test_files:
|
94
65
|
- spec/hashback/backend_spec.rb
|
95
66
|
- spec/hashback_spec.rb
|