ohm 1.4.0 → 2.0.0.alpha1

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.
data/test/uniques.rb CHANGED
@@ -64,7 +64,7 @@ test "removes the previous index when changing" do
64
64
  u.update(:email => "d@d.com")
65
65
 
66
66
  assert_equal nil, User.with(:email, "c@c.com")
67
- assert_equal nil, User.key[:uniques][:email].hget("c@c.com")
67
+ assert_equal nil, User.redis.call("HGET", User.key[:uniques][:email], "c@c.com")
68
68
  assert_equal u, User.with(:email, "d@d.com")
69
69
  end
70
70
 
@@ -72,7 +72,7 @@ test "removes the previous index when deleting" do |u|
72
72
  u.delete
73
73
 
74
74
  assert_equal nil, User.with(:email, "a@a.com")
75
- assert_equal nil, User.key[:uniques][:email].hget("a@a.com")
75
+ assert_equal nil, User.redis.call("HGET", User.key[:uniques][:email], "a@a.com")
76
76
  end
77
77
 
78
78
  test "unique virtual attribute" do
@@ -93,33 +93,3 @@ test "unique virtual attribute" do
93
93
  User.create(:email => "baz@yahoo.com")
94
94
  end
95
95
  end
96
-
97
- test "assert_unique" do |u|
98
- class User
99
- def assert_unique(att)
100
- result = self.class.with(att, send(att))
101
- assert((result.nil? || result.eql?(self)), [att, :not_unique])
102
- end
103
-
104
- def validate
105
- assert_unique :email
106
- end
107
- end
108
-
109
- # There's one user with email "a@a.com".
110
- user = User.new(:email => "a@a.com")
111
-
112
- # A new user with a conflicting attribute.
113
- assert_equal true, user.new?
114
- assert_equal false, user.valid?
115
- assert_equal [:not_unique], user.errors[:email]
116
-
117
- user.email = "b@b.com"
118
- user.save
119
- user.email = "a@a.com"
120
-
121
- # An existing user with a conflicting attribute.
122
- assert_equal false, user.new?
123
- assert_equal false, user.valid?
124
- assert_equal [:not_unique], user.errors[:email]
125
- end
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: 1.4.0
4
+ version: 2.0.0.alpha1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michel Martens
@@ -10,10 +10,10 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-01-22 00:00:00.000000000 Z
13
+ date: 2013-04-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: redis
16
+ name: redic
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
19
  - - '>='
@@ -27,47 +27,47 @@ dependencies:
27
27
  - !ruby/object:Gem::Version
28
28
  version: '0'
29
29
  - !ruby/object:Gem::Dependency
30
- name: nest
30
+ name: nido
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - ~>
33
+ - - '>='
34
34
  - !ruby/object:Gem::Version
35
- version: '1.0'
35
+ version: '0'
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: '1.0'
42
+ version: '0'
43
43
  - !ruby/object:Gem::Dependency
44
- name: scrivener
44
+ name: msgpack
45
45
  requirement: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - ~>
47
+ - - '>='
48
48
  - !ruby/object:Gem::Version
49
- version: 0.0.3
49
+ version: '0'
50
50
  type: :runtime
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
- - - ~>
54
+ - - '>='
55
55
  - !ruby/object:Gem::Version
56
- version: 0.0.3
56
+ version: '0'
57
57
  - !ruby/object:Gem::Dependency
58
58
  name: cutest
59
59
  requirement: !ruby/object:Gem::Requirement
60
60
  requirements:
61
- - - ~>
61
+ - - '>='
62
62
  - !ruby/object:Gem::Version
63
- version: '1.1'
63
+ version: '0'
64
64
  type: :development
65
65
  prerelease: false
66
66
  version_requirements: !ruby/object:Gem::Requirement
67
67
  requirements:
68
- - - ~>
68
+ - - '>='
69
69
  - !ruby/object:Gem::Version
70
- version: '1.1'
70
+ version: '0'
71
71
  description: Ohm is a library that allows to store an object in Redis, a persistent
72
72
  key-value database. It includes an extensible list of validations and has very good
73
73
  performance.
@@ -99,9 +99,9 @@ files:
99
99
  - lib/ohm.rb
100
100
  - lib/ohm/command.rb
101
101
  - lib/ohm/json.rb
102
- - lib/ohm/transaction.rb
102
+ - lib/ohm/lua/delete.lua
103
+ - lib/ohm/lua/save.lua
103
104
  - ohm.gemspec
104
- - test/1.8.6_test.rb
105
105
  - test/association.rb
