memstore 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -125,10 +125,10 @@ store << a << b << c
125
125
 
126
126
  ### Retrieving Items
127
127
 
128
- `size` returns the current number of items:
128
+ `length` (or `size`) returns the current number of items:
129
129
 
130
130
  ```ruby
131
- store.size
131
+ store.length
132
132
  # => 3
133
133
  ```
134
134
 
@@ -187,21 +187,27 @@ store.delete_keys(5..7, 9)
187
187
 
188
188
  The following methods are available to query the data store:
189
189
 
190
- - `find_all` (`find`)
190
+ - `find_all` (also available as `find`)
191
191
  - `find_any`
192
192
  - `find_one`
193
193
  - `find_not_all`
194
194
  - `find_none`
195
- - `first_all` (`first`)
195
+ - `first_all` (also available as `first`)
196
196
  - `first_any`
197
197
  - `first_one`
198
198
  - `first_not_all`
199
199
  - `first_none`
200
+ - `count_all` (also available as `count`)
201
+ - `count_any`
202
+ - `count_one`
203
+ - `count_not_all`
204
+ - `count_none`
200
205
 
201
206
  The first part indicates what is returned:
202
207
 
203
208
  - `find_*` returns all matches.
204
209
  - `first_*` returns the first match.
210
+ - `count_*` returns the number of matches.
205
211
 
206
212
  The second part indicates how conditions are evaluated:
207
213
 
@@ -213,13 +219,11 @@ The second part indicates how conditions are evaluated:
213
219
 
214
220
  In other words:
215
221
 
216
- - `all` means `condition && condition && ...`
217
- - `any` means `condition || condition || ...`
218
- - `one` means `condition ^ condition ^ ...` (XOR)
219
- - `not all` means `!(condition && condition && ...)` or `!condition || !condition || ...`
220
- - `none` means `!(condition || condition || ...)` or `!condition && !condition && ...`
221
-
222
- For convenience, `find` is aliased to `find_all` and `first` to `first_all`.
222
+ - `all` means `condition && condition && ...`.
223
+ - `any` means `condition || condition || ...`.
224
+ - `one` means `condition ^ condition ^ ...` (XOR).
225
+ - `not all` means `!(condition && condition && ...)` or `!condition || !condition || ...`.
226
+ - `none` means `!(condition || condition || ...)` or `!condition && !condition && ...`.
223
227
 
224
228
  All variants take a `conditions` hash and an optional block.
225
229
 
@@ -242,17 +246,17 @@ class Array
242
246
  end
243
247
  end
244
248
 
245
- store.find age: [23, 25, 27]
249
+ store.find(age: [23, 25, 27])
246
250
  ```
247
251
 
248
- The block is invoked with every item and can do more complex tests.
249
- Its return value is interpreted as a boolean value:
252
+ The block is invoked with the item *after* the conditions are evaluated. It should return a boolean value:
250
253
 
251
254
  ```ruby
252
- store.find { |item| item.age - item.child.age > 20 }
255
+ store.find(age: 25) { |item| item.age - item.child.age > 20 }
256
+ # is evaluated as (item.age == 25) && (item.age - item.child.age > 20)
253
257
  ```
254
258
 
255
- In addition to the evaluation logic, the arrays returned by all variants of `find` can be merged:
259
+ In addition to the evaluation logic, the arrays returned by all variants of `find_*` can be merged:
256
260
 
257
261
  ```ruby
258
262
  store.find(...) | store.find(...) | store.find(...)
@@ -263,8 +267,6 @@ Note that the pipe operator `|` already eliminates duplicates:
263
267
  ```ruby
264
268
  [a, b, c] | [c, d, e]
265
269
  # => [a, b, c, d, e]
266
- # which is equal to
267
- ([a, b, c] + [c, d, e]).uniq
268
270
  ```
269
271
 
270
272
  ### Serialization
data/lib/memstore.rb CHANGED
@@ -7,11 +7,11 @@ module MemStore
7
7
  end
