keyvaluetree 0.0.4 → 0.0.5
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/LICENSE +21 -0
- data/README.md +21 -3
- data/lib/keyvaluetree/hash.rb +69 -14
- data/lib/keyvaluetree/memory_store.rb +1 -1
- data/lib/keyvaluetree/store.rb +37 -16
- data/lib/keyvaluetree/transaction_store.rb +1 -1
- data/lib/keyvaluetree/version.rb +1 -1
- data/test/hash_test.rb +1 -1
- metadata +5 -4
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Udo Schneider <Udo.Schneider@homeaddress.de>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# keyvaluetree
|
2
2
|
|
3
|
-
|
3
|
+
keyvalutree provides an wrapper around a flat KeyValueStore which emulates an hierachical store (i.e. nested Hashes).
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -18,7 +18,25 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
|
21
|
+
### Simple
|
22
|
+
|
23
|
+
config = KeyValueTree::Hash.new()
|
24
|
+
|
25
|
+
config.server.name = 'localhost'
|
26
|
+
config.server['port'] = '123'
|
27
|
+
|
28
|
+
config.server['name'] => 'localhost'
|
29
|
+
config.server.port = '123'
|
30
|
+
|
31
|
+
### Using explicit MemoryStore
|
32
|
+
|
33
|
+
config = KeyValueTree::Hash.new(KeyValueTree::MemoryStore.new())
|
34
|
+
|
35
|
+
config.server.name = 'localhost'
|
36
|
+
config.server['port'] = '123'
|
37
|
+
|
38
|
+
config.server['name'] => 'localhost'
|
39
|
+
config.server.port = '123'
|
22
40
|
|
23
41
|
## Contributing
|
24
42
|
|
data/lib/keyvaluetree/hash.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module KeyValueTree
|
2
2
|
|
3
|
+
# Hash implements an hierachical Hash (i.e. Hashes in Hashes) backed by a flat-hash Store.
|
3
4
|
class Hash
|
4
5
|
|
5
6
|
attr_reader :store
|
@@ -10,6 +11,11 @@ module KeyValueTree
|
|
10
11
|
@store = store
|
11
12
|
end
|
12
13
|
|
14
|
+
# @!group Operations
|
15
|
+
|
16
|
+
# Return the value for the given key. If the the key is nil return self. If the value is nil (empty) return a new instance of Hash for the key
|
17
|
+
# @param [String]key The key to fetch
|
18
|
+
# @return [String,KeyValueTree::Hash] The result
|
13
19
|
def [] (key)
|
14
20
|
return self if key.nil?
|
15
21
|
value = @store.key(key_path_string(key))
|
@@ -17,6 +23,10 @@ module KeyValueTree
|
|
17
23
|
return KeyValueTree::Hash.new(@store, key, self)
|
18
24
|
end
|
19
25
|
|
26
|
+
# Set a value for the given key.
|
27
|
+
# @param [String]key The key to set
|
28
|
+
# @param [String]value The value to set
|
29
|
+
# @return [String] The value
|
20
30
|
def []= (key, value)
|
21
31
|
if value.is_a?(::Hash)
|
22
32
|
value.each do |hash_key, hash_value|
|
@@ -34,6 +44,58 @@ module KeyValueTree
|
|
34
44
|
return value
|
35
45
|
end
|
36
46
|
|
47
|
+
# Return the value for the given key. If the the key is nil return self. If the value is nil (empty) return a new instance of Hash for the key
|
48
|
+
# @param [String]key The key to fetch
|
49
|
+
# @return [String,KeyValueTree::Hash] The result
|
50
|
+
def [] (key)
|
51
|
+
return self if key.nil?
|
52
|
+
value = @store.key(key_path_string(key))
|
53
|
+
return value unless value.nil?
|
54
|
+
return KeyValueTree::Hash.new(@store, key, self)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Delete the value for the given key
|
58
|
+
# @param [String]key The key to delete
|
59
|
+
# @return [String,KeyValueTree::Hash] The value of the deleted key
|
60
|
+
def delete(key)
|
61
|
+
@store.delete(key_path_string(key.to_s))
|
62
|
+
end
|
63
|
+
|
64
|
+
# Delete the value for the given key and it's sub-keys
|
65
|
+
# @note This method might raise an exception if the store does not support the operation.
|
66
|
+
# @param [String]key The key to delete
|
67
|
+
# @return [nil] Undefined
|
68
|
+
def delete_all(key)
|
69
|
+
@store.delete_all(key_path_string(key.to_s))
|
70
|
+
end
|
71
|
+
|
72
|
+
# Import the given ::Hash into the Hash.
|
73
|
+
# @param [Hash]object The object to import
|
74
|
+
# @return [self]
|
75
|
+
def import(object)
|
76
|
+
self[nil] = object
|
77
|
+
end
|
78
|
+
|
79
|
+
# Return all keys.
|
80
|
+
# @note This method might raise an exception if the store does not support the operation.
|
81
|
+
# @return [Array<String>] An Array of keys
|
82
|
+
def keys
|
83
|
+
@store.keys_starting_with(key_path_string()).map { |each| each.split(".").first }.uniq
|
84
|
+
end
|
85
|
+
|
86
|
+
# Return true if the Hash is the root Hash (i.e. has no parent)
|
87
|
+
# @return [Boolean]
|
88
|
+
def root?
|
89
|
+
@parent.nil?
|
90
|
+
end
|
91
|
+
|
92
|
+
# @!endgroup
|
93
|
+
|
94
|
+
# @!group Helpers
|
95
|
+
|
96
|
+
# Handle method dispatch for missing methods. Provides the functionality to access a value using hash.key or set it via hash.key = value.
|
97
|
+
# @param [Symbol]method The called method
|
98
|
+
# @param [Array]args Provided arguments (if any)
|
37
99
|
def method_missing(method, *args)
|
38
100
|
property = method.to_s
|
39
101
|
if property =~ /=$/
|
@@ -43,6 +105,9 @@ module KeyValueTree
|
|
43
105
|
end
|
44
106
|
end
|
45
107
|
|
108
|
+
# Return the keypath to self as Array of keys. Append key is given
|
109
|
+
# @param [String,nil]key The subkey (if any)
|
110
|
+
# @return [Array<String>] An array of keys (starting with the root key)
|
46
111
|
def key_path(key = nil)
|
47
112
|
if root?
|
48
113
|
return [] if key.nil?
|
@@ -53,6 +118,9 @@ module KeyValueTree
|
|
53
118
|
end
|
54
119
|
end
|
55
120
|
|
121
|
+
# Return the keypath to self as dot separated String of keys. Append key is given
|
122
|
+
# @param [String,nil]key The subkey (if any)
|
123
|
+
# @return [String] A dot separated String of keys (starting with the root key)
|
56
124
|
def key_path_string(key = nil)
|
57
125
|
result = ''
|
58
126
|
key_path(key).each_with_index do |value, index|
|
@@ -66,21 +134,8 @@ module KeyValueTree
|
|
66
134
|
return result
|
67
135
|
end
|
68
136
|
|
69
|
-
|
70
|
-
@parent.nil?
|
71
|
-
end
|
137
|
+
# @!endgroup
|
72
138
|
|
73
|
-
def delete(key)
|
74
|
-
@store.delete(key_path_string(key.to_s))
|
75
|
-
end
|
76
|
-
|
77
|
-
def keys
|
78
|
-
@store.keys_starting_with(key_path_string()).map { |each| each.split(".").first }.uniq
|
79
|
-
end
|
80
|
-
|
81
|
-
def import(object)
|
82
|
-
self[nil] = object
|
83
|
-
end
|
84
139
|
end
|
85
140
|
|
86
141
|
end
|
data/lib/keyvaluetree/store.rb
CHANGED
@@ -1,47 +1,68 @@
|
|
1
1
|
module KeyValueTree
|
2
2
|
|
3
|
+
# This class defines the methods expected by KeyValueTree::Hash for it's Store backend
|
3
4
|
class Store
|
4
5
|
|
5
|
-
|
6
|
-
raise NotImplementedError
|
7
|
-
end
|
6
|
+
# @!group Required methods
|
8
7
|
|
8
|
+
# Return the value for the given key
|
9
|
+
# @param [String]key The key to fetch
|
10
|
+
# @return [String] The value for key or nil
|
9
11
|
def key(key)
|
10
12
|
raise NotImplementedError
|
11
13
|
end
|
12
14
|
|
15
|
+
# Store the value at the given key
|
16
|
+
# @param [String]key The key to store
|
17
|
+
# @param [String]value The value to store
|
18
|
+
# @return [String] The value
|
13
19
|
def store(key, value)
|
14
20
|
raise NotImplementedError
|
15
21
|
end
|
16
22
|
|
17
|
-
|
23
|
+
# Delete the given key
|
24
|
+
# @param [String]key The key to delete
|
25
|
+
# @return [String] The value for key or nil
|
26
|
+
def delete(key)
|
18
27
|
raise NotImplementedError
|
19
28
|
end
|
20
29
|
|
21
|
-
|
22
|
-
raise NotImplementedError
|
23
|
-
end
|
30
|
+
# @!endgroup
|
24
31
|
|
25
|
-
|
32
|
+
# @!group Optional methods (as some stores don't support (sub-) key enumeration)
|
33
|
+
|
34
|
+
# Fetch all keys in store
|
35
|
+
# @return [Array<String>] All keys in store
|
36
|
+
def keys
|
26
37
|
raise NotImplementedError
|
27
38
|
end
|
28
39
|
|
29
|
-
|
30
|
-
|
40
|
+
# Fetch all keys in store with the given key prefix
|
41
|
+
# @param [String]key The key prefix
|
42
|
+
# @return [Array<String>] All keys in store
|
43
|
+
def keys_starting_with(key)
|
44
|
+
self.keys.select do |sub_key|
|
45
|
+
sub_key.start_with?(key.to_s)
|
46
|
+
end
|
31
47
|
end
|
32
48
|
|
33
|
-
|
49
|
+
# Delete all keys starting with the given prefix
|
50
|
+
# @param [String]key The key prefix
|
51
|
+
# @return nil
|
52
|
+
def delete_all(key)
|
34
53
|
keys_starting_with(key.to_s).each do |each|
|
35
|
-
self.
|
54
|
+
self.delete(each)
|
36
55
|
end
|
37
56
|
end
|
38
57
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
58
|
+
# Convert the store to a *hierachical* Hash
|
59
|
+
# return [Hash]
|
60
|
+
def to_hash
|
61
|
+
raise NotImplementedError
|
43
62
|
end
|
44
63
|
|
64
|
+
# @!endgroup
|
65
|
+
|
45
66
|
end
|
46
67
|
|
47
68
|
end
|
data/lib/keyvaluetree/version.rb
CHANGED
data/test/hash_test.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keyvaluetree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-09-
|
12
|
+
date: 2013-09-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- .idea/misc.xml
|
88
88
|
- .idea/vcs.xml
|
89
89
|
- Gemfile
|
90
|
+
- LICENSE
|
90
91
|
- LICENSE.txt
|
91
92
|
- README.md
|
92
93
|
- Rakefile
|
@@ -116,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
117
|
version: '0'
|
117
118
|
segments:
|
118
119
|
- 0
|
119
|
-
hash: -
|
120
|
+
hash: -1788352517375914173
|
120
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
122
|
none: false
|
122
123
|
requirements:
|
@@ -125,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
126
|
version: '0'
|
126
127
|
segments:
|
127
128
|
- 0
|
128
|
-
hash: -
|
129
|
+
hash: -1788352517375914173
|
129
130
|
requirements: []
|
130
131
|
rubyforge_project:
|
131
132
|
rubygems_version: 1.8.24
|