106
106
  - test/command.rb
107
107
  - test/connection.rb
@@ -118,12 +118,9 @@ files:
118
118
  - test/json.rb
119
119
  - test/list.rb
120
120
  - test/model.rb
121
- - test/pipeline-performance.rb
122
121
  - test/test.conf
123
- - test/transactions.rb
124
122
  - test/uniques.rb
125
- - test/validations.rb
126
- homepage: http://soveran.github.com/ohm/
123
+ homepage: http://soveran.github.io/ohm/
127
124
  licenses:
128
125
  - MIT
129
126
  metadata: {}
@@ -138,12 +135,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
138
135
  version: '0'
139
136
  required_rubygems_version: !ruby/object:Gem::Requirement
140
137
  requirements:
141
- - - '>='
138
+ - - '>'
142
139
  - !ruby/object:Gem::Version
143
- version: '0'
140
+ version: 1.3.1
144
141
  requirements: []
145
142
  rubyforge_project: ohm
146
- rubygems_version: 2.0.14
143
+ rubygems_version: 2.0.3
147
144
  signing_key:
148
145
  specification_version: 4
149
146
  summary: Object-hash mapping library for Redis.
@@ -1,133 +0,0 @@
1
- module Ohm
2
-
3
- # Transactions in Ohm are designed to be composable and atomic. They use
4
- # Redis WATCH/MULTI/EXEC to perform the comands sequentially but in a single
5
- # step.
6
- #
7
- # @example
8
- #
9
- # redis = Ohm.redis
10
- #
11
- # t1 = Ohm::Transaction.new do |t|
12
- # s = nil
13
- #
14
- # t.watch("foo")
15
- #
16
- # t.read do
17
- # s = redis.type("foo")
18
- # end
19
- #
20
- # t.write do
21
- # redis.set("foo", s)
22
- # end
23
- # end
24
- #
25
- # t2 = Ohm::Transaction.new do |t|
26
- # t.watch("foo")
27
- #
28
- # t.write do
29
- # redis.set("foo", "bar")
30
- # end
31
- # end
32
- #
33
- # # Compose transactions by passing them to Ohm::Transaction.new.
34
- # t3 = Ohm::Transaction.new(t1, t2)
35
- # t3.commit(redis)
36
- #
37
- # # Compose transactions by appending them.
38
- # t1.append(t2)
39
- # t1.commit(redis)
40
- #
41
- # @see http://redis.io/topics/transactions Transactions in Redis.
42
- class Transaction
43
- class Store
44
- class EntryAlreadyExistsError < RuntimeError
45
- end
46
-
47
- class NoEntryError < RuntimeError
48
- end
49
-
50
- def initialize
51
- @dict = Hash.new
52
- end
53
-
54
- def [](key)
55
- raise NoEntryError unless @dict.member?(key)
56
-
57
- @dict[key]
58
- end
59
-
60
- def []=(key, value)
61
- raise EntryAlreadyExistsError if @dict.member?(key)
62
-
63
- @dict[key] = value
64
- end
65
- end
66
-
67
- attr :phase
68
-
69
- def initialize
70
- @phase = Hash.new { |h, k| h[k] = Array.new }
71
-
72
- yield self if block_given?
73
- end
74
-
75
- def append(t)
76
- t.phase.each do |key, values|
77
- phase[key].concat(values - phase[key])
78
- end
79
-
80
- self
81
- end
82
-
83
- def watch(*keys)
84
- phase[:watch].concat(keys - phase[:watch])
85
- end
86
-
87
- def read(&block)
88
- phase[:read] << block
89
- end
90
-
91
- def write(&block)
92
- phase[:write] << block
93
- end
94
-
95
- def before(&block)
96
- phase[:before] << block
97
- end
98
-
99
- def after(&block)
100
- phase[:after] << block
101
- end
102
-
103
- def commit(db)
104
- phase[:before].each(&:call)
105
-
106
- loop do
107
- store = Store.new
108
-
109
- if phase[:watch].any?
110
- db.watch(*phase[:watch])
111
- end
112
-
113
- run(phase[:read], store)
114
-
115
- break if db.multi do
116
- run(phase[:write], store)
117
- end
118
-
119
- store = nil
120
- end
121
-
122
- phase[:after].each(&:call)
123
- end
124
-
125
- def run(procs, store)
126
- procs.each { |p| p.call(store) }
127
- end
128
- end
129
-
130
- def self.transaction(&block)
131
- Transaction.new(&block)
132
- end
133
- end
data/test/1.8.6_test.rb DELETED
@@ -1,25 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
-
5
- prepare.clear
6
-
7
- test "String#lines should return the parts when separated with \\n" do
8
- assert ["a\n", "b\n", "c\n"] == "a\nb\nc\n".lines.to_a
9
- end
10
-
11
- test "String#lines return the parts when separated with \\r\\n" do
12
- assert ["a\r\n", "b\r\n", "c\r\n"] == "a\r\nb\r\nc\r\n".lines.to_a
13
- end
14
-
15
- test "String#lines accept a record separator" do
16
- assert ["ax", "bx", "cx"] == "axbxcx".lines("x").to_a
17
- end
18
-
19
- test "String#lines execute the passed block" do
20
- lines = ["a\r\n", "b\r\n", "c\r\n"]
21
-
22
- "a\r\nb\r\nc\r\n".lines do |line|
23
- assert lines.shift == line
24
- end
25
- end
@@ -1,67 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
-
5
- Ohm.flush
6
-
7
- class User < Ohm::Model
8
- attribute :fname
9
- attribute :lname
10
- attribute :bday
11
- attribute :gender
12
- attribute :city
13
- attribute :state
14
- attribute :country
15
- attribute :zip
16
- end
17
-
18
- create = lambda do |i|
19
- User.new(:fname => "John#{i}",
20
- :lname => "Doe#{i}",
21
- :bday => Time.now.to_s,
22
- :gender => "Male",
23
- :city => "Los Angeles",
24
- :state => "CA",
25
- :country => "US",
26
- :zip => "90210").save
27
- end
28
-
29
- 10.times(&create)
30
-
31
- require "benchmark"
32
-
33
- t1 = Benchmark.realtime do
34
- User.all.sort_by(:fname, :order => "DESC ALPHA").each do |user|
35
- end
36
- end
37
-
38
- t2 = Benchmark.realtime do
39
- ids = User.key[:all].smembers
40
-
41
- ids.each do |id|
42
- User[id]
43
- end
44
- end
45
-
46
- test "pipelined approach should be 1.5 at least times faster for 10 records" do
47
- assert(t2 / t1 >= 1.5)
48
- end
49
-
50
- 90.times(&create)
51
-
52
- t1 = Benchmark.realtime do
53
- User.all.sort_by(:fname, :order => "DESC ALPHA").each do |user|
54
- end
55
- end
56
-
57
- t2 = Benchmark.realtime do
58
- ids = User.key[:all].smembers
59
-
60
- ids.each do |id|
61
- User[id]
62
- end
63
- end
64
-
65
- test "the pipelined approach should be faster for 100 records" do
66
- assert(t2 > t1)
67
- end
data/test/transactions.rb DELETED
@@ -1,240 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
- require "ohm/transaction"
5
-
6
- prepare do
7
- Ohm.redis.del("foo")
8
- end
9
-
10
- setup do
11
- Ohm.redis
12
- end
13
-
14
- test "basic functionality" do |db|
15
- t = Ohm::Transaction.new
16
- x = nil
17
-
18
- t.watch("foo")
19
-
20
- t.read do
21
- x = db.get("foo")
22
- end
23
-
24
- t.write do
25
- db.set("foo", x.to_i + 2)
26
- end
27
-
28
- t.commit(db)
29
-
30
- assert_equal "2", db.get("foo")
31
- end
32
-
33
- test "new returns a transaction" do |db|
34
- t1 = Ohm::Transaction.new do |t|
35
- t.write do
36
- db.set("foo", "bar")
37
- end
38
- end
39
-
40
- t1.commit(db)
41
-
42
- assert_equal "bar", db.get("foo")
43
- end
44
-
45
- test "transaction local storage" do |db|
46
- t1 = Ohm::Transaction.new do |t|
47
- t.read do |s|
48
- s[:foo] = db.type("foo")
49
- end
50
-
51
- t.write do |s|
52
- db.set("foo", s[:foo].reverse)
53
- end
54
- end
55
-
56
- t1.commit(db)
57
-
58
- assert_equal "enon", db.get("foo")
59
- end
60
-
61
- test "composed transaction" do |db|
62
- t1 = Ohm::Transaction.new do |t|
63
- t.watch("foo")
64
-
65
- t.write do
66
- db.set("foo", "bar")
67
- end
68
- end
69
-
70
- t2 = Ohm::Transaction.new do |t|
71
- t.watch("foo")
72
-
73
- t.write do
74
- db.set("foo", "baz")
75
- end
76
- end
77
-
78
- t3 = Ohm::Transaction.new
79
- t3.append(t1)
80
- t3.append(t2)
81
- t3.commit(db)
82
-
83
- assert_equal "baz", db.get("foo")
84
-
85
- t4 = Ohm::Transaction.new
86
- t4.append(t2)
87
- t4.append(t1)
88
- t4.commit(db)
89
-
90
- assert_equal "bar", db.get("foo")
91
-
92
- t5 = Ohm::Transaction.new
93
- t5.append(t4)
94
- t5.commit(db)
95
-
96
- assert_equal "bar", db.get("foo")
97
-
98
- assert_equal ["foo"], t5.phase[:watch]
99
- assert_equal 2, t5.phase[:write].size
100
- end
101
-
102
- test "composing transactions with append" do |db|
103
- t1 = Ohm::Transaction.new do |t|
104
- t.write do
105
- db.set("foo", "bar")
106
- end
107
- end
108
-
109
- t2 = Ohm::Transaction.new do |t|
110
- t.write do
111
- db.set("foo", "baz")
112
- end
113
- end
114
-
115
- t1.append(t2)
116
- t1.commit(db)
117
-
118
- assert_equal "baz", db.get("foo")
119
-
120
- t2.append(t1)
121
- t2.commit(db)
122
-
123
- assert_equal "bar", db.get("foo")
124
- end
125
-
126
- test "appending or prepending is determined by when append is called" do |db|
127
- t1 = Ohm::Transaction.new do |t|
128
- t.write do
129
- db.set("foo", "bar")
130
- end
131
- end
132
-
133
- t2 = Ohm::Transaction.new do |t|
134
- t.append(t1)
135
-
136
- t.write do
137
- db.set("foo", "baz")
138
- end
139
- end
140
-
141
- t3 = Ohm::Transaction.new do |t|
142
- t.write do
143
- db.set("foo", "baz")
144
- end
145
-
146
- t.append(t1)
147
- end
148
-
149
- t2.commit(db)
150
-
151
- assert_equal "baz", db.get("foo")
152
-
153
- t3.commit(db)
154
-
155
- assert_equal "bar", db.get("foo")
156
- end
157
-
158
- test "storage in composed transactions" do |db|
159
- t1 = Ohm::Transaction.new do |t|
160
- t.read do |s|
161
- s[:foo] = db.type("foo")
162
- end
163
- end
164
-
165
- t2 = Ohm::Transaction.new do |t|
166
- t.write do |s|
167
- db.set("foo", s[:foo].reverse)
168
- end
169
- end
170
-
171
- t1.append(t2).commit(db)
172
-
173
- assert_equal "enon", db.get("foo")
174
- end
175
-
176
- test "reading an storage entries that doesn't exist raises" do |db|
177
- t1 = Ohm::Transaction.new do |t|
178
- t.read do |s|
179
- s[:foo]
180
- end
181
- end
182
-
183
- assert_raise Ohm::Transaction::Store::NoEntryError do
184
- t1.commit(db)
185
- end
186
- end
187
-
188
- test "storage entries can't be overriden" do |db|
189
- t1 = Ohm::Transaction.new do |t|
190
- t.read do |s|
191
- s[:foo] = db.type("foo")
192
- end
193
- end
194
-
195
- t2 = Ohm::Transaction.new do |t|
196
- t.read do |s|
197
- s[:foo] = db.exists("foo")
198
- end
199
- end
200
-
201
- assert_raise Ohm::Transaction::Store::EntryAlreadyExistsError do
202
- t1.append(t2).commit(db)
203
- end
204
- end
205
-
206
- test "banking transaction" do |db|
207
- class A < Ohm::Model
208
- attribute :amount
209
- end
210
-
211
- class B < Ohm::Model
212
- attribute :amount
213
- end
214
-
215
- def transfer(amount, account1, account2)
216
- Ohm.transaction do |t|
217
-
218
- t.watch(account1.key, account2.key)
219
-
220
- t.read do |s|
221
- s[:available] = account1.get(:amount).to_i
222
- end
223
-
224
- t.write do |s|
225
- if s[:available] >= amount
226
- account1.key.hincrby(:amount, - amount)
227
- account2.key.hincrby(:amount, amount)
228
- end
229
- end
230
- end
231
- end
232
-
233
- a = A.create :amount => 100
234
- b = B.create :amount => 0
235
-
236
- transfer(100, a, b).commit(db)
237
-
238
- assert_equal a.get(:amount), "0"
239
- assert_equal b.get(:amount), "100"
240
- end