uorm 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,26 +1,17 @@
1
+ require 'redis'
2
+ require 'hiredis'
3
+
1
4
  module Uorm
2
5
  module Redis
3
6
  def self.included base
4
7
  base.instance_eval do
5
- field :id, type: Type::String
6
-
7
- def persistance
8
- @persistance ||= Persistance.new self
9
- end
10
-
11
- def collection
12
- persistance.collection
13
- end
8
+ field :id, type: :String
14
9
  end
15
10
 
16
11
  def initialize values = {}
17
- values[:id] ||= values['id'] || nil
12
+ values[:id] ||= values['id']
18
13
  super values
19
14
  end
20
-
21
- def persistance
22
- self.class.persistance
23
- end
24
15
  end
25
16
  end
26
17
  end
@@ -0,0 +1,8 @@
1
+ module Uorm
2
+ module Redis
3
+ class Adapter < Splash.new client: EM::Synchrony::ConnectionPool.new(2) do
4
+ Redis.new driver: :synchrony, db: 14
5
+ end
6
+ end
7
+ end
8
+ end
@@ -1,29 +1,19 @@
1
1
  module Uorm
2
2
  module Redis
3
- class Persistance
4
- attr_reader :collection, :model
5
-
6
- def initialize model
7
- @model = model
8
- @collection = DB.client
9
- end
10
-
11
- def new? object
12
- object.id ? false : true
13
- end
3
+ class Persistance < Struct.new :model, :client
14
4
 
15
5
  def all options = {}
16
- ids = collection.keys
6
+ ids = client.keys
17
7
  return [] if ids.empty?
18
8
  ids.map { |id| find id }
19
9
  end
20
10
 
21
11
  def find id
22
- collection.mapped_hmget id, *model.fields.map(&:name)
12
+ client.mapped_hmget id, *model.fields.map(&:name)
23
13
  end
24
14
 
25
15
  def create object
26
- object.id = SecureRandom.uuid
16
+ object.id = ::SecureRandom.uuid
27
17
  write object
28
18
  end
29
19
 
@@ -32,13 +22,13 @@ module Uorm
32
22
  end
33
23
 
34
24
  def delete object
35
- collection.del object.id
25
+ client.del object.id
36
26
  end
37
27
 
38
28
  private
39
29
 
40
30
  def write object
41
- collection.mapped_hmset object.id, object.attributes
31
+ client.mapped_hmset object.id, object.attributes
42
32
  end
43
33
  end
44
34
  end
