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.
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