memstore 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/memstore.rb CHANGED
@@ -7,18 +7,22 @@ require "memstore/queries"
7
7
 
8
8
  module MemStore
9
9
 
10
+ # Shortcut to ObjectStore::new
10
11
  def self.new(key=nil, items={})
11
12
  ObjectStore.new(key, items)
12
13
  end
13
14
 
15
+ # Shortcut to ObjectStore::from_binary
14
16
  def self.from_binary(binary)
15
17
  ObjectStore.from_binary(binary)
16
18
  end
17
19
 
20
+ # Shortcut to ObjectStore::from_file
18
21
  def self.from_file(file)
19
22
  ObjectStore.from_file(file)
20
23
  end
21
24
 
25
+ # Shortcut to ObjectStore::with_file
22
26
  def self.with_file(file, key=nil, items={}, &block)
23
27
  ObjectStore.with_file(file, key, items, &block)
24
28
  end
@@ -2,11 +2,61 @@
2
2
 
3
3
  module MemStore
4
4
 
5
+ # A HashStore accesses item attributes through item[attribute].
5
6
  class HashStore < ObjectStore
6
7
 
8
+ # Initializes a HashStore.
9
+ #
10
+ # key - Optional Object used as an item’s key attribute (default: nil).
11
+ # When no key is specified, Object#hash will be used for uniquely identifying items.
12
+ # items - Optional Hash of items to initialize the data store with (default: empty Hash).
13
+ #
14
+ # Examples
15
+ #
16
+ # store = HashStore.new
17
+ # store = HashStore.new(:id)
18
+ # store = HashStore.new(nil, { a.hash => a, b.hash => b, c.hash => c })
19
+ # store = HashStore.new(:id, { 1 => a, 2 => b, 3 => c })
20
+ #
21
+ # Returns initialized ObjectStore.
22
+ def initialize(key=nil, items={})
23
+ @key, @items = key, items
24
+ end
25
+
26
+ # Returns data store as a Hash with the fields :key and :items.
27
+ def to_hash
28
+ { key: @key, items: @items }
29
+ end
30
+
31
+ # Restores a data store from binary format.
32
+ #
33
+ # binary - Binary data containing a serialized instance of HashStore.
34
+ #
35
+ # Examples
36
+ #
37
+ # store = HashStore.from_binary(IO.read(file))
38
+ #
39
+ # Returns instance of HashStore
40
+ # or nil if marshalling failed or marshalled object isn’t a HashStore.
41
+ # Raises whatever Marshal::load raises.
42
+ def self.from_binary(binary)
43
+ restored = Marshal.load(binary) rescue nil
44
+ if restored.instance_of?(HashStore) then restored else nil end
45
+ end
46
+
47
+ # Restores a data store from a Hash.
48
+ #
49
+ # hash - Hash that contains a serialized HashStore.
50
+ # It must have the fields :key/"key" and :items/"items".
51
+ #
52
+ # Examples
53
+ #
54
+ # store = HashStore.from_hash(hash)
55
+ #
56
+ # Returns instance of HashStore
57
+ # or nil if hash isn’t a Hash or doesn’t have the required fields.
7
58
  def self.from_hash(hash)
8
59
  begin
9
-
10
60
  if hash.has_key?(:key) then key = hash[:key]
11
61
  elsif hash.has_key? "key" then key = hash["key"]
12
62
  else return nil end
@@ -16,26 +66,30 @@ module MemStore
16
66
  else return nil end
17
67
 
18
68
  if items.is_a?(Hash) then self.new(key, items) else self.new(key) end
19
-
20
69
  rescue
21
70
  nil
22
71
  end
23
72
  end
24
73
 
25
- def initialize(key=nil, items={})
26
- @key, @items = key, items
27
- end
28
-
29
- def to_hash
30
- { key: @key, items: @items }
31
- end
32
-
33
74
  private
34
75
 
76
+ # Internal: Obtains the key attribute of an item.
77
+ #
78
+ # item - Object that responds to the [] operator (e.g. Hash).
79
+ #
80
+ # Returns result of calling the [] operator with the key attribute on the item.
81
+ # Raises NoMethodError when item does’t respond to the key attribute method.
35
82
  def key(item)
36
83
  if @key.nil? then item.hash else item[@key] end
37
84
  end
38
85
 
