ohm_util 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gems +4 -0
- data/.gitignore +3 -0
- data/CHANGELOG.md +408 -0
- data/CONTRIBUTING +19 -0
- data/LICENSE +19 -0
- data/README.md +570 -0
- data/benchmarks/common.rb +28 -0
- data/benchmarks/create.rb +21 -0
- data/benchmarks/delete.rb +13 -0
- data/examples/activity-feed.rb +157 -0
- data/examples/chaining.rb +162 -0
- data/examples/json-hash.rb +75 -0
- data/examples/one-to-many.rb +118 -0
- data/examples/philosophy.rb +137 -0
- data/examples/redis-logging.txt +179 -0
- data/examples/slug.rb +149 -0
- data/examples/tagging.rb +237 -0
- data/lib/lua/delete.lua +72 -0
- data/lib/lua/save.lua +126 -0
- data/lib/ohm_util.rb +116 -0
- data/makefile +9 -0
- data/ohm-util.gemspec +14 -0
- data/test/association.rb +33 -0
- data/test/connection.rb +16 -0
- data/test/core.rb +24 -0
- data/test/counters.rb +67 -0
- data/test/enumerable.rb +79 -0
- data/test/filtering.rb +185 -0
- data/test/hash_key.rb +31 -0
- data/test/helper.rb +23 -0
- data/test/indices.rb +138 -0
- data/test/json.rb +62 -0
- data/test/list.rb +83 -0
- data/test/model.rb +819 -0
- data/test/set.rb +37 -0
- data/test/thread_safety.rb +67 -0
- data/test/to_hash.rb +29 -0
- data/test/uniques.rb +108 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cf5dda52c9868dfe4a8448a2d250f25aad6c0dda
|
4
|
+
data.tar.gz: 3ccef59a4db068f983537e167f1da6d77237ec79
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9e13cd84fd246ad8f0a8373d6bebbef3f8e0768a34d54dc86f23dd9617c5598d7446e9659d6ef841d400196efb3a9b4471ff8d5facc4528d6a98e886bb892d48
|
7
|
+
data.tar.gz: 8bfd55f9246fcc6c746da4c6d711e4d3b77147b5736b44f972ba2848e91f0f6fd97111a33797d27d7ea08c33df0cf56601baa095874f2e54faf1844093c49c76
|
data/.gems
ADDED
data/.gitignore
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,408 @@
|
|
1
|
+
## 3.1.1
|
2
|
+
|
3
|
+
- Serialize keys as strings when using JSON.
|
4
|
+
|
5
|
+
- Reset attributes when calling `load!`.
|
6
|
+
|
7
|
+
## 3.1.0
|
8
|
+
|
9
|
+
- Use Nest instead of Nido
|
10
|
+
|
11
|
+
A new release of Nest (3.0.0) simplified the interaction
|
12
|
+
with Redis.
|
13
|
+
|
14
|
+
- Use Model#hash for equality
|
15
|
+
|
16
|
+
This change just removes some slight redundancy in the code.
|
17
|
+
The external behavior remains unchanged.
|
18
|
+
|
19
|
+
## 3.0.3
|
20
|
+
|
21
|
+
- Fix bug that gave false positives for unique indices.
|
22
|
+
|
23
|
+
Uniques were indexed for nil values as empty strings. This
|
24
|
+
release fixes that issue.
|
25
|
+
|
26
|
+
## 3.0.2
|
27
|
+
|
28
|
+
- Fix bug created the wrong keys when indexing floats.
|
29
|
+
|
30
|
+
As reported by @slowernet, if an indexed attribute was assigned a
|
31
|
+
real value with 0 fractional part (eg. 3.0), the `tostring` function
|
32
|
+
in lua truncated the value to an integer. As a result, the index
|
33
|
+
was created with the wrong key (Model:indices:attribute:3, instead
|
34
|
+
of Model:indices:attribute:3.0). The fix is to convert all values
|
35
|
+
to strings before sending them to the Lua script.
|
36
|
+
|
37
|
+
## 3.0.1
|
38
|
+
|
39
|
+
- Adapt Lua scripts to Redis unstable.
|
40
|
+
|
41
|
+
## 3.0.0
|
42
|
+
|
43
|
+
- Use JSON instead of msgpack for internal encoding.
|
44
|
+
|
45
|
+
When Ohm started using Lua internally for saving, updating and
|
46
|
+
deleting objects, it used msgpack for serializing. Redis supports
|
47
|
+
both msgpack and JSON, and we picked msgpack because it produces
|
48
|
+
a more compact representation. At some point, the Ruby msgpack
|
49
|
+
library and the internal msgpack support in Redis diverged, and
|
50
|
+
we were forced to lock the dependency to a specific gem version.
|
51
|
+
Recently, some people complained about encoding issues originating
|
52
|
+
from msgpack inside Redis, and once they tried a modified Ohm
|
53
|
+
that uses JSON instead of msgpack, all their issues disappeared.
|
54
|
+
That's why we think it's time for removing msgpack altogether and
|
55
|
+
use JSON instead.
|
56
|
+
|
57
|
+
- Move the raise of MissingID to Ohm::Model#key.
|
58
|
+
|
59
|
+
In previous versions, trying to access an instance's `id` would
|
60
|
+
raise a `MissingID` error. The reason why raising that error is
|
61
|
+
convenient is because it allows Ohm to fail as early as possible
|
62
|
+
when you try to use an object that hasn't been saved yet. The
|
63
|
+
error can arise from comparisons, from direct calls to `id`, and
|
64
|
+
also from any call to methods that need `object.key` to return a
|
65
|
+
proper value, as `key` in turn calls the `id` method. But it turns
|
66
|
+
out that many form builders rely on the fact that sending the
|
67
|
+
`id` message to most ORMs results in either a valid ID or `nil`,
|
68
|
+
and here Ohm was the exception. By moving the check from `id` to
|
69
|
+
`key`, we can keep most of the previous behavior and we can return
|
70
|
+
`nil` when sending the `id` message to a new instance, thus making
|
71
|
+
Ohm compatible with most form builders.
|
72
|
+
|
73
|
+
- Add `Ohm::Model#increment` and `Ohm::Model#decrement`. These methods
|
74
|
+
are aliases of `incr` and `decr` respectively.
|
75
|
+
|
76
|
+
## 2.3.0
|
77
|
+
|
78
|
+
- Retry save and delete if scripts were flushed in the server.
|
79
|
+
- Depend on Redic ~> 1.5.0 in order to use of `call!` instead of `call`.
|
80
|
+
|
81
|
+
## 2.2.1
|
82
|
+
|
83
|
+
- Lock msgpack version
|
84
|
+
|
85
|
+
## 2.2.0
|
86
|
+
|
87
|
+
- Use Stal for set operations
|
88
|
+
|
89
|
+
## 2.1.0
|
90
|
+
|
91
|
+
- Add `combine` filter
|
92
|
+
|
93
|
+
## 2.0.0
|
94
|
+
|
95
|
+
- Lists now respond to range.
|
96
|
+
|
97
|
+
Example:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
class Comment < Ohm::Model
|
101
|
+
end
|
102
|
+
|
103
|
+
class Post < Ohm::Model
|
104
|
+
list :comments, :Comment
|
105
|
+
end
|
106
|
+
|
107
|
+
c1 = Comment.create
|
108
|
+
c2 = Comment.create
|
109
|
+
c3 = Comment.create
|
110
|
+
|
111
|
+
post = Post.create
|
112
|
+
post.comments.push(c1)
|
113
|
+
post.comments.push(c2)
|
114
|
+
post.comments.push(c3)
|
115
|
+
|
116
|
+
post.comments.range(0, 1) == [c1, c2]
|
117
|
+
# => true
|
118
|
+
```
|
119
|
+
|
120
|
+
- When a record is created, `#id` returns a string instead of an integer.
|
121
|
+
This ensures IDs are strings everywhere:
|
122
|
+
|
123
|
+
Example:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
|
127
|
+
# Before
|
128
|
+
Meetup.create(name: "Ruby").id # => 1
|
129
|
+
Meetup.with(:name, "Ruby").id # => "1"
|
130
|
+
|
131
|
+
# Now
|
132
|
+
Meetup.create(name: "Ruby").id # => "1"
|
133
|
+
Meetup.with(:name, "Ruby").id # => "1"
|
134
|
+
```
|
135
|
+
|
136
|
+
- If an attribute is set to an empty string, Ohm won't delete it.
|
137
|
+
|
138
|
+
Example:
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
# Before
|
142
|
+
event = Meetup.create(location: "")
|
143
|
+
Meetup[event.id].location # => nil
|
144
|
+
|
145
|
+
# Now
|
146
|
+
event = Meetup.create(location: "")
|
147
|
+
Meetup[event.id].location # => ""
|
148
|
+
```
|
149
|
+
|
150
|
+
- Include `Ohm::List#ids` in the public API. It returns an array with all
|
151
|
+
the ID's in the list.
|
152
|
+
|
153
|
+
Example:
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
class Comment < Ohm::Model
|
157
|
+
end
|
158
|
+
|
159
|
+
class Post < Ohm::Model
|
160
|
+
list :comments, :Comment
|
161
|
+
end
|
162
|
+
|
163
|
+
post = Post.create
|
164
|
+
post.comments.push(Comment.create)
|
165
|
+
post.comments.push(Comment.create)
|
166
|
+
post.comments.push(Comment.create)
|
167
|
+
|
168
|
+
post.comments.ids
|
169
|
+
# => ["1", "2", "3"]
|
170
|
+
```
|
171
|
+
|
172
|
+
- Include `Ohm::BasicSet#exists?` in the public API. This makes possible
|
173
|
+
to check if an id is included in a set. Check `Ohm::BasicSet#exists?`
|
174
|
+
documentation for more details.
|
175
|
+
|
176
|
+
Example:
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
class Post < Ohm::Model
|
180
|
+
end
|
181
|
+
|
182
|
+
class User < Ohm::Model
|
183
|
+
set :posts, :Post
|
184
|
+
end
|
185
|
+
|
186
|
+
user = User.create
|
187
|
+
user.posts.add(post = Post.create)
|
188
|
+
|
189
|
+
user.posts.exists?(post.id) # => true
|
190
|
+
user.posts.exists?("nonexistent") # => false
|
191
|
+
```
|
192
|
+
|
193
|
+
- Change `Ohm::MultiSet#except` to union keys instead of intersect them
|
194
|
+
when passing an array.
|
195
|
+
|
196
|
+
Example:
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
class User < Ohm::Model
|
200
|
+
attribute :name
|
201
|
+
end
|
202
|
+
|
203
|
+
john = User.create(name: "John")
|
204
|
+
jane = User.create(name: "Jane")
|
205
|
+
|
206
|
+
res = User.all.except(name: [john.name, jane.name])
|
207
|
+
|
208
|
+
# Before
|
209
|
+
res.size # => 2
|
210
|
+
|
211
|
+
# Now
|
212
|
+
res.size # => 0
|
213
|
+
```
|
214
|
+
|
215
|
+
- Move ID generation to Lua. With this change, it's no longer possible
|
216
|
+
to generate custom ids. All ids are autoincremented.
|
217
|
+
|
218
|
+
- Add `Ohm::Model.track` method to allow track of custom keys. This key
|
219
|
+
is removed when the model is deleted.
|
220
|
+
|
221
|
+
Example:
|
222
|
+
|
223
|
+
```ruby
|
224
|
+
class Foo < Ohm::Model
|
225
|
+
track :notes
|
226
|
+
end
|
227
|
+
|
228
|
+
foo = Foo.create
|
229
|
+
|
230
|
+
Foo.redis.call("SET", foo.key[:notes], "something")
|
231
|
+
Foo.redis.call("GET", "Foo:1:notes")
|
232
|
+
# => "something"
|
233
|
+
|
234
|
+
foo.delete
|
235
|
+
Foo.redis.call("GET", "Foo:1:notes")
|
236
|
+
# => nil
|
237
|
+
```
|
238
|
+
|
239
|
+
- `Ohm::Model#reference` accepts strings as model references.
|
240
|
+
|
241
|
+
Example:
|
242
|
+
|
243
|
+
```ruby
|
244
|
+
class Bar < Ohm::Model
|
245
|
+
reference :foo, "SomeNamespace::Foo"
|
246
|
+
end
|
247
|
+
|
248
|
+
Bar.create.foo.class # => SomeNamespace::Foo
|
249
|
+
```
|
250
|
+
|
251
|
+
- `Ohm::Model#save` sanitizes attributes before sending them to Lua.
|
252
|
+
This complies with the original spec in Ohm v1 where a `to_s`
|
253
|
+
is done on each value.
|
254
|
+
|
255
|
+
Example:
|
256
|
+
|
257
|
+
```ruby
|
258
|
+
class Post < Ohm::Model
|
259
|
+
attribute :published
|
260
|
+
end
|
261
|
+
|
262
|
+
post = Post.create(published: true)
|
263
|
+
post = Post[post.id]
|
264
|
+
|
265
|
+
# Before
|
266
|
+
post.published # => "1"
|
267
|
+
|
268
|
+
# Now
|
269
|
+
post.published # => "true"
|
270
|
+
```
|
271
|
+
|
272
|
+
- `Ohm::Model#save` don't save values for attributes set to false.
|
273
|
+
|
274
|
+
Example:
|
275
|
+
|
276
|
+
```ruby
|
277
|
+
class Post < Ohm::Model
|
278
|
+
attribute :published
|
279
|
+
end
|
280
|
+
|
281
|
+
post = Post.create(published: false)
|
282
|
+
post = Post[post.id]
|
283
|
+
|
284
|
+
# Before
|
285
|
+
post.published # => "0"
|
286
|
+
|
287
|
+
# Now
|
288
|
+
post.published # => nil
|
289
|
+
```
|
290
|
+
|
291
|
+
- `nest` dependency has been removed. Now, Ohm uses [nido][nido]
|
292
|
+
to generate the keys that hold the data.
|
293
|
+
|
294
|
+
- `scrivener` dependency has been removed. Ohm no longer supports model
|
295
|
+
validations and favors filter validation on the boundary layer. Check
|
296
|
+
[scrivener][scrivener] project for more information.
|
297
|
+
|
298
|
+
- `redis` dependency has been removed. Ohm 2 uses [redic][redic],
|
299
|
+
a lightweight Redis client. Redic uses the `hiredis` gem for the
|
300
|
+
connection and for parsing the replies. Now, it defaults to a
|
301
|
+
Redic connection to "redis://127.0.0.1:6379". To change it, you
|
302
|
+
will need to provide an instance of `Redic` through the `Ohm.redis=`
|
303
|
+
helper.
|
304
|
+
|
305
|
+
Example:
|
306
|
+
|
307
|
+
```ruby
|
308
|
+
Ohm.redis = Redic.new("redis://:<passwd>@<host>:<port>/<db>")
|
309
|
+
```
|
310
|
+
|
311
|
+
Check the Redic README for more details.
|
312
|
+
|
313
|
+
- `Ohm::Model#transaction` and `Ohm::Transaction` have been removed.
|
314
|
+
|
315
|
+
- Move `save` and `delete` operations to Lua scripts.
|
316
|
+
|
317
|
+
- Support for Ruby 1.8 has been removed.
|
318
|
+
|
319
|
+
[nido]: https://github.com/soveran/nido
|
320
|
+
[scrivener]: https://github.com/soveran/scrivener
|
321
|
+
[redic]: https://github.com/amakawa/redic
|
322
|
+
|
323
|
+
## 1.4.0
|
324
|
+
|
325
|
+
- Add `combine` filter
|
326
|
+
|
327
|
+
## 1.3.2
|
328
|
+
|
329
|
+
- Fetching a batch of objects is now done in batches of 1000 objects at
|
330
|
+
a time. If you are iterating over large collections, this change should
|
331
|
+
provide a significant performance boost both in used memory and total
|
332
|
+
execution time.
|
333
|
+
|
334
|
+
- `MutableSet#<<` is now an alias for `#add`.
|
335
|
+
|
336
|
+
## 1.3.1
|
337
|
+
|
338
|
+
- Improve memory consumption when indexing persisted attributes.
|
339
|
+
No migration is needed and old indices will be cleaned up as you save
|
340
|
+
instances.
|
341
|
+
|
342
|
+
## 1.3.0
|
343
|
+
|
344
|
+
- Add Model.attributes.
|
345
|
+
|
346
|
+
## 1.2.0
|
347
|
+
|
348
|
+
- Enumerable fix.
|
349
|
+
|
350
|
+
- Merge Ohm::PipelinedFetch into Ohm::Collection.
|
351
|
+
|
352
|
+
- Fix Set, MultiSet, and List enumerable behavior.
|
353
|
+
|
354
|
+
- Change dependencies to use latest cutest.
|
355
|
+
|
356
|
+
## 1.1.0
|
357
|
+
|
358
|
+
- Compatible with redis-rb 3.
|
359
|
+
|
360
|
+
## 1.0.0
|
361
|
+
|
362
|
+
- Fetching a batch of objects is now done through one pipeline, effectively
|
363
|
+
reducing the IO to just 2 operations (one for SMEMBERS / LRANGE, one for
|
364
|
+
the actual HGET of all the individual HASHes.)
|
365
|
+
|
366
|
+
- write_remote / read_remote have been replaced with set / get respectively.
|
367
|
+
|
368
|
+
- Ohm::Model.unique has been added.
|
369
|
+
|
370
|
+
- Ohm::Model::Set has been renamed to Ohm::Set
|
371
|
+
|
372
|
+
- Ohm::Model::List has been renamed to Ohm::List
|
373
|
+
|
374
|
+
- Ohm::Model::Collection is gone.
|
375
|
+
|
376
|
+
- Ohm::Validations is gone. Ohm now uses Scrivener::Validations.
|
377
|
+
|
378
|
+
- Ohm::Key is gone. Ohm now uses Nest directly.
|
379
|
+
|
380
|
+
- No more concept of volatile keys.
|
381
|
+
|
382
|
+
- Ohm::Model::Wrapper is gone.
|
383
|
+
|
384
|
+
- Use Symbols for constants instead of relying on Ohm::Model.const_missing.
|
385
|
+
|
386
|
+
- `#sort` / `#sort_by` now uses `limit` as it's used in redis-rb, e.g. you
|
387
|
+
have to pass in an array like so: sort(limit: [0, 1]).
|
388
|
+
|
389
|
+
- Set / List have been trimmed to contain only the minimum number
|
390
|
+
of necessary methods.
|
391
|
+
|
392
|
+
- You can no longer mutate a collection / set as before, e.g. doing
|
393
|
+
User.find(...).add(User[1]) will throw an error.
|
394
|
+
|
395
|
+
- The #union operation has been added. You can now chain it with your filters.
|
396
|
+
|
397
|
+
- Temporary keys when doing finds are now automatically cleaned up.
|
398
|
+
|
399
|
+
- Counters are now stored in their own key instead, i.e. in
|
400
|
+
User:<id>:counters.
|
401
|
+
|
402
|
+
- JSON support has to be explicitly required by doing `require
|
403
|
+
"ohm/json"`.
|
404
|
+
|
405
|
+
- All save / delete / update operations are now done using
|
406
|
+
transactions (see http://redis.io/topics/transactions).
|
407
|
+
|
408
|
+
- All indices are now stored without converting the values to base64.
|
data/CONTRIBUTING
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
This code tries to solve a particular problem with a very simple
|
2
|
+
implementation. We try to keep the code to a minimum while making
|
3
|
+
it as clear as possible. The design is very likely finished, and
|
4
|
+
if some feature is missing it is possible that it was left out on
|
5
|
+
purpose. That said, new usage patterns may arise, and when that
|
6
|
+
happens we are ready to adapt if necessary.
|
7
|
+
|
8
|
+
A good first step for contributing is to meet us on IRC and discuss
|
9
|
+
ideas. We spend a lot of time on #lesscode at freenode, always ready
|
10
|
+
to talk about code and simplicity. If connecting to IRC is not an
|
11
|
+
option, you can create an issue explaining the proposed change and
|
12
|
+
a use case. We pay a lot of attention to use cases, because our
|
13
|
+
goal is to keep the code base simple. Usually the result of a
|
14
|
+
conversation is the creation of a different tool.
|
15
|
+
|
16
|
+
Please don't start the conversation with a pull request. The code
|
17
|
+
should come at last, and even though it may help to convey an idea,
|
18
|
+
more often than not it draws the attention to a particular
|
19
|
+
implementation.
|
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2009 Michel Martens and Damian Janowski
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|