8
8
 
9
9
  def self.from_binary(binary)
10
- begin Marshal.load(binary) rescue nil end
10
+ ObjectStore.from_binary(binary)
11
11
  end
12
12
 
13
13
  def self.from_file(file)
14
- begin self.from_binary(IO.read(file)) rescue nil end
14
+ ObjectStore.from_file(file)
15
15
  end
16
16
 
17
17
  class ObjectStore
@@ -29,9 +29,11 @@ module MemStore
29
29
  end
30
30
  alias_method :<<, :insert
31
31
 
32
- def size
32
+ def length
33
33
  @items.length
34
34
  end
35
+ alias_method :size, :length
36
+ alias_method :count, :length
35
37
 
36
38
  def [](*keys)
37
39
  return @items[keys.first] if keys.length == 1 && !keys.first.is_a?(Range)
@@ -103,6 +105,35 @@ module MemStore
103
105
  all.detect { |item| instance_exec(item, conditions, block, &FIND_NONE) }
104
106
  end
105
107
 
108
+ def count_all(conditions={}, &block)
109
+ all.count { |item| instance_exec(item, conditions, block, &FIND_ALL) }
110
+ end
111
+ alias_method :count, :count_all
112
+
113
+ def count_any(conditions={}, &block)
114
+ all.count { |item| instance_exec(item, conditions, block, &FIND_ANY) }
115
+ end
116
+
117
+ def count_one(conditions={}, &block)
118
+ all.count { |item| instance_exec(item, conditions, block, &FIND_ONE) }
119
+ end
120
+
121
+ def count_not_all(conditions={}, &block)
122
+ all.count { |item| !instance_exec(item, conditions, block, &FIND_ALL) }
123
+ end
124
+
125
+ def count_none(conditions={}, &block)
126
+ all.count { |item| instance_exec(item, conditions, block, &FIND_NONE) }
127
+ end
128
+
129
+ def self.from_binary(binary)
130
+ begin Marshal.load(binary) rescue nil end
131
+ end
132
+
133
+ def self.from_file(file)
134
+ begin self.from_binary(IO.read(file)) rescue nil end
135
+ end
136
+
106
137
  def to_binary
107
138
  Marshal.dump(self)
108
139
  end
@@ -1,3 +1,3 @@
1
1
  module MemStore
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -48,19 +48,32 @@ describe MemStore::ObjectStore do
48
48
  it "can be converted to and from binary" do
49
49
  o = Dummy.new("custom key")
50
50
  store = MemStore::ObjectStore.new(:id).insert(o)
51
- restored = MemStore.from_binary(store.to_binary)
51
+ restored = MemStore::ObjectStore.from_binary(store.to_binary)
52
52
  restored.must_be_instance_of MemStore::ObjectStore
53
53
  restored.items.must_equal store.items
54
54
  restored.instance_variable_get(:@key).must_equal :id
55
55
  end
56
56
 
57
+ it "returns nil when conversion from binary fails" do
58
+ MemStore::ObjectStore.from_binary(nil).must_equal nil
59
+ end
60
+
57
61
  it "can be serialized to and deserialized from a binary file" do
58
62
  tmp = Tempfile.new("memstore")
59
- MemStore::ObjectStore.new.to_file tmp
60
- MemStore.from_file(tmp).must_be_instance_of MemStore::ObjectStore
63
+ o = Dummy.new("custom key")
64
+ store = MemStore::ObjectStore.new(:id).insert(o)
65
+ store.to_file(tmp)
66
+ restored = MemStore::ObjectStore.from_file(tmp)
67
+ restored.must_be_instance_of MemStore::ObjectStore
68
+ restored.items.must_equal store.items
69
+ restored.instance_variable_get(:@key).must_equal :id
61
70
  tmp.unlink
62
71
  end
63
72
 
73
+ it "returns nil when deserialization from binary file fails" do
74
+ MemStore::ObjectStore.from_file("does_not_exist").must_equal nil
75
+ end
76
+
64
77
  end