86
+ # Internal: Obtains the specified attribute of an item.
87
+ #
88
+ # item - Object that responds to the [] operator (e.g. Hash).
89
+ # attribute - Object used as the attribute key in the item.
90
+ #
91
+ # Returns result of calling the [] operator with the attribute on the item.
92
+ # Raises NoMethodError when item does’t respond to the [] operator.
39
93
  def attr(item, attribute)
40
94
  item[attribute]
41
95
  end
data/lib/memstore/json.rb CHANGED
@@ -23,7 +23,7 @@ module MemStore
23
23
  end
24
24
 
25
25
  def self.with_json_file(file, key=nil, items={}, &block)
26
- self.run_with_file(:from_json_file, :to_json_file, file, key, items, &block)
26
+ self.execute_with_file(:from_json_file, :to_json_file, file, key, items, &block)
27
27
  end
28
28
 
29
29
  end
@@ -23,7 +23,7 @@ module MemStore
23
23
  end
24
24
 
25
25
  def self.with_msgpack_file(file, key=nil, items={}, &block)
26
- self.run_with_file(:from_msgpack_file, :to_msgpack_file, file, key, items, &block)
26
+ self.execute_with_file(:from_msgpack_file, :to_msgpack_file, file, key, items, &block)
27
27
  end
28
28
 
29
29
  end
@@ -2,39 +2,100 @@
2
2
 
3
3
  module MemStore
4
4
 
5
+ # An ObjectStore accesses item attributes through item#attribute.
5
6
  class ObjectStore
6
7
 
8
+ # Initializes an ObjectStore.
9
+ #
10
+ # key - Optional Symbol or String naming the method to obtain an item’s key attribute (default: nil).
11
+ # When no key is specified, Object#hash will be used for uniquely identifying items.
12
+ # items - Optional Hash of items to initialize the data store with (default: empty Hash).
13
+ #
14
+ # Examples
15
+ #
16
+ # store = ObjectStore.new
17
+ # store = ObjectStore.new(:id)
18
+ # store = ObjectStore.new(nil, { a.hash => a, b.hash => b, c.hash => c })
19
+ # store = ObjectStore.new(:id, { 1 => a, 2 => b, 3 => c })
20
+ #
21
+ # Returns initialized ObjectStore.
7
22
  def initialize(key=nil, items={})
8
23
  @key = key || :hash
9
24
  @items = items
10
25
  end
11
26
 
27
+ # Provides access to internal items collection (which is simply a Hash).
12
28
  attr_accessor :items
13
29
 
30
+ # Inserts one or more items into the data store, can be chained.
31
+ # Also available as #<<, which only allows for one item at a time.
32
+ #
33
+ # items - One or more Objects that respond to the method specified as key attribute.
34
+ #
35
+ # Examples
36
+ #
37
+ # store.insert(a).insert(b).insert(c)
38
+ # store.insert(a, b, c)
39
+ # store << a << b << c
40
+ #
41
+ # Returns the data store itself to enable chaining.
42
+ # Raises NoMethodError when an item does’t respond to the key attribute method.
14
43
  def insert(*items)
15
44
  items.each { |item| @items[key(item)] = item }
16
45
  self
17
46
  end
18
47
  alias_method :<<, :insert
19
48
 
49
+ # Returns total number of items in the data store. Also available as #size.
20
50
  def length
21
51
  @items.length
22
52
  end
23
53
  alias_method :size, :length
24
- alias_method :count, :length
25
54
 
55
+ # Retrieves one or more items by key.
56
+ #
57
+ # keys - One or more Objects or Ranges that are keys of items.
58
+ # For a Range, all items with keys in that range are returned.
59
+ #
60
+ # Examples
61
+ #
62
+ # store[1]
63
+ # store[1, 2, 3]
64
+ # store[1..3]
65
+ # store[1, 3..5, 7]
66
+ #
67
+ # Returns an Object if a single key was given
68
+ # or nil if no item with that key exists
69
+ # or an Array of Objects when multiple keys were given
70
+ # in which nil is placed wherever there isn’t an item with that key.
26
71
  def [](*keys)
27
72
  return @items[keys.first] if keys.length == 1 && !keys.first.is_a?(Range)
28
- keys.inject [] do |items, key|
73
+ keys.inject([]) do |items, key|
29
74
  if key.is_a?(Range) then key.inject(items) { |i, k| i << @items[k] }
