jsl-hashback 0.0.2.5 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|