ohm 3.0.3 → 3.1.0
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.
- checksums.yaml +4 -4
- data/.gems +2 -3
- data/CHANGELOG.md +12 -0
- data/README.md +39 -20
- data/lib/ohm.rb +25 -31
- data/ohm.gemspec +2 -2
- data/test/indices.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65d8dd7c7555b0a26c8f4eb8845c08354b174acc
|
4
|
+
data.tar.gz: b12b6410534f2031ae211eff20604e9ac6da4473
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 322e82928c55dc4fbaa9a370220c8e7c0bc382ef4a709fd96456add67a4b26f56617f7f54af4c5a3c14af59fc27fe50fa0ad6339db9246be7c1bee87fa743ddd
|
7
|
+
data.tar.gz: dbf21bd5c4984b2d6cbbb8c379aa88696c0a2a154d1fcf5cccfad35ca2e24856d223bb6e3b4642c556b163e82ae344e1cf9d45e2fcfe5b625aca6ef8b5c36d3f
|
data/.gems
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
## 3.1.0
|
2
|
+
|
3
|
+
- Use Nest instead of Nido
|
4
|
+
|
5
|
+
A new release of Nest (3.0.0) simplified the interaction
|
6
|
+
with Redis.
|
7
|
+
|
8
|
+
- Use Model#hash for equality
|
9
|
+
|
10
|
+
This change just removes some slight redundancy in the code.
|
11
|
+
The external behavior remains unchanged.
|
12
|
+
|
1
13
|
## 3.0.3
|
2
14
|
|
3
15
|
- Fix bug that gave false positives for unique indices.
|
data/README.md
CHANGED
@@ -21,6 +21,7 @@ Related projects
|
|
21
21
|
|
22
22
|
These are libraries in other languages that were inspired by Ohm.
|
23
23
|
|
24
|
+
* [Ohm](https://github.com/soveran/ohm-crystal) for Crystal, created by soveran
|
24
25
|
* [JOhm](https://github.com/xetorthio/johm) for Java, created by xetorthio
|
25
26
|
* [Lohm](https://github.com/slact/lua-ohm) for Lua, created by slact
|
26
27
|
* [ohm.lua](https://github.com/amakawa/ohm.lua) for Lua, created by amakawa
|
@@ -174,15 +175,15 @@ Attribute types
|
|
174
175
|
|
175
176
|
Ohm::Model provides 4 attribute types:
|
176
177
|
|
177
|
-
*
|
178
|
-
*
|
179
|
-
*
|
180
|
-
*
|
178
|
+
* `Ohm::Model.attribute`,
|
179
|
+
* `Ohm::Model.set`
|
180
|
+
* `Ohm::Model.list`
|
181
|
+
* `Ohm::Model.counter`
|
181
182
|
|
182
183
|
and 2 meta types:
|
183
184
|
|
184
|
-
*
|
185
|
-
*
|
185
|
+
* `Ohm::Model.reference`
|
186
|
+
* `Ohm::Model.collection`.
|
186
187
|
|
187
188
|
### attribute
|
188
189
|
|
@@ -304,9 +305,9 @@ end
|
|
304
305
|
|
305
306
|
## Sorting
|
306
307
|
|
307
|
-
Since `attendees` is a
|
308
|
-
methods:
|
309
|
-
ordered by `id`, and
|
308
|
+
Since `attendees` is a `Ohm::Model::Set`, it exposes two sorting
|
309
|
+
methods: `Ohm::Model::Collection#sort` returns the elements
|
310
|
+
ordered by `id`, and `Ohm::Model::Collection#sort_by` receives
|
310
311
|
a parameter with an attribute name, which will determine the sorting
|
311
312
|
order. Both methods receive an options hash which is explained below:
|
312
313
|
|
@@ -337,8 +338,8 @@ Example:
|
|
337
338
|
### :by
|
338
339
|
|
339
340
|
Key or Hash key with which to sort by. An important distinction with
|
340
|
-
using
|
341
|
-
|
341
|
+
using `Ohm::Model::Collection#sort` and
|
342
|
+
`Ohm::Model::Collection#sort_by` is that `sort_by` automatically
|
342
343
|
converts the passed argument with the assumption that it is a hash key
|
343
344
|
and it's within the current model you are sorting.
|
344
345
|
|
@@ -354,8 +355,8 @@ otherwise.
|
|
354
355
|
### :get
|
355
356
|
|
356
357
|
A key pattern to return, e.g. `Post:*->title`. As is the case with
|
357
|
-
the `:by` option, using
|
358
|
-
|
358
|
+
the `:by` option, using `Ohm::Model::Collection#sort` and
|
359
|
+
`Ohm::Model::Collection#sort_by` has distinct differences in
|
359
360
|
that `sort_by` does much of the hand-coding for you.
|
360
361
|
|
361
362
|
```ruby
|
@@ -391,7 +392,7 @@ you can use `post.comments.ids`.
|
|
391
392
|
|
392
393
|
### References explained
|
393
394
|
|
394
|
-
Doing a
|
395
|
+
Doing a `Ohm::Model.reference` is actually just a shortcut for
|
395
396
|
the following:
|
396
397
|
|
397
398
|
```ruby
|
@@ -423,10 +424,10 @@ Comment.find(post_id: 1)
|
|
423
424
|
|
424
425
|
### Collections explained
|
425
426
|
|
426
|
-
The reason a
|
427
|
-
|
427
|
+
The reason a `Ohm::Model.reference` and a
|
428
|
+
`Ohm::Model.collection` go hand in hand, is that a collection is
|
428
429
|
just a macro that defines a finder for you, and we know that to find a model
|
429
|
-
by a field requires an
|
430
|
+
by a field requires an `Ohm::Model.index` to be defined for the field
|
430
431
|
you want to search.
|
431
432
|
|
432
433
|
```ruby
|
@@ -460,18 +461,36 @@ Post.to_reference == :post
|
|
460
461
|
# => true
|
461
462
|
```
|
462
463
|
|
464
|
+
Modules
|
465
|
+
-------
|
466
|
+
|
467
|
+
If your models are defined inside a module, you will have to define
|
468
|
+
the references and collections as in the following example:
|
469
|
+
|
470
|
+
```ruby
|
471
|
+
module SomeNamespace
|
472
|
+
class Foo < Ohm::Model
|
473
|
+
attribute :name
|
474
|
+
end
|
475
|
+
|
476
|
+
class Bar < Ohm::Model
|
477
|
+
reference :foo, 'SomeNamespace::Foo'
|
478
|
+
end
|
479
|
+
end
|
480
|
+
```
|
481
|
+
|
463
482
|
Indices
|
464
483
|
-------
|
465
484
|
|
466
|
-
An
|
485
|
+
An `Ohm::Model.index` is a set that's handled automatically by Ohm. For
|
467
486
|
any index declared, Ohm maintains different sets of objects IDs for quick
|
468
487
|
lookups.
|
469
488
|
|
470
489
|
In the `Event` example, the index on the name attribute will
|
471
490
|
allow for searches like `Event.find(name: "some value")`.
|
472
491
|
|
473
|
-
Note that the methods
|
474
|
-
|
492
|
+
Note that the methods `Ohm::Model::Set#find` and
|
493
|
+
`Ohm::Model::Set#except` need a corresponding index in order to work.
|
475
494
|
|
476
495
|
### Finding records
|
477
496
|
|
data/lib/ohm.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
require "json"
|
4
|
-
require "
|
4
|
+
require "nest"
|
5
5
|
require "redic"
|
6
6
|
require "stal"
|
7
7
|
|
@@ -173,17 +173,17 @@ module Ohm
|
|
173
173
|
|
174
174
|
# Returns the total size of the list using LLEN.
|
175
175
|
def size
|
176
|
-
|
176
|
+
key.call("LLEN")
|
177
177
|
end
|
178
178
|
|
179
179
|
# Returns the first element of the list using LINDEX.
|
180
180
|
def first
|
181
|
-
model[
|
181
|
+
model[key.call("LINDEX", 0)]
|
182
182
|
end
|
183
183
|
|
184
184
|
# Returns the last element of the list using LINDEX.
|
185
185
|
def last
|
186
|
-
model[
|
186
|
+
model[key.call("LINDEX", -1)]
|
187
187
|
end
|
188
188
|
|
189
189
|
# Returns an array of elements from the list using LRANGE.
|
@@ -211,7 +211,7 @@ module Ohm
|
|
211
211
|
# [c1, c2] == post.comments.range(0, 1)
|
212
212
|
# # => true
|
213
213
|
def range(start, stop)
|
214
|
-
fetch(
|
214
|
+
fetch(key.call("LRANGE", start, stop))
|
215
215
|
end
|
216
216
|
|
217
217
|
# Checks if the model is part of this List.
|
@@ -255,12 +255,12 @@ module Ohm
|
|
255
255
|
|
256
256
|
# Pushes the model to the _end_ of the list using RPUSH.
|
257
257
|
def push(model)
|
258
|
-
|
258
|
+
key.call("RPUSH", model.id)
|
259
259
|
end
|
260
260
|
|
261
261
|
# Pushes the model to the _beginning_ of the list using LPUSH.
|
262
262
|
def unshift(model)
|
263
|
-
|
263
|
+
key.call("LPUSH", model.id)
|
264
264
|
end
|
265
265
|
|
266
266
|
# Delete a model from the list.
|
@@ -292,7 +292,7 @@ module Ohm
|
|
292
292
|
|
293
293
|
# LREM key 0 <id> means remove all elements matching <id>
|
294
294
|
# @see http://redis.io/commands/lrem
|
295
|
-
|
295
|
+
key.call("LREM", 0, model.id)
|
296
296
|
end
|
297
297
|
|
298
298
|
# Returns an array with all the ID's of the list.
|
@@ -316,7 +316,7 @@ module Ohm
|
|
316
316
|
# # => ["1", "2", "3"]
|
317
317
|
#
|
318
318
|
def ids
|
319
|
-
|
319
|
+
key.call("LRANGE", 0, -1)
|
320
320
|
end
|
321
321
|
|
322
322
|
private
|
@@ -378,7 +378,7 @@ module Ohm
|
|
378
378
|
if Array === key
|
379
379
|
Stal.solve(redis, key)
|
380
380
|
else
|
381
|
-
|
381
|
+
key.call("SMEMBERS")
|
382
382
|
end
|
383
383
|
end
|
384
384
|
|
@@ -599,7 +599,7 @@ module Ohm
|
|
599
599
|
# user.posts.add(post)
|
600
600
|
#
|
601
601
|
def add(model)
|
602
|
-
|
602
|
+
key.call("SADD", model.id)
|
603
603
|
end
|
604
604
|
|
605
605
|
alias_method :<<, :add
|
@@ -614,7 +614,7 @@ module Ohm
|
|
614
614
|
# user.posts.delete(post)
|
615
615
|
#
|
616
616
|
def delete(model)
|
617
|
-
|
617
|
+
key.call("SREM", model.id)
|
618
618
|
end
|
619
619
|
|
620
620
|
# Replace all the existing elements of a set with a different
|
@@ -719,18 +719,14 @@ module Ohm
|
|
719
719
|
# class User < Ohm::Model
|
720
720
|
# end
|
721
721
|
#
|
722
|
-
# User.key
|
723
|
-
# User.key.kind_of?(String)
|
722
|
+
# User.key.kind_of?(Nest)
|
724
723
|
# # => true
|
725
724
|
#
|
726
|
-
#
|
727
|
-
#
|
728
|
-
#
|
729
|
-
# To find out more about Nido, see:
|
730
|
-
# http://github.com/soveran/nido
|
725
|
+
# To find out more about Nest, see:
|
726
|
+
# http://github.com/soveran/nest
|
731
727
|
#
|
732
728
|
def self.key
|
733
|
-
@key ||=
|
729
|
+
@key ||= Nest.new(self.name, redis)
|
734
730
|
end
|
735
731
|
|
736
732
|
# Retrieve a record by ID.
|
@@ -763,7 +759,7 @@ module Ohm
|
|
763
759
|
|
764
760
|
# Check if the ID exists within <Model>:all.
|
765
761
|
def self.exists?(id)
|
766
|
-
|
762
|
+
key[:all].call("SISMEMBER", id) == 1
|
767
763
|
end
|
768
764
|
|
769
765
|
# Find values in `unique` indices.
|
@@ -781,7 +777,7 @@ module Ohm
|
|
781
777
|
def self.with(att, val)
|
782
778
|
raise IndexNotFound unless uniques.include?(att)
|
783
779
|
|
784
|
-
id =
|
780
|
+
id = key[:uniques][att].call("HGET", val)
|
785
781
|
new(:id => id).load! if id
|
786
782
|
end
|
787
783
|
|
@@ -1079,7 +1075,7 @@ module Ohm
|
|
1079
1075
|
define_method(name) do
|
1080
1076
|
return 0 if new?
|
1081
1077
|
|
1082
|
-
|
1078
|
+
key[:counters].call("HGET", name).to_i
|
1083
1079
|
end
|
1084
1080
|
end
|
1085
1081
|
|
@@ -1141,15 +1137,13 @@ module Ohm
|
|
1141
1137
|
# 2. That they represent the same Redis key.
|
1142
1138
|
#
|
1143
1139
|
def ==(other)
|
1144
|
-
other.kind_of?(model) && other.
|
1145
|
-
rescue MissingID
|
1146
|
-
false
|
1140
|
+
other.kind_of?(model) && other.hash == hash
|
1147
1141
|
end
|
1148
1142
|
|
1149
1143
|
# Preload all the attributes of this model from Redis. Used
|
1150
1144
|
# internally by `Model::[]`.
|
1151
1145
|
def load!
|
1152
|
-
update_attributes(Utils.dict(
|
1146
|
+
update_attributes(Utils.dict(key.call("HGETALL"))) unless new?
|
1153
1147
|
return self
|
1154
1148
|
end
|
1155
1149
|
|
@@ -1170,7 +1164,7 @@ module Ohm
|
|
1170
1164
|
# | u.get(:name) == "B"
|
1171
1165
|
#
|
1172
1166
|
def get(att)
|
1173
|
-
@attributes[att] =
|
1167
|
+
@attributes[att] = key.call("HGET", att)
|
1174
1168
|
end
|
1175
1169
|
|
1176
1170
|
# Update an attribute value atomically. The best usecase for this
|
@@ -1181,9 +1175,9 @@ module Ohm
|
|
1181
1175
|
#
|
1182
1176
|
def set(att, val)
|
1183
1177
|
if val.to_s.empty?
|
1184
|
-
|
1178
|
+
key.call("HDEL", att)
|
1185
1179
|
else
|
1186
|
-
|
1180
|
+
key.call("HSET", att, val)
|
1187
1181
|
end
|
1188
1182
|
|
1189
1183
|
@attributes[att] = val
|
@@ -1224,7 +1218,7 @@ module Ohm
|
|
1224
1218
|
# ad.hits # => 3
|
1225
1219
|
#
|
1226
1220
|
def increment(att, count = 1)
|
1227
|
-
|
1221
|
+
key[:counters].call("HINCRBY", att, count)
|
1228
1222
|
end
|
1229
1223
|
|
1230
1224
|
# Decrements a counter atomically. Internally uses `HINCRBY`.
|
data/ohm.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "ohm"
|
3
|
-
s.version = "3.0
|
3
|
+
s.version = "3.1.0"
|
4
4
|
s.summary = %{Object-hash mapping library for Redis.}
|
5
5
|
s.description = %Q{Ohm is a library that allows to store an object in Redis, a persistent key-value database. It has very good performance.}
|
6
6
|
s.authors = ["Michel Martens", "Damian Janowski", "Cyril David"]
|
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.rubyforge_project = "ohm"
|
14
14
|
|
15
15
|
s.add_dependency "redic", "~> 1.5.0"
|
16
|
-
s.add_dependency "
|
16
|
+
s.add_dependency "nest", "~> 3"
|
17
17
|
s.add_dependency "stal"
|
18
18
|
|
19
19
|
s.add_development_dependency "cutest"
|
data/test/indices.rb
CHANGED
@@ -51,7 +51,7 @@ test "raise an error if the parameter supplied is not a hash" do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
test "avoid intersections with the all collection" do
|
54
|
-
assert_equal "User:indices:email:foo", User.find(:email => "foo").key
|
54
|
+
assert_equal "User:indices:email:foo", User.find(:email => "foo").key.to_s
|
55
55
|
end
|
56
56
|
|
57
57
|
test "allow multiple chained finds" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ohm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michel Martens
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-
|
13
|
+
date: 2016-12-03 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: redic
|
@@ -27,19 +27,19 @@ dependencies:
|
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
version: 1.5.0
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
|
-
name:
|
30
|
+
name: nest
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
|
-
- - "
|
33
|
+
- - "~>"
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: '
|
35
|
+
version: '3'
|
36
36
|
type: :runtime
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
|
-
- - "
|
40
|
+
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
42
|
+
version: '3'
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: stal
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|