30
75
  else items << @items[key] end
31
76
  end
32
77
  end
33
78
 
79
+ # Returns all items as an Array.
34
80
  def all
35
81
  @items.values
36
82
  end
37
83
 
84
+ # Deletes one or more items by reference. Also available as #delete_item and #delete.
85
+ #
86
+ # items - One or more Objects that respond to the method specified as key attribute.
87
+ #
88
+ # Examples
89
+ #
90
+ # store.delete_item(a)
91
+ # store.delete_items(a, b, c)
92
+ # store.delete(a)
93
+ # store.delete(a, b, c)
94
+ #
95
+ # Returns the Object that was removed if a single item was given
96
+ # or nil if the item isn’t in the data store
97
+ # or an Array of Objects that were removed when multiple items were given
98
+ # in which nil is placed wherever that item isn’t in the data store.
38
99
  def delete_items(*items)
39
100
  return @items.delete(key(items.first)) if items.length == 1
40
101
  items.collect { |item| @items.delete(key(item)) }
@@ -42,47 +103,147 @@ module MemStore
42
103
  alias_method :delete_item, :delete_items
43
104
  alias_method :delete, :delete_items
44
105
 
106
+ # Deletes one or more items by key. Also available as #delete_key.
107
+ #
108
+ # keys - One or more Objects or Ranges that are keys of items.
109
+ # For a Range, all items with keys in that range are deleted.
110
+ #
111
+ # Examples
112
+ #
113
+ # store.delete_key(1)
114
+ # store.delete_keys(1, 2, 3)
115
+ # store.delete_keys(1..3)
116
+ # store.delete_keys(1, 3..5, 7)
117
+ #
118
+ # Returns the Object that was removed if a single key was given
119
+ # or nil if no item with that key exists
120
+ # or an Array of Objects that were removed when multiple keys were given
121
+ # in which nil is placed wherever there isn’t an item with that key.
45
122
  def delete_keys(*keys)
46
123
  return @items.delete(keys.first) if keys.length == 1 && !keys.first.is_a?(Range)
47
- keys.inject [] do |items, key|
124
+ keys.inject([]) do |items, key|
48
125
  if key.is_a?(Range) then key.inject(items) { |i, k| i << @items.delete(k) }
49
126
  else items << @items.delete(key) end
50
127
  end
51
128
  end
52
129
  alias_method :delete_key, :delete_keys
53
130
 
54
- def self.from_binary(binary)
55
- restored = Marshal.load(binary) rescue nil
56
- if restored.kind_of?(ObjectStore) || restored.kind_of?(HashStore) then restored else nil end
57
- end
58
-
59
- def self.from_file(file)
60
- self.from_binary(IO.read(file)) rescue nil
61
- end
62
-
131
+ # Returns data store in binary format.
132
+ # Raises whatever Marshal::dump raises.
63
133
  def to_binary
64
134
  Marshal.dump(self)
65
135
  end
66
136
 
137
+ # Writes data store to a file in binary format.
138
+ #
139
+ # file - IO stream of file name as String.
140
+ #
141
+ # Returns number of bytes that were written to the file.
142
+ # Raises whatever IO::write raises.
67
143
  def to_file(file)
68
144
  IO.write(file, self.to_binary)
69
145
  end
70
146
 
