hash_cabinet 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +48 -0
  3. data/lib/hash_cabinet.rb +218 -0
  4. metadata +44 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d284b1a7d996a2e750db02e4db77d2be4afb543ae88da7a385174f00f1533b9c
4
+ data.tar.gz: 270859870c5130c08e057cb7379f74902bf691db52c87ee8dffe592343b7dd14
5
+ SHA512:
6
+ metadata.gz: c3e93b6bc0904c02f003b8c913c7d25989d0526e0233bfdd612faedd75cfeb3fd193bf026066371a98fe26a33d8ae4fc4a3c274f0351eb1fbb31f063b609c9c1
7
+ data.tar.gz: 01d325e99d38b83f73c0e3007d546884af69af974f3193b6908b476ac8cadfb9a10ec16efec49bbd11e75e16aa7886a5e9635128c915ca4be1709f9ec7c93f54
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ Hash Cabinet - File based key-object store
2
+ ==================================================
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/hash_cabinet.svg)](https://badge.fury.io/rb/hash_cabinet)
5
+
6
+ ---
7
+
8
+ Hash Cabinet is a file-based, key-object store with hash-like access.
9
+
10
+
11
+ Highlights
12
+ --------------------------------------------------
13
+
14
+ - Tiny library, based on Ruby's built in [SDBM].
15
+ - Stores simple values or complex objects through transparent YAML
16
+ serialization.
17
+ - Easy hash-like access: `cabinet['key'] = 'value'`.
18
+ - Mirrors most of the native SDBM methods.
19
+
20
+
21
+ Installation
22
+ --------------------------------------------------
23
+
24
+ $ gem install hash_cabinet
25
+
26
+
27
+
28
+ Usage
29
+ --------------------------------------------------
30
+
31
+ ```ruby
32
+ cabinet = HashCabinet.new 'dbfile'
33
+
34
+ # Store values
35
+ cabinet['some-key'] = 'some=value'
36
+ cabinet['another-key'] = { color: 'yellow' }
37
+
38
+ # Retrieve values
39
+ p cabinet['another-key']
40
+ #=> {:color=>"yellow", :shape=>"circle"}
41
+
42
+ # Show all values
43
+ p cabinet.to_h
44
+ #=> {"some-key"=>"some=value", "another-key"=>{:color=>"yellow"}
45
+
46
+ ```
47
+
48
+ [SDBM]: https://ruby-doc.org/stdlib-2.6.3/libdoc/sdbm/rdoc/SDBM.html
@@ -0,0 +1,218 @@
1
+ require 'sdbm'
2
+ require 'yaml'
3
+
4
+ class HashCabinet
5
+
6
+ # Refinements to allow using +from_yaml+ as the opposite of +to_yaml+.
7
+ module ReverseYAML
8
+ refine String do
9
+ def from_yaml
10
+ YAML.load self
11
+ end
12
+ end
13
+
14
+ refine NilClass do
15
+ def from_yaml
16
+ nil
17
+ end
18
+ end
19
+ end
20
+
21
+ using ReverseYAML
22
+
23
+ # Returns the path to the database file.
24
+ attr_reader :path
25
+
26
+ # Initialize a new database file at {path}.
27
+ def initialize(path)
28
+ @path = path
29
+ end
30
+
31
+ # Yields the +SDBM+ object to the block. Under most circumstances, this
32
+ # method should not be used directly, as it is used by all other methods.
33
+ #
34
+ # Example:
35
+ #
36
+ # cabinet = HashCabinet.new 'filename'
37
+ #
38
+ # cabinet.transaction do |db|
39
+ # db.clear
40
+ # end
41
+ #
42
+ def transaction(&block)
43
+ SDBM.open path, &block
44
+ end
45
+
46
+ # Returns the value in the database associated with the given +key+.
47
+ def [](key)
48
+ transaction { |db| db[key].from_yaml }
49
+ end
50
+
51
+ # Inserts or updates a value in the database with the given key as an index.
52
+ def []=(key, value)
53
+ transaction { |db| db[key] = value.to_yaml }
54
+ end
55
+
56
+ # Deletes all key-value pairs from the database.
57
+ def clear
58
+ transaction { |db| db.clear }
59
+ end
60
+
61
+ # Deletes the given `key` from the database.
62
+ def delete(key)
63
+ transaction { |db| db.delete key }
64
+ end
65
+
66
+ # Iterates over the key-value pairs in the database, deleting those for
67
+ # which the block returns true.
68
+ def delete_if(&block)
69
+ transaction do |db|
70
+ db.delete_if do |key, value|
71
+ yield key, value.from_yaml
72
+ end
73
+ end
74
+ end
75
+
76
+ # Iterates over each key-value pair in the database.
77
+ def each(&block)
78
+ transaction do |db|
79
+ db.each do |key, value|
80
+ yield key, value.from_yaml
81
+ end
82
+ end
83
+ end
84
+
85
+
86
+ # Iterates over each key in the database.
87
+ def each_key(&block)
88
+ transaction { |db| db.each_key &block }
89
+ end
90
+
91
+
92
+ # Iterates over each key-value pair in the database.
93
+ def each_value(&block)
94
+ transaction do |db|
95
+ db.each_value do |value|
96
+ yield value.from_yaml
97
+ end
98
+ end
99
+ end
100
+
101
+ # Returns +true+ if the database is empty.
102
+ def empty?
103
+ transaction { |db| db.empty? }
104
+ end
105
+
106
+ # Returns true if the database contains the given key.
107
+ def has_key?(key)
108
+ transaction { |db| db.has_key? key }
109
+ end
110
+
111
+ # Returns +true+ if the database contains the given value.
112
+ def has_value?(value)
113
+ transaction { |db| db.has_value? value.to_yaml }
114
+ end
115
+
116
+ # Returns +true+ if the database contains the given key.
117
+ def include?(key)
118
+ transaction { |db| db.include? key }
119
+ end
120
+
121
+ # Returns the key associated with the given value. If more than one key
122
+ # corresponds to the given value, then the first key will be returned.
123
+ # If no keys are found, +nil+ will be returned.
124
+ def key(value)
125
+ transaction { |db| db.key value.to_yaml }
126
+ end
127
+
128
+ # Returns +true+ if the database contains the given key.
129
+ def key?(key)
130
+ transaction { |db| db.key? key }
131
+ end
132
+
133
+ # Returns a new Array containing the keys in the database.
134
+ def keys
135
+ transaction { |db| db.keys }
136
+ end
137
+
138
+ # Returns the number of keys in the database.
139
+ def length
140
+ transaction { |db| db.length }
141
+ end
142
+
143
+ # Empties the database, then inserts the given key-value pairs.
144
+ # This method will work with any object which implements an +#each_pair+
145
+ # method, such as a Hash.
146
+ def replace(data)
147
+ data = data.transform_values &:to_yaml
148
+ data = data.transform_keys &:to_s
149
+ transaction { |db| db.replace data }
150
+ end
151
+
152
+ # Returns a new Hash of key-value pairs for which the block returns true.
153
+ def select(&block)
154
+ transaction do |db|
155
+ db.select do |key, value|
156
+ yield key, value.from_yaml
157
+ end.to_h.transform_values &:from_yaml
158
+ end
159
+ end
160
+
161
+ # Removes a key-value pair from the database and returns them as an Array.
162
+ #
163
+ # If the database is empty, returns nil.
164
+ def shift
165
+ transaction do |db|
166
+ result = db.shift
167
+ [result[0], result[1].from_yaml]
168
+ end
169
+ end
170
+
171
+ # Returns the number of keys in the database.
172
+ def size
173
+ transaction { |db| db.size }
174
+ end
175
+
176
+ # Returns a new Array containing each key-value pair in the database.
177
+ def to_a
178
+ transaction do |db|
179
+ db.to_a.map { |pair| [pair[0], pair[1].from_yaml] }
180
+ end
181
+ end
182
+
183
+ # Returns a new Hash containing each key-value pair in the database.
184
+ def to_h
185
+ transaction do |db|
186
+ db.to_h.transform_values &:from_yaml
187
+ end
188
+ end
189
+
190
+ # Insert or update key-value pairs.
191
+ #
192
+ # This method will work with any object which implements an +#each_pair+
193
+ # method, such as a Hash.
194
+ def update(data)
195
+ data = data.transform_values &:to_yaml
196
+ transaction { |db| db.update data }
197
+ end
198
+
199
+ # Returns +true+ if the database contains the given value.
200
+ def value?(value)
201
+ transaction { |db| db.value? value.to_yaml }
202
+ end
203
+
204
+ # Returns a new Array containing the values in the database.
205
+ def values
206
+ transaction do |db|
207
+ db.values.map &:from_yaml
208
+ end
209
+ end
210
+
211
+ # Returns an Array of values corresponding to the given keys.
212
+ def values_at(*key)
213
+ transaction do |db|
214
+ db.values_at(*key).map &:from_yaml
215
+ end
216
+ end
217
+
218
+ end
metadata ADDED
@@ -0,0 +1,44 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hash_cabinet
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Danny Ben Shitrit
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-09-18 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Store objects in a file using hash-like syntax
14
+ email: db@dannyben.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - README.md
20
+ - lib/hash_cabinet.rb
21
+ homepage: https://github.com/dannyben/hash_cabinet
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.4.0
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubygems_version: 3.0.4
41
+ signing_key:
42
+ specification_version: 4
43
+ summary: Key-object file database with hash-like access
44
+ test_files: []