@@ -0,0 +1,258 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ class AMongoModel
5
+ include Uorm::Model
6
+ include Uorm::Mongo
7
+
8
+ field :reference, type: :ObjectId
9
+ field :name, type: :String
10
+ field :count, type: :Integer
11
+ field :dollars, type: :Float
12
+ field :favorite, type: :Boolean
13
+ field :created, type: :Time
14
+ end
15
+
16
+ describe AMongoModel do
17
+
18
+ let!(:attributes) do
19
+ {
20
+ reference: '50995b8c15529d4676000001',
21
+ name: 'whatever',
22
+ count: 5.to_s,
23
+ dollars: 2.3.to_s,
24
+ favorite: true.to_s,
25
+ created: Time.utc(0).to_s
26
+ }
27
+ end
28
+ let(:collection) { EM::Mongo::Collection.new('uorm', 'test').tap(&:remove) }
29
+ let(:persistance) { AMongoModel.persistance = Uorm::Mongo::Persistance.new AMongoModel, collection }
30
+ let(:test_persistance) { AMongoModel.persistance = Uorm::Mongo::TestPerstistance.new }
31
+
32
+ before { test_persistance }
33
+
34
+ describe '.new' do
35
+ subject { AMongoModel.new attributes }
36
+
37
+ its(:reference) { should == BSON::ObjectId('50995b8c15529d4676000001') }
38
+ its(:name) { should == 'whatever' }
39
+ its(:count) { should == 5 }
40
+ its(:dollars) { should == 2.3 }
41
+ its(:favorite) { should be_true }
42
+ its(:created) { should == Time.utc(0) }
43
+
44
+ its(:as_json) do
45
+ should == {
46
+ reference: '50995b8c15529d4676000001',
47
+ name: "whatever",
48
+ count: 5,
49
+ dollars: 2.3,
50
+ favorite: true,
51
+ created: Time.utc(0).to_i,
52
+ id: nil
53
+ }
54
+ end
55
+ end
56
+
57
+ describe '.all' do
58
+ it 'returns a collection of all objects' do
59
+ EM.synchrony do
60
+ test_persistance.create AMongoModel.new name: 'findme'
61
+
62
+ AMongoModel.all.should be_collection_of AMongoModel
63
+
64
+ EM.stop
65
+ end
66
+ end
67
+
68
+ it 'returns a collection of objects with the query' do
69
+ EM.synchrony do
70
+ persistance.create AMongoModel.new name: 'findme'
71
+
72
+ AMongoModel.all(name: 'findme').should be_collection_of AMongoModel
73
+
74
+ EM.stop
75
+ end
76
+ end
77
+
78
+ it 'returns an empty array if the client is empty' do
79
+ EM.synchrony do
80
+ AMongoModel.all.should =~ []
81
+
82
+ EM.stop
83
+ end
84
+ end
85
+
86
+ it 'converts time strings into time objects' do
87
+ EM.synchrony do
88
+ persistance.create AMongoModel.new created: Time.parse('2001-01-02')
89
+
90
+ AMongoModel.all(created: { '$gt' => '2001-01-01' }).
91
+ should be_collection_of AMongoModel
92
+
93
+ AMongoModel.all(created: { '$lt' => Time.parse('2001-01-01')}).
94
+ should be_empty
95
+
96
+ EM.stop
97
+ end
98
+ end
99
+
100
+ it 'converts reference strings into BSON::ObjectId objects' do
101
+ EM.synchrony do
102
+ persistance.create AMongoModel.new reference: BSON::ObjectId('50995b8c15529d4676000001')
103
+
104
+ AMongoModel.all(reference: '50995b8c15529d4676000001').
105
+ should be_collection_of AMongoModel
106
+
107
+ EM.stop
108
+ end
109
+ end
110
+
111
+ it 'converts multiple query parameters' do
112
+ EM.synchrony do
113
+ persistance.create AMongoModel.new reference: BSON::ObjectId('50995b8c15529d4676000001'), created: Time.parse('2003-01-01')
114
+
115
+ AMongoModel.all(reference: '50995b8c15529d4676000001', created: '2003-01-01').
116
+ should be_collection_of AMongoModel
117
+
118
+ EM.stop
119
+ end
120
+ end
121
+
122
+ it 'runs async given a block' do
123
+ EM.synchrony do
124
+ persistance.create AMongoModel.new reference: BSON::ObjectId('50995b8c15529d4676000001')
125
+ fail_in 1
126
+
127
+ AMongoModel.all do |model|
128
+ model.should be_instance_of AMongoModel
129
+
130
+ EM.stop
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ describe '.find' do
137
+ it 'returns the first object with the given id' do
138
+ EM.synchrony do
139
+ AMongoModel.find(subject.save.id).should be_instance_of AMongoModel
140
+
141
+ EM.stop
142
+ end
143
+ end
144
+
145
+ it 'converts id BSON::ObjectId' do
146
+ EM.synchrony do
147
+ AMongoModel.find(subject.save.id.to_s).should be_instance_of AMongoModel
148
+
149
+ EM.stop
150
+ end
151
+ end
152
+
153
+ it 'runs async given a block' do
154
+ EM.synchrony do
155
+ id = persistance.create AMongoModel.new attributes
156
+ fail_in 1
157
+
158
+ AMongoModel.find(id) do |found|
159
+ found.should be_instance_of AMongoModel
160
+
161
+ EM.stop
162
+ end
163
+ end
164
+ end
165
+ end
166
+
167
+ describe '.create' do
168
+ it 'adds the object to the collection' do
169
+ EM.synchrony do
170
+ expect { subject.save }.to change { test_persistance.size }
171
+
172
+ EM.stop
173
+ end
174
+ end
175
+
176
+ it 'returns an object with the newly created attributes' do
177
+ EM.synchrony do
178
+ AMongoModel.create(attributes).should be_instance_of AMongoModel
179
+
180
+ EM.stop
181
+ end
182
+ end
183
+
184
+ it 'runs async given a block' do
185
+ EM.synchrony do
186
+ persistance
187
+ fail_in 1
188
+
189
+ AMongoModel.create(attributes) do |model|
190
+ model.should be_instance_of AMongoModel
191
+
192
+ EM.stop
193
+ end
194
+
195
+ end
196
+ end
197
+ end
198
+
199
+ describe '#save' do
200
+ subject { AMongoModel.new attributes }
201
+
202
+ it 'creates the object if it does not have an id' do
203
+ EM.synchrony do
204
+ persistance
205
+
206
+ expect { subject.save }.to change { subject.id }
207
+ EM.stop
208
+ end
209
+ end
210
+
211
+ it 'maintains the same id of the record if it exists' do
212
+ EM.synchrony do
213
+ persistance
214
+ subject.save
215
+
216
+ expect { subject.save }.to_not change { subject.id }
217
+ EM.stop
218
+ end
219
+ end
220
+ end
221
+
222
+ describe '#update' do
223
+ subject { AMongoModel.new attributes }
224
+
225
+ it 'updates the object with the given attributes' do
226
+ EM.synchrony do
227
+ persistance
228
+
229
+ expect { subject.update name: 'new' }.to change { subject.name }
230
+
231
+ EM.stop
232
+ end
233
+ end
234
+
235
+ it 'updates the collection with the given attributes' do
236
+ EM.synchrony do
237
+ persistance
238
+
239
+ expect { subject.update name: 'another' }.to_not change { persistance.count }
240
+
241
+ EM.stop
242
+ end
243
+ end
244
+ end
245
+
246
+ describe '#delete' do
247
+ subject { AMongoModel.new attributes }
248
+ it 'removes the object from the collection' do
249
+ EM.synchrony do
250
+ test_persistance.create subject
251
+
252
+ expect { subject.delete }.to change { test_persistance.size }
253
+
254
+ EM.stop
255
+ end
256
+ end
257
+ end
258
+ end
@@ -0,0 +1,161 @@
1
+ require 'spec_helper'
2
+
3
+ class ARedisModel
4
+ include Uorm::Model
5
+ include Uorm::Redis
6
+
7
+ field :reference, type: :String
8
+ field :name, type: :String
9
+ field :count, type: :Integer
10
+ field :dollars, type: :Float
11
+ field :favorite, type: :Boolean
12
+ field :created, type: :Time
13
+ end
14
+
15
+ describe ARedisModel do
16
+
17
+ let(:attributes) do
18
+ {
19
+ reference: '2d931510-d99f-494a-8c67-87feb05e1594',
20
+ name: 'whatever',
21
+ count: 5.to_s,
22
+ dollars: 2.3.to_s,
23
+ favorite: true.to_s,
24
+ created: Time.utc(0).to_s
25
+ }
26
+ end
27
+
28
+ let(:client) { Redis.new(db: 15, driver: :synchrony).tap(&:flushdb) }
29
+ let(:persistance) { AMongoModel.persistance = Uorm::Redis::Persistance.new ARedisModel, client }
30
+ let(:test_persistance) { AMongoModel.persistance = Uorm::Mongo::TestPerstistance.new }
31
+
32
+ before { test_persistance }
33
+
34
+ describe '.new' do
35
+ subject { ARedisModel.new attributes }
36
+
37
+ its(:reference) { should == '2d931510-d99f-494a-8c67-87feb05e1594' }
38
+ its(:name) { should == 'whatever' }
39
+ its(:count) { should == 5 }
40
+ its(:dollars) { should == 2.3 }
41
+ its(:favorite) { should be_true }
42
+ its(:created) { should == Time.utc(0) }
43
+
44
+ its(:as_json) do
45
+ should == {
46
+ reference: '2d931510-d99f-494a-8c67-87feb05e1594',
47
+ name: "whatever",
48
+ count: 5,
49
+ dollars: 2.3,
50
+ favorite: true,
51
+ created: Time.utc(0).to_i,
52
+ id: nil
53
+ }
54
+ end
55
+ end
56
+
57
+ describe '.all' do
58
+ it 'returns a client of all objects' do
59
+ EM.synchrony do
60
+ test_persistance.create ARedisModel.new attributes
61
+ ARedisModel.all.should be_collection_of ARedisModel
62
+
63
+ EM.stop
64
+ end
65
+ end
66
+
67
+ it 'returns an empty array if the client is empty' do
68
+ EM.synchrony do
69
+ ARedisModel.all.should =~ []
70
+
71
+ EM.stop
72
+ end
73
+ end
74
+ end
75
+
76
+ describe '.find' do
77
+ it 'returns the first object with the given id' do
78
+ EM.synchrony do
79
+ id = persistance.create ARedisModel.new attributes
80
+ ARedisModel.find(id).should be_instance_of ARedisModel
81
+
82
+ EM.stop
83
+ end
84
+ end
85
+ end
86
+
87
+ describe '.create' do
88
+ it 'adds the object to the client' do
89
+ EM.synchrony do
90
+
91
+ expect { ARedisModel.create attributes }.to change { test_persistance.size }
92
+
93
+ EM.stop
94
+ end
95
+ end
96
+
97
+ it 'returns an object with the newly created attributes' do
98
+ EM.synchrony do
99
+ ARedisModel.create(attributes).should be_instance_of ARedisModel
100
+
101
+ EM.stop
102
+ end
103
+ end
104
+ end
105
+
106
+ describe '#save' do
107
+ it 'creates the object if it does not have an id' do
108
+ EM.synchrony do
109
+ persistance
110
+
111
+ model = ARedisModel.new attributes
112
+ expect { model.save }.to change { model.id }
113
+
114
+ EM.stop
115
+ end
116
+ end
117
+
118
+ it 'updates the object if it does exist' do
119
+ EM.synchrony do
120
+ persistance
121
+
122
+ model = ARedisModel.create attributes
123
+ expect { model.save }.to_not change { model.id }
124
+
125
+ EM.stop
126
+ end
127
+ end
128
+ end
129
+
130
+ describe '#update' do
131
+ it 'updates the object with the given attributes' do
132
+ EM.synchrony do
133
+ model = ARedisModel.create attributes
134
+ expect { model.update name: 'new' }.to change { model.name }
135
+
136
+ EM.stop
137
+ end
138
+ end
139
+
140
+ it 'updates the client with the given attributes' do
141
+ EM.synchrony do
142
+ model = ARedisModel.create attributes
143
+ expect { model.update name: 'another' }.
144
+ to change { ARedisModel.find(model.id).name }
145
+
146
+ EM.stop
147
+ end
148
+ end
149
+ end
150
+
151
+ describe '#delete' do
152
+ it 'removes the object from the client' do
153
+ EM.synchrony do
154
+ model = ARedisModel.create attributes
155
+ expect { model.delete }.to change { test_persistance.size }
156
+
157
+ EM.stop
158
+ end
159
+ end
160
+ end
161
+ end