147
+ # Restores a data store from binary format.
148
+ #
149
+ # binary - Binary data containing a serialized instance of ObjectStore.
150
+ #
151
+ # Examples
152
+ #
153
+ # store = ObjectStore.from_binary(IO.read(file))
154
+ #
155
+ # Returns instance of ObjectStore
156
+ # or nil if marshalling failed or marshalled object isn’t an ObjectStore.
157
+ # Raises whatever Marshal::load raises.
158
+ def self.from_binary(binary)
159
+ restored = Marshal.load(binary) rescue nil
160
+ if restored.instance_of?(ObjectStore) then restored else nil end
161
+ end
162
+
163
+ # Restores a data store from a binary file.
164
+ #
165
+ # file - IO stream or file name as String.
166
+ #
167
+ # Examples
168
+ #
169
+ # store = ObjectStore.from_file(file)
170
+ #
171
+ # Returns instance of ObjectStore or nil (result of ::from_binary)
172
+ # or nil if file IO failed, e.g. because file doesn’t exist or isn’t readable.
173
+ # Raises whatever IO::read or Marshal::load raise.
174
+ def self.from_file(file)
175
+ self.from_binary(IO.read(file)) rescue nil
176
+ end
177
+
178
+ # Executes a given block while keeping an exclusive lock on a file.
179
+ # Allows to use the same file for persistence from multiple threads/processes.
180
+ # Tries to deserialize a data store from the file using ::from_file.
181
+ # If that fails, a new one will be created using the supplied key and items.
182
+ # Writes data store back to file using #to_file after block returns.
183
+ #
184
+ # file - IO stream or file name as String.
185
+ # key - Optional key attribute (Symbol or String) to use in ::new (default: nil).
186
+ # items - Optional items Hash to use in ::new (default: empty Hash).
187
+ # block - Block that will be called after a data store was restored or created.
188
+ #
189
+ # Yields the restored or newly created data store.
190
+ #
191
+ # Examples
192
+ #
193
+ # size_after_changes = ObjectStore.with_file(file, :id) do |store|
194
+ # store.delete(a, b, c, d, e)
195
+ # store.insert(f, g, h)
196
+ # store.size
197
+ # end
198
+ #
199
+ # Returns whatever the block returns.
200
+ # Raises whatever File::open, IO::read, Marshal::load, Marshal::dump or IO::write raise.
71
201
  def self.with_file(file, key=nil, items={}, &block)
72
- self.run_with_file(:from_file, :to_file, file, key, items, &block)
202
+ self.execute_with_file(:from_file, :to_file, file, key, items, &block)
73
203
  end
74
204
 
75
205
  private
76
206
 
207
+ # Internal: Obtains the key attribute of an item.
208
+ #
209
+ # item - Object that responds to the attribute.
210
+ #
211
+ # Returns result of calling the key attribute method on the item.
212
+ # Raises NoMethodError when item does’t respond to the key attribute method.
77
213
  def key(item)
78
214
  item.send(@key)
79
215
  end
80
216
 
217
+ # Internal: Obtains the specified attribute of an item.
218
+ #
219
+ # item - Object that responds to the attribute.
220
+ # attribute - Symbol or String naming the attribute.
221
+ #
222
+ # Returns result of calling the attribute method on the item.
223
+ # Raises NoMethodError when item does’t respond to the attribute method.
81
224
  def attr(item, attribute)
82
225
  item.send(attribute)
83
226
  end
84
227
 
85
- def self.run_with_file(from_file_method, to_file_method, file, key=nil, items={}, &block)
228
+ # Internal: Used to implement with_file and variants for different formats/subclasses.
229
+ # Takes required method names, can therefore be used by any subclass.
230
+ # Executes a given block while keeping an exclusive lock on a file.
231
+ # Tries to deserialize a data store from the file using from_file_method.
232
+ # If that fails, a new one will be created using the supplied key and items.
233
+ # Writes data store back to file using to_file_method after block returns.
234
+ #
235
+ # from_file_method - Name of class method (Symbol or String) to deserialize data store from file.
236
+ # to_file_method - Name of instance method (Symbol or String) to serialize data store to file.
237
+ # file - IO stream or file name as String.
238
+ # key - Optional key attribute (Symbol or String) to use in ::new (default: nil).
239
+ # items - Optional items Hash to use in ::new (default: empty Hash).
240
+ # block - Block that will be called after a data store was restored or created.
241
+ #
242
+ # Yields the restored or newly created data store.
243
+ #
244
+ # Returns whatever the block returns.
245
+ # Raises whatever File::open, IO::read, Marshal::load, Marshal::dump or IO::write raise.
246
+ def self.execute_with_file(from_file_method, to_file_method, file, key=nil, items={}, &block)
86
247
  File.open(file) do |file|
87
248
  file.flock(File::LOCK_EX)
88
249
  store = self.send(from_file_method, file) || self.new(key, items)
@@ -4,91 +4,141 @@ module MemStore
4
4
 
5
5
  class ObjectStore
6
6
 