65
78
 
66
79
  describe MemStore::HashStore do
@@ -84,9 +97,8 @@ describe MemStore::HashStore do
84
97
  end
85
98
 
86
99
  it "can be converted to and from binary" do
87
- store = MemStore::HashStore.new(:id)
88
- 10.times { |i| store << { id: i } }
89
- restored = MemStore.from_binary(store.to_binary)
100
+ store = MemStore::HashStore.new(:id).insert({ id: "custom key" })
101
+ restored = MemStore::HashStore.from_binary(store.to_binary)
90
102
  restored.must_be_instance_of MemStore::HashStore
91
103
  restored.items.must_equal store.items
92
104
  restored.instance_variable_get(:@key).must_equal :id
@@ -94,8 +106,12 @@ describe MemStore::HashStore do
94
106
 
95
107
  it "can be serialized to and deserialized from a binary file" do
96
108
  tmp = Tempfile.new("memstore")
97
- MemStore::HashStore.new.to_file tmp
98
- MemStore.from_file(tmp).must_be_instance_of MemStore::HashStore
109
+ store = MemStore::HashStore.new(:id).insert({ id: "custom key" })
110
+ store.to_file(tmp)
111
+ restored = MemStore::HashStore.from_file(tmp)
112
+ restored.must_be_instance_of MemStore::HashStore
113
+ restored.items.must_equal store.items
114
+ restored.instance_variable_get(:@key).must_equal :id
99
115
  tmp.unlink
100
116
  end
101
117
 
@@ -122,6 +138,10 @@ describe MemStore do
122
138
  10.times { |i| @store << i.to_f }
123
139
  end
124
140
 
141
+ it "returns the overall number of items" do
142
+ @store.length.must_equal 10
143
+ end
144
+
125
145
  it "returns a single item by itself" do
126
146
  @store[3].must_equal 3.0
127
147
  end
@@ -157,21 +177,6 @@ describe MemStore do
157
177
  @store.all.must_equal [0.0, 1.0, 2.0, 7.0, 8.0, 9.0]
158
178
  end
159
179
 
160
- it "can be serialized to and deserialized from a binary file" do
161
- tmp = Tempfile.new("memstore")
162
- @store.to_file tmp
163
- MemStore.from_file(tmp).items.must_equal @store.items
164
- tmp.unlink
165
- end
166
-
167
- it "returns nil when conversion from binary fails" do
168
- MemStore.from_binary(nil).must_equal nil
169
- end
170
-
171
- it "returns nil when deserialization from binary file fails" do
172
- MemStore.from_file("does_not_exist").must_equal nil
173
- end
174
-
175
180
  end
176
181
 
177
182
  describe MemStore do
@@ -235,4 +240,29 @@ describe MemStore do
235
240
  match.id.must_equal 3
236
241
  end
237
242
 
243
+ it "counts all items fulfilling all conditions" do
244
+ count = @store.count_all(id: 3..7, child: String)
245
+ count.must_equal [4, 6].length
246
+ end
247
+
248
+ it "counts all items fulfilling at least one condition" do
249
+ count = @store.count_any(id: 3..7, child: String)
250
+ count.must_equal [0, 2, 3, 4, 5, 6, 7, 8].length
251
+ end
252
+
253
+ it "counts all items fulfilling exactly one condition" do
254
+ count = @store.count_one(name: /o/, child: String)
255
+ count.must_equal [1, 4, 7, 9].length
256
+ end
257
+
258
+ it "counts all items violating at least one condition" do
259
+ count = @store.count_not_all(name: /o/, child: String)
260
+ count.must_equal [1, 3, 4, 5, 7, 9].length
261
+ end
262
+
263
+ it "counts all items violating all conditions" do
264
+ count = @store.count_none(name: /o/, child: String)
265
+ count.must_equal [3, 5].length
266
+ end
267
+
238
268
  end
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.0.1
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: