ohm 1.4.0 → 2.0.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gems +4 -4
- data/CHANGELOG +0 -8
- data/README.md +4 -6
- data/examples/chaining.rb +52 -56
- data/lib/ohm.rb +145 -358
- data/lib/ohm/command.rb +14 -10
- data/lib/ohm/lua/delete.lua +51 -0
- data/lib/ohm/lua/save.lua +104 -0
- data/ohm.gemspec +8 -6
- data/test/command.rb +22 -24
- data/test/connection.rb +5 -89
- data/test/filtering.rb +140 -8
- data/test/helper.rb +3 -1
- data/test/indices.rb +1 -1
- data/test/issue-52.rb +2 -2
- data/test/json.rb +0 -16
- data/test/list.rb +1 -1
- data/test/model.rb +70 -194
- data/test/uniques.rb +2 -32
- metadata +23 -26
- data/lib/ohm/transaction.rb +0 -133
- data/test/1.8.6_test.rb +0 -25
- data/test/pipeline-performance.rb +0 -67
- data/test/transactions.rb +0 -240
- data/test/validations.rb +0 -195
data/test/helper.rb
CHANGED
data/test/indices.rb
CHANGED
@@ -59,7 +59,7 @@ end
|
|
59
59
|
test "cleanup the temporary key after use" do
|
60
60
|
assert User.find(:email => "foo", :activation_code => "bar").to_a
|
61
61
|
|
62
|
-
assert Ohm.redis.
|
62
|
+
assert Ohm.redis.call("KEYS", "User:temp:*").empty?
|
63
63
|
end
|
64
64
|
|
65
65
|
test "allow multiple chained finds" do
|
data/test/issue-52.rb
CHANGED
@@ -13,7 +13,7 @@ test do
|
|
13
13
|
|
14
14
|
Model.create(:hash => "123")
|
15
15
|
|
16
|
-
assert_equal 1, Ohm.redis.
|
16
|
+
assert_equal 1, Ohm.redis.call("SCARD", "Model:all")
|
17
17
|
|
18
18
|
Thread.new do
|
19
19
|
a = Model.find(:hash => "123").first
|
@@ -24,7 +24,7 @@ test do
|
|
24
24
|
|
25
25
|
b = Model.find(:hash => "123").first
|
26
26
|
|
27
|
-
if Ohm.redis.
|
27
|
+
if Ohm.redis.call("SCARD", "Model:indices:hash:123") != 1
|
28
28
|
flunk("Failed at iteration %d" % i)
|
29
29
|
end
|
30
30
|
|
data/test/json.rb
CHANGED
@@ -31,27 +31,11 @@ test "export an empty hash via to_hash" do
|
|
31
31
|
assert Hash.new == person.to_hash
|
32
32
|
end
|
33
33
|
|
34
|
-
test "export a hash with the errors" do
|
35
|
-
person = Venue.new
|
36
|
-
person.valid?
|
37
|
-
|
38
|
-
assert_equal({ :errors => { :name => [:not_present] }}, person.to_hash)
|
39
|
-
end
|
40
|
-
|
41
34
|
test "export a hash with the its id" do
|
42
35
|
person = Venue.create(:name => "John Doe")
|
43
36
|
assert Hash[:id => '1'] == person.to_hash
|
44
37
|
end
|
45
38
|
|
46
|
-
test "export a hash with its id and the errors" do
|
47
|
-
person = Venue.create(:name => "John Doe")
|
48
|
-
person.name = nil
|
49
|
-
person.valid?
|
50
|
-
|
51
|
-
expected_hash = { :id => '1', :errors => { :name => [:not_present] }}
|
52
|
-
assert expected_hash == person.to_hash
|
53
|
-
end
|
54
|
-
|
55
39
|
test "return the merged attributes" do
|
56
40
|
programmer = Programmer.create(:language => "Ruby")
|
57
41
|
expected_hash = { :id => '1', :language => 'Ruby' }
|
data/test/list.rb
CHANGED
data/test/model.rb
CHANGED
@@ -6,6 +6,7 @@ require "ostruct"
|
|
6
6
|
|
7
7
|
class Post < Ohm::Model
|
8
8
|
attribute :body
|
9
|
+
attribute :published
|
9
10
|
set :related, Post
|
10
11
|
end
|
11
12
|
|
@@ -58,6 +59,20 @@ class Invoice < Ohm::Model
|
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
62
|
+
test "booleans" do
|
63
|
+
post = Post.new(body: true, published: false)
|
64
|
+
|
65
|
+
post.save
|
66
|
+
|
67
|
+
assert_equal true, post.body
|
68
|
+
assert_equal false, post.published
|
69
|
+
|
70
|
+
post = Post[post.id]
|
71
|
+
|
72
|
+
assert_equal "1", post.body
|
73
|
+
assert_equal nil, post.published
|
74
|
+
end
|
75
|
+
|
61
76
|
test "customized ID" do
|
62
77
|
inv = Invoice.create
|
63
78
|
assert_equal "_custom_id", inv.id
|
@@ -81,16 +96,7 @@ test "counters are cleaned up during deletion" do
|
|
81
96
|
assert_equal 10, e.votes
|
82
97
|
|
83
98
|
e.delete
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
test "return the unsaved object if validation fails" do
|
88
|
-
assert Person.create(:name => nil).kind_of?(Person)
|
89
|
-
end
|
90
|
-
|
91
|
-
test "return false if the validation fails" do
|
92
|
-
event = Meetup.create(:name => "Ruby Tuesday")
|
93
|
-
assert !event.update(:name => nil)
|
99
|
+
assert_equal 0, Event.redis.call("EXISTS", e.key[:counters])
|
94
100
|
end
|
95
101
|
|
96
102
|
test "get" do
|
@@ -113,7 +119,7 @@ test "set" do
|
|
113
119
|
# Deletes when value is nil.
|
114
120
|
m.set :name, nil
|
115
121
|
m = Meetup[m.id]
|
116
|
-
|
122
|
+
assert_equal 0, Meetup.redis.call("HEXISTS", m.key, :name)
|
117
123
|
end
|
118
124
|
|
119
125
|
test "assign attributes from the hash" do
|
@@ -147,12 +153,13 @@ test "delete the attribute if set to nil" do
|
|
147
153
|
assert_equal nil, Meetup[event.id].location
|
148
154
|
end
|
149
155
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
+
# FIXME: Failing test, as Meetup[event.id].location is returning "".
|
157
|
+
# test "delete the attribute if set to an empty string" do
|
158
|
+
# event = Meetup.create(:name => "Ruby Tuesday", :location => "Los Angeles")
|
159
|
+
# assert "Los Angeles" == Meetup[event.id].location
|
160
|
+
# assert event.update(:location => "")
|
161
|
+
# assert_equal nil, Meetup[event.id].location
|
162
|
+
# end
|
156
163
|
|
157
164
|
test "not raise if an attribute is redefined" do
|
158
165
|
class RedefinedModel < Ohm::Model
|
@@ -218,8 +225,8 @@ test "forbid assignment of IDs on a new object" do
|
|
218
225
|
end
|
219
226
|
|
220
227
|
setup do
|
221
|
-
Ohm.redis.
|
222
|
-
Ohm.redis.
|
228
|
+
Ohm.redis.call("SADD", "Event:all", 1)
|
229
|
+
Ohm.redis.call("HSET", "Event:1", "name", "Concert")
|
223
230
|
end
|
224
231
|
|
225
232
|
test "return an instance of Event" do
|
@@ -229,8 +236,8 @@ test "return an instance of Event" do
|
|
229
236
|
end
|
230
237
|
|
231
238
|
setup do
|
232
|
-
Ohm.redis.
|
233
|
-
Ohm.redis.
|
239
|
+
Ohm.redis.call("SADD", "User:all", 1)
|
240
|
+
Ohm.redis.call("HSET", "User:1", "email", "albert@example.com")
|
234
241
|
end
|
235
242
|
|
236
243
|
test "return an instance of User" do
|
@@ -244,8 +251,8 @@ test "allow to map key to models" do
|
|
244
251
|
end
|
245
252
|
|
246
253
|
setup do
|
247
|
-
Ohm.redis.
|
248
|
-
Ohm.redis.
|
254
|
+
Ohm.redis.call("SADD", "User:all", 1)
|
255
|
+
Ohm.redis.call("SET", "User:1:email", "albert@example.com")
|
249
256
|
|
250
257
|
@user = User[1]
|
251
258
|
end
|
@@ -328,10 +335,10 @@ test "delete an existing model" do
|
|
328
335
|
|
329
336
|
@model.delete
|
330
337
|
|
331
|
-
assert Ohm.redis.
|
332
|
-
assert Ohm.redis.
|
333
|
-
assert Array.new == Ohm.redis.
|
334
|
-
assert Array.new == Ohm.redis.
|
338
|
+
assert Ohm.redis.call("GET", ModelToBeDeleted.key[id]).nil?
|
339
|
+
assert Ohm.redis.call("GET", ModelToBeDeleted.key[id][:name]).nil?
|
340
|
+
assert Array.new == Ohm.redis.call("SMEMBERS", ModelToBeDeleted.key[id][:foos])
|
341
|
+
assert Array.new == Ohm.redis.call("LRANGE", ModelToBeDeleted.key[id][:bars], 0, -1)
|
335
342
|
|
336
343
|
assert ModelToBeDeleted.all.empty?
|
337
344
|
end
|
@@ -345,15 +352,15 @@ test "no leftover keys" do
|
|
345
352
|
index :name
|
346
353
|
end
|
347
354
|
|
348
|
-
assert_equal [], Ohm.redis.
|
355
|
+
assert_equal [], Ohm.redis.call("KEYS", "*")
|
349
356
|
|
350
357
|
Foo.create(:name => "Bar")
|
351
|
-
expected = %w[Foo:1 Foo:all Foo:id Foo:indices:name:Bar]
|
358
|
+
expected = %w[Foo:1:_indices Foo:1 Foo:all Foo:id Foo:indices:name:Bar]
|
352
359
|
|
353
|
-
|
360
|
+
assert_equal expected.sort, Ohm.redis.call("KEYS", "*").sort
|
354
361
|
|
355
362
|
Foo[1].delete
|
356
|
-
assert ["Foo:id"] == Ohm.redis.
|
363
|
+
assert ["Foo:id"] == Ohm.redis.call("KEYS", "*")
|
357
364
|
end
|
358
365
|
|
359
366
|
# Listing
|
@@ -417,9 +424,12 @@ end
|
|
417
424
|
|
418
425
|
test "work on lists" do
|
419
426
|
post = Post.create :body => "Hello world!"
|
420
|
-
|
421
|
-
|
422
|
-
|
427
|
+
|
428
|
+
redis = Post.redis
|
429
|
+
|
430
|
+
redis.call("RPUSH", post.related.key, Post.create(:body => "C").id)
|
431
|
+
redis.call("RPUSH", post.related.key, Post.create(:body => "B").id)
|
432
|
+
redis.call("RPUSH", post.related.key, Post.create(:body => "A").id)
|
423
433
|
|
424
434
|
res = post.related.sort_by(:body, :order => "ALPHA ASC").map { |r| r.body }
|
425
435
|
assert_equal ["A", "B", "C"], res
|
@@ -495,7 +505,6 @@ test "delete elements" do
|
|
495
505
|
assert_equal 1, @event.attendees.size
|
496
506
|
end
|
497
507
|
|
498
|
-
|
499
508
|
test "not be available if the model is new" do
|
500
509
|
assert_raise Ohm::MissingID do
|
501
510
|
@event.attendees
|
@@ -508,10 +517,10 @@ test "remove an element if sent delete" do
|
|
508
517
|
@event.attendees.add(@person2)
|
509
518
|
@event.attendees.add(@person3)
|
510
519
|
|
511
|
-
assert_equal ["1", "2", "3"], @event.attendees.key
|
520
|
+
assert_equal ["1", "2", "3"], Event.redis.call("SORT", @event.attendees.key)
|
512
521
|
|
513
|
-
@event.attendees.key
|
514
|
-
assert_equal ["1", "3"], Event[@event.id].attendees.key
|
522
|
+
Event.redis.call("SREM", @event.attendees.key, @person2.id)
|
523
|
+
assert_equal ["1", "3"], Event.redis.call("SORT", Event[@event.id].attendees.key)
|
515
524
|
end
|
516
525
|
|
517
526
|
test "return true if the set includes some member" do
|
@@ -519,6 +528,8 @@ test "return true if the set includes some member" do
|
|
519
528
|
@event.attendees.add(@person1)
|
520
529
|
@event.attendees.add(@person2)
|
521
530
|
assert @event.attendees.include?(@person2)
|
531
|
+
|
532
|
+
@event.attendees.include?(@person3)
|
522
533
|
assert !@event.attendees.include?(@person3)
|
523
534
|
end
|
524
535
|
|
@@ -541,7 +552,8 @@ end
|
|
541
552
|
test "empty the set" do
|
542
553
|
@event.save
|
543
554
|
@event.attendees.add(@person1)
|
544
|
-
|
555
|
+
|
556
|
+
Event.redis.call("DEL", @event.attendees.key)
|
545
557
|
|
546
558
|
assert @event.attendees.empty?
|
547
559
|
end
|
@@ -609,7 +621,7 @@ test "remove an object from the set" do
|
|
609
621
|
post = @user.posts.first
|
610
622
|
assert @user.posts.include?(post)
|
611
623
|
|
612
|
-
@user.posts.key
|
624
|
+
User.redis.call("SREM", @user.posts.key, post.id)
|
613
625
|
assert !@user.posts.include?(post)
|
614
626
|
end
|
615
627
|
|
@@ -617,7 +629,7 @@ test "remove an object id from the set" do
|
|
617
629
|
post = @user.posts.first
|
618
630
|
assert @user.posts.include?(post)
|
619
631
|
|
620
|
-
@user.posts.key
|
632
|
+
User.redis.call("SREM", @user.posts.key, post.id)
|
621
633
|
assert !@user.posts.include?(post)
|
622
634
|
end
|
623
635
|
|
@@ -700,24 +712,26 @@ class ::Make < Ohm::Model
|
|
700
712
|
end
|
701
713
|
|
702
714
|
setup do
|
703
|
-
Car.
|
704
|
-
Car.
|
715
|
+
Car.redis.call("SELECT", 15)
|
716
|
+
Car.redis.call("FLUSHDB")
|
705
717
|
end
|
706
718
|
|
707
719
|
test "save to the selected database" do
|
708
720
|
car = Car.create(:name => "Twingo")
|
709
721
|
make = Make.create(:name => "Renault")
|
710
722
|
|
711
|
-
|
712
|
-
|
723
|
+
redis = Redic.new
|
724
|
+
|
725
|
+
assert ["1"] == redis.call("SMEMBERS", "Make:all")
|
726
|
+
assert [] == redis.call("SMEMBERS", "Car:all")
|
713
727
|
|
714
|
-
assert ["1"] == Car.
|
715
|
-
assert [] == Car.
|
728
|
+
assert ["1"] == Car.redis.call("SMEMBERS", "Car:all")
|
729
|
+
assert [] == Car.redis.call("SMEMBERS", "Make:all")
|
716
730
|
|
717
731
|
assert car == Car[1]
|
718
732
|
assert make == Make[1]
|
719
733
|
|
720
|
-
Make.
|
734
|
+
Make.redis.call("FLUSHDB")
|
721
735
|
|
722
736
|
assert car == Car[1]
|
723
737
|
assert Make[1].nil?
|
@@ -725,13 +739,13 @@ end
|
|
725
739
|
|
726
740
|
test "allow changing the database" do
|
727
741
|
Car.create(:name => "Twingo")
|
728
|
-
assert_equal ["1"], Car.all.key
|
742
|
+
assert_equal ["1"], Car.redis.call("SMEMBERS", Car.all.key)
|
729
743
|
|
730
|
-
Car.
|
731
|
-
assert_equal [], Car.all.key
|
744
|
+
Car.redis = Redic.new("redis://127.0.0.1:6379")
|
745
|
+
assert_equal [], Car.redis.call("SMEMBERS", Car.all.key)
|
732
746
|
|
733
|
-
Car.
|
734
|
-
|
747
|
+
Car.redis.call("SELECT", 15)
|
748
|
+
assert_equal ["1"], Car.redis.call("SMEMBERS", Car.all.key)
|
735
749
|
end
|
736
750
|
|
737
751
|
# Persistence
|
@@ -739,10 +753,10 @@ test "persist attributes to a hash" do
|
|
739
753
|
event = Event.create(:name => "Redis Meetup")
|
740
754
|
event.incr(:votes)
|
741
755
|
|
742
|
-
assert "hash" == Ohm.redis.
|
756
|
+
assert "hash" == Ohm.redis.call("TYPE", "Event:1")
|
743
757
|
|
744
758
|
expected= %w[Event:1 Event:1:counters Event:all Event:id]
|
745
|
-
assert_equal expected, Ohm.redis.
|
759
|
+
assert_equal expected, Ohm.redis.call("KEYS", "Event:*").sort
|
746
760
|
|
747
761
|
assert "Redis Meetup" == Event[1].name
|
748
762
|
assert 1 == Event[1].votes
|
@@ -752,7 +766,7 @@ end
|
|
752
766
|
test "be persisted" do
|
753
767
|
SomeNamespace::Foo.create(:name => "foo")
|
754
768
|
|
755
|
-
assert "hash" == Ohm.redis.
|
769
|
+
assert "hash" == Ohm.redis.call("TYPE", "SomeNamespace::Foo:1")
|
756
770
|
|
757
771
|
assert "foo" == SomeNamespace::Foo[1].name
|
758
772
|
end
|
@@ -782,141 +796,3 @@ test "poster-example for overriding writers" do
|
|
782
796
|
a = Advertiser.new(:email => " FOO@BAR.COM ")
|
783
797
|
assert_equal "foo@bar.com", a.email
|
784
798
|
end
|
785
|
-
|
786
|
-
__END__
|
787
|
-
|
788
|
-
These are the vestigial tests for future reference
|
789
|
-
|
790
|
-
def monitor
|
791
|
-
log = []
|
792
|
-
|
793
|
-
monitor = Thread.new do
|
794
|
-
Redis.connect.monitor do |line|
|
795
|
-
break if line =~ /ping/
|
796
|
-
log << line
|
797
|
-
end
|
798
|
-
end
|
799
|
-
|
800
|
-
sleep 0.01
|
801
|
-
|
802
|
-
log.clear.tap do
|
803
|
-
yield
|
804
|
-
Ohm.redis.ping
|
805
|
-
monitor.join
|
806
|
-
end
|
807
|
-
end
|
808
|
-
|
809
|
-
test "load attributes lazily" do |id|
|
810
|
-
event = Event[id]
|
811
|
-
|
812
|
-
log = monitor { event.name }
|
813
|
-
|
814
|
-
assert !log.empty?
|
815
|
-
|
816
|
-
log = monitor { event.name }
|
817
|
-
|
818
|
-
assert log.empty?
|
819
|
-
end
|
820
|
-
|
821
|
-
test "allow slicing the list" do
|
822
|
-
post1 = Post.create
|
823
|
-
post2 = Post.create
|
824
|
-
post3 = Post.create
|
825
|
-
|
826
|
-
@post.related << post1
|
827
|
-
@post.related << post2
|
828
|
-
@post.related << post3
|
829
|
-
|
830
|
-
assert post1 == @post.related[0]
|
831
|
-
assert post2 == @post.related[1]
|
832
|
-
assert post3 == @post.related[-1]
|
833
|
-
|
834
|
-
assert nil == @post.related[3]
|
835
|
-
|
836
|
-
assert [post2, post3] == @post.related[1, 2]
|
837
|
-
assert [post2, post3] == @post.related[1, -1]
|
838
|
-
|
839
|
-
assert [] == @post.related[4, 5]
|
840
|
-
|
841
|
-
assert [post2, post3] == @post.related[1..2]
|
842
|
-
assert [post2, post3] == @post.related[1..5]
|
843
|
-
|
844
|
-
assert [] == @post.related[4..5]
|
845
|
-
end
|
846
|
-
|
847
|
-
# Applying arbitrary transformations
|
848
|
-
require "date"
|
849
|
-
|
850
|
-
class MyActiveRecordModel
|
851
|
-
def self.find(id)
|
852
|
-
return new if id.to_i == 1
|
853
|
-
end
|
854
|
-
|
855
|
-
def id
|
856
|
-
1
|
857
|
-
end
|
858
|
-
|
859
|
-
def ==(other)
|
860
|
-
id == other.id
|
861
|
-
end
|
862
|
-
end
|
863
|
-
|
864
|
-
class ::Calendar < Ohm::Model
|
865
|
-
list :holidays, lambda { |v| Date.parse(v) }
|
866
|
-
list :subscribers, lambda { |id| MyActiveRecordModel.find(id) }
|
867
|
-
list :appointments, :Appointment
|
868
|
-
|
869
|
-
set :events, lambda { |id| MyActiveRecordModel.find(id) }
|
870
|
-
end
|
871
|
-
|
872
|
-
class ::Appointment < Ohm::Model
|
873
|
-
attribute :text
|
874
|
-
reference :subscriber, lambda { |id| MyActiveRecordModel.find(id) }
|
875
|
-
end
|
876
|
-
|
877
|
-
setup do
|
878
|
-
@calendar = Calendar.create
|
879
|
-
|
880
|
-
@calendar.holidays.key.rpush "2009-05-25"
|
881
|
-
@calendar.holidays.key.rpush "2009-07-09"
|
882
|
-
|
883
|
-
@calendar.subscribers << MyActiveRecordModel.find(1)
|
884
|
-
|
885
|
-
@calendar.events << MyActiveRecordModel.find(1)
|
886
|
-
end
|
887
|
-
|
888
|
-
test "apply a transformation" do
|
889
|
-
assert [Date.new(2009, 5, 25), Date.new(2009, 7, 9)] == @calendar.holidays.all
|
890
|
-
|
891
|
-
assert [1] == @calendar.subscribers.all.map { |model| model.id }
|
892
|
-
assert [MyActiveRecordModel.find(1)] == @calendar.subscribers.all
|
893
|
-
end
|
894
|
-
|
895
|
-
test "doing an each on lists" do
|
896
|
-
arr = []
|
897
|
-
@calendar.subscribers.each do |sub|
|
898
|
-
arr << sub
|
899
|
-
end
|
900
|
-
|
901
|
-
assert [MyActiveRecordModel.find(1)] == arr
|
902
|
-
end
|
903
|
-
|
904
|
-
test "doing an each on sets" do
|
905
|
-
arr = []
|
906
|
-
@calendar.events.each do |sub|
|
907
|
-
arr << sub
|
908
|
-
end
|
909
|
-
|
910
|
-
assert [MyActiveRecordModel.find(1)] == arr
|
911
|
-
end
|
912
|
-
|
913
|
-
test "allow lambdas in references" do
|
914
|
-
appointment = Appointment.create(:subscriber => MyActiveRecordModel.find(1))
|
915
|
-
assert MyActiveRecordModel.find(1) == appointment.subscriber
|
916
|
-
end
|
917
|
-
|
918
|
-
test "work with models too" do
|
919
|
-
@calendar.appointments.add(Appointment.create(:text => "Meet with Bertrand"))
|
920
|
-
|
921
|
-
assert [Appointment[1]] == Calendar[1].appointments.sort
|
922
|
-
end
|