7
+ # All methods have the following signature:
8
+ #
9
+ # conditions - Hash mapping attributes to conditions.
10
+ # Attributes can be Symbols or String for ObjectStore
11
+ # and any kind of Object for HashStore.
12
+ # Conditions can be any kind of Object that responds to #===.
13
+ # block - Optional block taking an item and returning a bool indicating
14
+ # whether the item passed the tests within the block.
15
+ #
16
+ # Yields every item in the data store after the conditions were evaluated for it.
17
+
18
+ ### find ###
19
+
20
+ # Also available as #find.
21
+ # Returns an Array of items that fulfill all conditions.
7
22
  def find_all(conditions={}, &block)
8
23
  all.select { |item| instance_exec(item, conditions, block, &FIND_ALL) }
9
24
  end
10
25
  alias_method :find, :find_all
11
26
 
27
+ # Returns an Array of items that fulfill at least one condition.
12
28
  def find_any(conditions={}, &block)
13
29
  all.select { |item| instance_exec(item, conditions, block, &FIND_ANY) }
14
30
  end
15
31
 
32
+ # Returns an Array of items that fulfill exactly one condition.
16
33
  def find_one(conditions={}, &block)
17
34
  all.select { |item| instance_exec(item, conditions, block, &FIND_ONE) }
18
35
  end
19
36
 
37
+ # Returns an Array of items that violate at least one condition.
20
38
  def find_not_all(conditions={}, &block)
21
39
  all.reject { |item| instance_exec(item, conditions, block, &FIND_ALL) }
22
40
  end
23
41
 
42
+ # Returns an Array of items that violate all conditions.
24
43
  def find_none(conditions={}, &block)
25
44
  all.select { |item| instance_exec(item, conditions, block, &FIND_NONE) }
26
45
  end
27
46
 
47
+ ### first ###
48
+
49
+ # Also available as #first.
50
+ # Returns the first item that fulfills all conditions.
28
51
  def first_all(conditions={}, &block)
29
52
  all.detect { |item| instance_exec(item, conditions, block, &FIND_ALL) }
30
53
  end
31
54
  alias_method :first, :first_all
32
55
 
56
+ # Returns the first item that fulfills at least one condition.
33
57
  def first_any(conditions={}, &block)
34
58
  all.detect { |item| instance_exec(item, conditions, block, &FIND_ANY) }
35
59
  end
36
60
 
61
+ # Returns the first item that fulfills exactly one condition.
37
62
  def first_one(conditions={}, &block)
38
63
  all.detect { |item| instance_exec(item, conditions, block, &FIND_ONE) }
39
64
  end
40
65
 
66
+ # which is equivalent to: !condition || !condition || ... [|| !block]
67
+ # Returns the first item that violates at least one condition.
41
68
  def first_not_all(conditions={}, &block)
42
69
  all.detect { |item| !instance_exec(item, conditions, block, &FIND_ALL) }
43
70
  end
44
71
 
72
+ # Returns the first item that violates all conditions.
45
73
  def first_none(conditions={}, &block)
46
74
  all.detect { |item| instance_exec(item, conditions, block, &FIND_NONE) }
47
75
  end
48
76
 
77
+ ### count ###
78
+
79
+ # Also available as #count.
80
+ # Returns the number of items that fulfill all conditions.
49
81
  def count_all(conditions={}, &block)
50
82
  all.count { |item| instance_exec(item, conditions, block, &FIND_ALL) }
51
83
  end
52
84
  alias_method :count, :count_all
53
85
 
86
+ # Returns the number of items that fulfill at least one condition.
54
87
  def count_any(conditions={}, &block)
55
88
  all.count { |item| instance_exec(item, conditions, block, &FIND_ANY) }
56
89
  end
57
90
 
91
+ # Returns the number of items that fulfill exactly one condition.
58
92
  def count_one(conditions={}, &block)
59
93
  all.count { |item| instance_exec(item, conditions, block, &FIND_ONE) }
60
94
  end
61
95
 
96
+ # which is equivalent to: !condition || !condition || ... [|| !block]
97
+ # Returns the number of items that violate at least one condition.
62
98
  def count_not_all(conditions={}, &block)
63
99
  all.count { |item| !instance_exec(item, conditions, block, &FIND_ALL) }
64
100
  end
65
101
 
102
+ # Returns the number of items that violate all conditions.
66
103
  def count_none(conditions={}, &block)
67
104
  all.count { |item| instance_exec(item, conditions, block, &FIND_NONE) }
68
105
  end
69
106
 
70
107
  private
71
-
108
+
109
+ # All blocks have the following signature:
110
+ #
111
+ # item - The item (Object for ObjectStore, Hash for HashStore) to be tested.
112
+ # conditions - Hash of conditions to be evaluated.
113
+ # block - Optional block that can test the item after the conditions are evaluated.
114
+ #
115
+ # Returns a bool indicating whether the item was a match
116
+ # for the given conditions and matching logic.
117
+
118
+ # Internal: Evaluates conditions using AND, i.e. condition && condition && ... [&& block]
72
119
  FIND_ALL = Proc.new do |item, conditions, block|
73
120
  conditions.all? { |attribute, condition| condition === attr(item, attribute) } &&
74
121
  if block then !!block.call(item) else true end
75
122
  end
76
123
 
124
+ # Internal: Evaluates conditions using OR, i.e. condition || condition || ... [|| block]
77
125
  FIND_ANY = Proc.new do |item, conditions, block|
78
126
  conditions.any? { |attribute, condition| condition === attr(item, attribute) } ||
79
127
  if block then !!block.call(item) else false end
80
128
  end
81
129
 
82
- FIND_NONE = Proc.new do |item, conditions, block|
83
- conditions.none? { |attribute, condition| condition === attr(item, attribute) } &&
84
- if block then !!block.call(item) else true end
85
- end
86
-
130
+ # Internal: Evaluates conditions using XOR, i.e. condition ^ condition ^ condition ... [^ block]
87
131
  FIND_ONE = Proc.new do |item, conditions, block|
88
- conditions.one? { |attribute, condition| condition === attr(item, attribute) } ||
132
+ conditions.one? { |attribute, condition| condition === attr(item, attribute) } ^
89
133
  if block then !!block.call(item) else false end
90
134
  end
91
135
 
136
+ # Internal: Evaluates condition using AND NOT, i.e. !condition && !condition && ... [&& !block]
137
+ FIND_NONE = Proc.new do |item, conditions, block|
138
+ conditions.none? { |attribute, condition| condition === attr(item, attribute) } &&
139
+ if block then !!!block.call(item) else true end
140
+ end
141
+
92
142
  end
93
143
 
94
144
  end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module MemStore
2
- VERSION = "1.2.0"
4
+ VERSION = "1.2.1"
3
5
  end
data/lib/memstore/yaml.rb CHANGED
@@ -27,7 +27,7 @@ module MemStore
27
27
  end
28
28
 
29
29
  def self.with_yaml_file(file, key=nil, items={}, &block)
30
- self.run_with_file(:from_yaml_file, :to_yaml_file, file, key, items, &block)
30
+ self.execute_with_file(:from_yaml_file, :to_yaml_file, file, key, items, &block)
31
31
  end
32
32
 
33
33
  end
@@ -34,6 +34,15 @@ describe MemStore::HashStore do
34
34
  restored.instance_variable_get(:@key).must_equal @store.instance_variable_get(:@key)
35
35
  end
36
36
 
37
+ it "returns nil when conversion from binary fails" do
38
+ MemStore::HashStore.from_binary(nil).must_equal nil
39
+ MemStore::HashStore.from_binary(Marshal.dump(Object.new)).must_equal nil
40
+ end
41
+
42
+ it "returns nil when marshalled object isn’t instance of HashStore" do
43
+ MemStore::HashStore.from_binary(MemStore::ObjectStore.new.to_binary).must_equal nil
44
+ end
45
+
37
46
  it "can be serialized to and deserialized from a binary file" do
38
47
  tmp = Tempfile.new("memstore")
39
48
  @store.to_file(tmp)
@@ -82,6 +82,10 @@ describe MemStore::ObjectStore do
82
82
  MemStore::ObjectStore.from_binary(Marshal.dump(Object.new)).must_equal nil
83
83
  end
84
84
 
85
+ it "returns nil when marshalled object isn’t instance of ObjectStore" do
86
+ MemStore::ObjectStore.from_binary(MemStore::HashStore.new.to_binary).must_equal nil
87
+ end
88
+
85
89
  it "can be serialized to and deserialized from a binary file" do
86
90
  tmp = Tempfile.new("memstore")
87
91
  @store.to_file(tmp)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: memstore
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
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-02-20 00:00:00.000000000 Z
12
+ date: 2013-02-21 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: MemStore is a simple in-memory data store that supports adding, retrieving
15
15
  and deleting items as well as complex search queries and easy serialization.