redis_orm 0.3 → 0.4
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/CHANGELOG +8 -0
- data/Manifest +1 -0
- data/README.md +59 -31
- data/Rakefile +4 -3
- data/lib/redis_orm/associations/has_one.rb +13 -11
- data/lib/redis_orm/redis_orm.rb +85 -41
- data/redis_orm.gemspec +9 -9
- data/test/associations_test.rb +22 -19
- data/test/basic_functionality_test.rb +13 -23
- data/test/callbacks_test.rb +1 -22
- data/test/changes_array_test.rb +7 -23
- data/test/dynamic_finders_test.rb +1 -22
- data/test/exceptions_test.rb +8 -26
- data/test/has_one_has_many_test.rb +1 -22
- data/test/indices_test.rb +26 -21
- data/test/options_test.rb +29 -25
- data/test/polymorphic_test.rb +1 -22
- data/test/test_helper.rb +25 -0
- data/test/validations_test.rb +1 -22
- metadata +13 -13
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
v0.4 [16-06-2011]
|
2
|
+
* added :conditions key to the options hash in #find/#all methods
|
3
|
+
* added #{property_name}_changed? instance method
|
4
|
+
* fixed self-reference link for has_one association/added test for it
|
5
|
+
* added :case_insensitive option to index declaration
|
6
|
+
* fixed bug with no output when installed rspec > 2.6
|
7
|
+
* added more tests and refactored old ones, updated documentation
|
8
|
+
|
1
9
|
v0.3 [06-06-2011]
|
2
10
|
* fixed #find functionality both for model itself and for has_many proxy
|
3
11
|
* made sure ORM correctly resets associations when nil/[] provided
|
data/Manifest
CHANGED
data/README.md
CHANGED
@@ -40,7 +40,7 @@ class User < RedisOrm::Base
|
|
40
40
|
end
|
41
41
|
```
|
42
42
|
|
43
|
-
|
43
|
+
Supported property types:
|
44
44
|
|
45
45
|
* **Integer**
|
46
46
|
|
@@ -49,12 +49,11 @@ Following property types are supported:
|
|
49
49
|
* **Float**
|
50
50
|
|
51
51
|
* **RedisOrm::Boolean**
|
52
|
-
there is no Boolean class in Ruby so it's a special class to
|
52
|
+
there is no Boolean class in Ruby so it's a special class to store TrueClass or FalseClass objects
|
53
53
|
|
54
54
|
* **Time**
|
55
55
|
|
56
|
-
|
57
|
-
Property definition supports following options:
|
56
|
+
Following options are available in property declaration:
|
58
57
|
|
59
58
|
* **:default**
|
60
59
|
|
@@ -62,7 +61,7 @@ Property definition supports following options:
|
|
62
61
|
|
63
62
|
## Searching records by the value
|
64
63
|
|
65
|
-
Usually it's done via
|
64
|
+
Usually it's done via declaring an index and using dynamic finders later. For example:
|
66
65
|
|
67
66
|
```ruby
|
68
67
|
class User < RedisOrm::Base
|
@@ -76,16 +75,9 @@ User.find_by_name "germaninthetown" # => found 1 record
|
|
76
75
|
User.find_all_by_name "germaninthetown" # => array with 1 record
|
77
76
|
```
|
78
77
|
|
79
|
-
Dynamic finders work mostly the way they
|
78
|
+
Dynamic finders work mostly the way they do in ActiveRecord. The only difference is if you didn't specified index or compound index on the attributes you are searching on the exception will be raised.
|
80
79
|
|
81
|
-
## Options for #find/#all
|
82
|
-
|
83
|
-
For example we associate 2 photos with the album
|
84
|
-
|
85
|
-
```ruby
|
86
|
-
@album.photos << @photo2
|
87
|
-
@album.photos << @photo1
|
88
|
-
```
|
80
|
+
## Options for #find/#all
|
89
81
|
|
90
82
|
To extract all or part of the associated records you could use 3 options for now (#find is an alias for #all in has_many proxy):
|
91
83
|
|
@@ -95,21 +87,33 @@ To extract all or part of the associated records you could use 3 options for now
|
|
95
87
|
|
96
88
|
* :order
|
97
89
|
|
98
|
-
Either :desc or :asc (default), since records are stored with Time.now.to_f scores,
|
90
|
+
Either :desc or :asc (default), since records are stored with Time.now.to_f scores, by default they could be fetched only in that (or reversed) order. To store them in different order you should *zadd* record's id to some other sorted list manually.
|
91
|
+
|
92
|
+
* :conditions
|
93
|
+
|
94
|
+
Hash where keys must be equal to some property name (there must be index for this property too).
|
99
95
|
|
100
96
|
```ruby
|
97
|
+
# for example we associate 2 photos with the album
|
98
|
+
@album.photos << @photo2
|
99
|
+
@album.photos << @photo1
|
100
|
+
|
101
101
|
@album.photos.all(:limit => 0, :offset => 0).should == []
|
102
102
|
@album.photos.all(:limit => 1, :offset => 0).size.should == 1
|
103
103
|
@album.photos.all(:limit => 2, :offset => 0)
|
104
|
-
@album.photos.find(:order => "asc")
|
104
|
+
@album.photos.find(:all, :order => "asc")
|
105
105
|
|
106
|
+
Photo.find(:first, :order => "desc")
|
106
107
|
Photo.all(:order => "asc", :limit => 5)
|
107
108
|
Photo.all(:order => "desc", :limit => 10, :offset => 50)
|
109
|
+
|
110
|
+
Photo.find(:all, :conditions => {:image => "facepalm.jpg"}) # => [...]
|
111
|
+
Photo.find(:first, :conditions => {:image => "boobs.png"}) # => @photo1
|
108
112
|
```
|
109
113
|
|
110
114
|
## Indices
|
111
115
|
|
112
|
-
Indices are used in a different way then they are used in relational databases.
|
116
|
+
Indices are used in a different way then they are used in relational databases. They are used to find record by they value rather then to quick access them.
|
113
117
|
|
114
118
|
You could add index to any attribute of the model (it also could be compound):
|
115
119
|
|
@@ -123,7 +127,7 @@ class User < RedisOrm::Base
|
|
123
127
|
end
|
124
128
|
```
|
125
129
|
|
126
|
-
With index defined for the property (or
|
130
|
+
With index defined for the property (or properties) the id of the saved object is stored in the special sorted set, so it could be found later by the value. For example with defined User model from the above code:
|
127
131
|
|
128
132
|
```ruby
|
129
133
|
user = User.new :first_name => "Robert", :last_name => "Pirsig"
|
@@ -141,6 +145,12 @@ Index definition supports following options:
|
|
141
145
|
|
142
146
|
* **:unique** Boolean default: false
|
143
147
|
|
148
|
+
If true is specified then value is stored in ordinary key-value structure with index as the key, otherwise the values are added to sorted set with index as the key.
|
149
|
+
|
150
|
+
* **:case_insensitive** Boolean default: false
|
151
|
+
|
152
|
+
If true is specified then property values are saved downcased (and then are transformed to downcase form when searching with dynamic finders). Works for compound indices too.
|
153
|
+
|
144
154
|
## Associations
|
145
155
|
|
146
156
|
RedisOrm provides 3 association types:
|
@@ -236,7 +246,7 @@ cat3.articles # => [article]
|
|
236
246
|
|
237
247
|
Backlinks are automatically created.
|
238
248
|
|
239
|
-
###
|
249
|
+
### Self-referencing association
|
240
250
|
|
241
251
|
```ruby
|
242
252
|
class User < RedisOrm::Base
|
@@ -256,7 +266,7 @@ friend1.friends # => []
|
|
256
266
|
friend2.friends # => []
|
257
267
|
```
|
258
268
|
|
259
|
-
As an exception if *:as* option for the association is provided the backlinks
|
269
|
+
As an exception if *:as* option for the association is provided the backlinks aren't created.
|
260
270
|
|
261
271
|
### Polymorphic associations
|
262
272
|
|
@@ -297,7 +307,7 @@ All associations supports following options:
|
|
297
307
|
|
298
308
|
* *:as*
|
299
309
|
|
300
|
-
Symbol could be accessed by provided name
|
310
|
+
Symbol Association could be accessed by provided name
|
301
311
|
|
302
312
|
* *:dependent*
|
303
313
|
|
@@ -380,13 +390,17 @@ When saving object standard ActiveModel's #valid? method is invoked at first. Th
|
|
380
390
|
|
381
391
|
The object's id is stored in "model_name:ids" sorted set with Time.now.to_f as a score. So records are ordered by created_at time by default.
|
382
392
|
|
393
|
+
## Dirty
|
394
|
+
|
395
|
+
Redis_orm also provides dirty methods to check whether the property has changed and what are these changes. To check it you could use 2 methods: #property_changed? (returns true or false) and #property_changes (returns array with changed values).
|
396
|
+
|
383
397
|
## Tests
|
384
398
|
|
385
|
-
Though I a fan of the Test::Unit all tests are based on RSpec. And the only reason I did it
|
399
|
+
Though I'm a big fan of the Test::Unit all tests are based on RSpec. And the only reason I did it are *before(:all)* and *after(:all)* hooks. So I could spawn/kill redis-server's process (from test_helper.rb):
|
386
400
|
|
387
401
|
```ruby
|
388
|
-
|
389
|
-
before(:all) do
|
402
|
+
RSpec.configure do |config|
|
403
|
+
config.before(:all) do
|
390
404
|
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
|
391
405
|
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
|
392
406
|
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
@@ -394,24 +408,38 @@ describe "check callbacks" do
|
|
394
408
|
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
395
409
|
end
|
396
410
|
|
397
|
-
before(:each) do
|
411
|
+
config.before(:each) do
|
398
412
|
$redis.flushall if $redis
|
399
413
|
end
|
400
414
|
|
401
|
-
after(:each) do
|
415
|
+
config.after(:each) do
|
402
416
|
$redis.flushall if $redis
|
403
417
|
end
|
404
418
|
|
405
|
-
after(:all) do
|
419
|
+
config.after(:all) do
|
406
420
|
Process.kill 9, $redis_pid.to_i if $redis_pid
|
407
421
|
end
|
408
|
-
|
409
|
-
# it "should ..." do
|
410
|
-
# ...
|
411
|
-
# end
|
412
422
|
end
|
413
423
|
```
|
414
424
|
|
415
425
|
To run all tests just invoke *rake test*
|
416
426
|
|
417
427
|
Copyright © 2011 Dmitrii Samoilov, released under the MIT license
|
428
|
+
|
429
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
430
|
+
of this software and associated documentation files (the "Software"), to deal
|
431
|
+
in the Software without restriction, including without limitation the rights
|
432
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
433
|
+
copies of the Software, and to permit persons to whom the Software is
|
434
|
+
furnished to do so, subject to the following conditions:
|
435
|
+
|
436
|
+
The above copyright notice and this permission notice shall be included in
|
437
|
+
all copies or substantial portions of the Software.
|
438
|
+
|
439
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
440
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
441
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
442
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
443
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
444
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
445
|
+
THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
require 'psych'
|
1
2
|
require 'rubygems'
|
2
3
|
require 'rake'
|
3
|
-
|
4
|
+
#=begin
|
4
5
|
require 'echoe'
|
5
6
|
|
6
|
-
Echoe.new('redis_orm', '0.
|
7
|
+
Echoe.new('redis_orm', '0.4') do |p|
|
7
8
|
p.description = "ORM for Redis advanced key-value storage"
|
8
9
|
p.url = "https://github.com/german/redis_orm"
|
9
10
|
p.author = "Dmitrii Samoilov"
|
@@ -11,7 +12,7 @@ Echoe.new('redis_orm', '0.3') do |p|
|
|
11
12
|
p.dependencies = ["activesupport >=3.0.0", "activemodel >=3.0.0", "redis >=2.2.0"]
|
12
13
|
p.development_dependencies = ["rspec >=2.5.0"]
|
13
14
|
end
|
14
|
-
|
15
|
+
#=end
|
15
16
|
|
16
17
|
#require 'rake/testtask'
|
17
18
|
#$LOAD_PATH << File.join(File.dirname(__FILE__), 'lib')
|
@@ -33,19 +33,21 @@ module RedisOrm
|
|
33
33
|
raise TypeMismatchError
|
34
34
|
end
|
35
35
|
|
36
|
-
if
|
37
|
-
|
38
|
-
$redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", id) if old_assoc
|
39
|
-
else
|
40
|
-
# check whether *assoc_with_record* object has *belongs_to* declaration and TODO it states *self.model_name* and there is no record yet from the *assoc_with_record*'s side (in order not to provoke recursion)
|
41
|
-
if class_associations[assoc_with_record.model_name].detect{|h| [:belongs_to, :has_one].include?(h[:type]) && h[:foreign_model] == model_name.to_sym} && assoc_with_record.send(model_name.to_sym).nil?
|
42
|
-
# old association is being rewritten here automatically so we don't have to worry about it
|
43
|
-
assoc_with_record.send("#{model_name}=", self)
|
44
|
-
elsif class_associations[assoc_with_record.model_name].detect{|h| :has_many == h[:type] && h[:foreign_models] == model_name.to_s.pluralize.to_sym} && !$redis.zrank("#{assoc_with_record.model_name}:#{assoc_with_record.id}:#{model_name.pluralize}", self.id)
|
36
|
+
if !options[:as]
|
37
|
+
if assoc_with_record.nil?
|
45
38
|
# remove old assoc
|
46
39
|
$redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", id) if old_assoc
|
47
|
-
|
48
|
-
assoc_with_record.
|
40
|
+
else
|
41
|
+
# check whether *assoc_with_record* object has *belongs_to* declaration and TODO it states *self.model_name* and there is no record yet from the *assoc_with_record*'s side (in order not to provoke recursion)
|
42
|
+
if class_associations[assoc_with_record.model_name].detect{|h| [:belongs_to, :has_one].include?(h[:type]) && h[:foreign_model] == model_name.to_sym} && assoc_with_record.send(model_name.to_sym).nil?
|
43
|
+
# old association is being rewritten here automatically so we don't have to worry about it
|
44
|
+
assoc_with_record.send("#{model_name}=", self)
|
45
|
+
elsif class_associations[assoc_with_record.model_name].detect{|h| :has_many == h[:type] && h[:foreign_models] == model_name.to_s.pluralize.to_sym} && !$redis.zrank("#{assoc_with_record.model_name}:#{assoc_with_record.id}:#{model_name.pluralize}", self.id)
|
46
|
+
# remove old assoc
|
47
|
+
$redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", id) if old_assoc
|
48
|
+
# create/add new ones
|
49
|
+
assoc_with_record.send(model_name.pluralize.to_sym).send(:"<<", self)
|
50
|
+
end
|
49
51
|
end
|
50
52
|
end
|
51
53
|
end
|
data/lib/redis_orm/redis_orm.rb
CHANGED
@@ -96,6 +96,10 @@ module RedisOrm
|
|
96
96
|
send(:define_method, "#{property_name}_changes".to_sym) do
|
97
97
|
instance_variable_get(:"@#{property_name}_changes")
|
98
98
|
end
|
99
|
+
|
100
|
+
send(:define_method, "#{property_name}_changed?".to_sym) do
|
101
|
+
instance_variable_get(:"@#{property_name}_changes").size > 1
|
102
|
+
end
|
99
103
|
end
|
100
104
|
|
101
105
|
def timestamps
|
@@ -124,17 +128,61 @@ module RedisOrm
|
|
124
128
|
id.empty? ? nil : find(id[0])
|
125
129
|
end
|
126
130
|
|
131
|
+
def find_index(properties)
|
132
|
+
@@indices[model_name].detect do |models_index|
|
133
|
+
if models_index[:name].is_a?(Array) && models_index[:name].size == properties.size
|
134
|
+
models_index[:name] == properties.map{|p| p.to_sym}
|
135
|
+
elsif !models_index[:name].is_a?(Array) && properties.size == 1
|
136
|
+
models_index[:name] == properties[0].to_sym
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def construct_prepared_index(index, properties_hash)
|
142
|
+
prepared_index = model_name.to_s
|
143
|
+
|
144
|
+
properties_hash.each do |key, value|
|
145
|
+
# raise if User.find_by_firstname_and_castname => there's no *castname* in User's properties
|
146
|
+
raise ArgumentsMismatch if !@@properties[model_name].detect{|p| p[:name] == key.to_sym}
|
147
|
+
prepared_index += ":#{key}:#{value}"
|
148
|
+
end
|
149
|
+
|
150
|
+
prepared_index.downcase! if index[:options][:case_insensitive]
|
151
|
+
|
152
|
+
prepared_index
|
153
|
+
end
|
154
|
+
|
127
155
|
def all(options = {})
|
128
156
|
limit = if options[:limit] && options[:offset]
|
129
157
|
[options[:offset].to_i, options[:limit].to_i]
|
130
158
|
elsif options[:limit]
|
131
159
|
[0, options[:limit].to_i]
|
132
160
|
end
|
133
|
-
|
134
|
-
if options[:
|
135
|
-
|
136
|
-
|
137
|
-
|
161
|
+
|
162
|
+
if options[:conditions] && options[:conditions].is_a?(Hash)
|
163
|
+
properties = options[:conditions].collect{|key, value| key}
|
164
|
+
index = find_index(properties)
|
165
|
+
|
166
|
+
raise NotIndexFound if !index
|
167
|
+
|
168
|
+
prepared_index = construct_prepared_index(index, options[:conditions])
|
169
|
+
|
170
|
+
records = []
|
171
|
+
|
172
|
+
if index[:options][:unique]
|
173
|
+
id = $redis.get prepared_index
|
174
|
+
records << model_name.to_s.camelize.constantize.find(id)
|
175
|
+
else
|
176
|
+
ids = $redis.zrangebyscore(prepared_index, 0, Time.now.to_f)
|
177
|
+
records += model_name.to_s.camelize.constantize.find(ids)
|
178
|
+
end
|
179
|
+
records
|
180
|
+
else
|
181
|
+
if options[:order].to_s == 'desc'
|
182
|
+
$redis.zrevrangebyscore("#{model_name}:ids", Time.now.to_f, 0, :limit => limit).compact.collect{|id| find(id)}
|
183
|
+
else
|
184
|
+
$redis.zrangebyscore("#{model_name}:ids", 0, Time.now.to_f, :limit => limit).compact.collect{|id| find(id)}
|
185
|
+
end
|
138
186
|
end
|
139
187
|
end
|
140
188
|
|
@@ -199,34 +247,27 @@ module RedisOrm
|
|
199
247
|
obj = new(options, nil, false)
|
200
248
|
obj.save
|
201
249
|
obj
|
202
|
-
end
|
203
|
-
|
250
|
+
end
|
251
|
+
|
204
252
|
# dynamic finders
|
205
253
|
def method_missing(method_name, *args, &block)
|
206
254
|
if method_name =~ /^find_(all_)?by_(\w*)/
|
207
|
-
|
255
|
+
|
208
256
|
index = if $2
|
209
257
|
properties = $2.split('_and_')
|
210
258
|
raise ArgumentsMismatch if properties.size != args.size
|
211
|
-
|
212
|
-
properties.each_with_index do |prop, i|
|
213
|
-
|
214
|
-
raise ArgumentsMismatch if !@@properties[model_name].detect{|p| p[:name] == prop.to_sym}
|
215
|
-
prepared_index += ":#{prop}:#{args[i].to_s}"
|
216
|
-
end
|
217
|
-
|
218
|
-
@@indices[model_name].detect do |models_index|
|
219
|
-
if models_index[:name].is_a?(Array) && models_index[:name].size == properties.size
|
220
|
-
models_index[:name] == properties.map{|p| p.to_sym}
|
221
|
-
elsif !models_index[:name].is_a?(Array) && properties.size == 1
|
222
|
-
models_index[:name] == properties[0].to_sym
|
223
|
-
end
|
259
|
+
properties_hash = {}
|
260
|
+
properties.each_with_index do |prop, i|
|
261
|
+
properties_hash.merge!({prop.to_sym => args[i]})
|
224
262
|
end
|
263
|
+
find_index(properties)
|
225
264
|
end
|
226
265
|
|
227
266
|
raise NotIndexFound if !index
|
267
|
+
|
268
|
+
prepared_index = construct_prepared_index(index, properties_hash)
|
228
269
|
|
229
|
-
if method_name =~ /^find_by_(\w*)/
|
270
|
+
if method_name =~ /^find_by_(\w*)/
|
230
271
|
id = if index[:options][:unique]
|
231
272
|
$redis.get prepared_index
|
232
273
|
else
|
@@ -302,10 +343,10 @@ module RedisOrm
|
|
302
343
|
if persisted? # then there might be old indices
|
303
344
|
# check whether there's old indices exists and if yes - delete them
|
304
345
|
@@properties[model_name].each do |prop|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
prev_prop_value =
|
346
|
+
# if there were no changes for current property skip it (indices remains the same)
|
347
|
+
next if ! self.send(:"#{prop[:name]}_changed?")
|
348
|
+
|
349
|
+
prev_prop_value = instance_variable_get(:"@#{prop[:name]}_changes").first
|
309
350
|
|
310
351
|
indices = @@indices[model_name].inject([]) do |sum, models_index|
|
311
352
|
if models_index[:name].is_a?(Array)
|
@@ -380,13 +421,7 @@ module RedisOrm
|
|
380
421
|
# save new indices in order to sort by finders
|
381
422
|
# city:name:Харьков => 1
|
382
423
|
@@indices[model_name].each do |index|
|
383
|
-
prepared_index =
|
384
|
-
index[:name].inject([model_name]) do |sum, index_part|
|
385
|
-
sum += [index_part, self.instance_variable_get(:"@#{index_part}").to_s]
|
386
|
-
end.join(':')
|
387
|
-
else
|
388
|
-
[model_name, index[:name], self.instance_variable_get(:"@#{index[:name]}").to_s].join(':')
|
389
|
-
end
|
424
|
+
prepared_index = construct_prepared_index(index) # instance method not class one!
|
390
425
|
|
391
426
|
if index[:options][:unique]
|
392
427
|
$redis.set(prepared_index, @id)
|
@@ -494,13 +529,7 @@ module RedisOrm
|
|
494
529
|
|
495
530
|
# we need to ensure that smembers are correct after removal of the record
|
496
531
|
@@indices[model_name].each do |index|
|
497
|
-
prepared_index =
|
498
|
-
index[:name].inject([model_name]) do |sum, index_part|
|
499
|
-
sum += [index_part, self.instance_variable_get(:"@#{index_part}")]
|
500
|
-
end.join(':')
|
501
|
-
else
|
502
|
-
[model_name, index[:name], self.instance_variable_get(:"@#{index[:name]}")].join(':')
|
503
|
-
end
|
532
|
+
prepared_index = construct_prepared_index(index) # instance method not class one!
|
504
533
|
|
505
534
|
if index[:options][:unique]
|
506
535
|
$redis.del(prepared_index)
|
@@ -514,6 +543,21 @@ module RedisOrm
|
|
514
543
|
end
|
515
544
|
|
516
545
|
true # if there were no errors just return true, so *if* conditions would work
|
517
|
-
end
|
546
|
+
end
|
547
|
+
|
548
|
+
protected
|
549
|
+
def construct_prepared_index(index)
|
550
|
+
prepared_index = if index[:name].is_a?(Array) # TODO sort alphabetically
|
551
|
+
index[:name].inject([model_name]) do |sum, index_part|
|
552
|
+
sum += [index_part, self.instance_variable_get(:"@#{index_part}")]
|
553
|
+
end.join(':')
|
554
|
+
else
|
555
|
+
[model_name, index[:name], self.instance_variable_get(:"@#{index[:name]}")].join(':')
|
556
|
+
end
|
557
|
+
|
558
|
+
prepared_index.downcase! if index[:options][:case_insensitive]
|
559
|
+
|
560
|
+
prepared_index
|
561
|
+
end
|
518
562
|
end
|
519
563
|
end
|
data/redis_orm.gemspec
CHANGED
@@ -2,22 +2,22 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{redis_orm}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.4"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
-
s.authors = [
|
9
|
-
s.date = %q{2011-06-
|
8
|
+
s.authors = [%q{Dmitrii Samoilov}]
|
9
|
+
s.date = %q{2011-06-15}
|
10
10
|
s.description = %q{ORM for Redis advanced key-value storage}
|
11
11
|
s.email = %q{germaninthetown@gmail.com}
|
12
|
-
s.extra_rdoc_files = [
|
13
|
-
s.files = [
|
12
|
+
s.extra_rdoc_files = [%q{CHANGELOG}, %q{LICENSE}, %q{README.md}, %q{lib/redis_orm.rb}, %q{lib/redis_orm/active_model_behavior.rb}, %q{lib/redis_orm/associations/belongs_to.rb}, %q{lib/redis_orm/associations/has_many.rb}, %q{lib/redis_orm/associations/has_many_proxy.rb}, %q{lib/redis_orm/associations/has_one.rb}, %q{lib/redis_orm/redis_orm.rb}]
|
13
|
+
s.files = [%q{CHANGELOG}, %q{LICENSE}, %q{Manifest}, %q{README.md}, %q{Rakefile}, %q{lib/redis_orm.rb}, %q{lib/redis_orm/active_model_behavior.rb}, %q{lib/redis_orm/associations/belongs_to.rb}, %q{lib/redis_orm/associations/has_many.rb}, %q{lib/redis_orm/associations/has_many_proxy.rb}, %q{lib/redis_orm/associations/has_one.rb}, %q{lib/redis_orm/redis_orm.rb}, %q{redis_orm.gemspec}, %q{test/associations_test.rb}, %q{test/basic_functionality_test.rb}, %q{test/callbacks_test.rb}, %q{test/changes_array_test.rb}, %q{test/dynamic_finders_test.rb}, %q{test/exceptions_test.rb}, %q{test/has_one_has_many_test.rb}, %q{test/indices_test.rb}, %q{test/options_test.rb}, %q{test/polymorphic_test.rb}, %q{test/redis.conf}, %q{test/test_helper.rb}, %q{test/validations_test.rb}]
|
14
14
|
s.homepage = %q{https://github.com/german/redis_orm}
|
15
|
-
s.rdoc_options = [
|
16
|
-
s.require_paths = [
|
15
|
+
s.rdoc_options = [%q{--line-numbers}, %q{--inline-source}, %q{--title}, %q{Redis_orm}, %q{--main}, %q{README.md}]
|
16
|
+
s.require_paths = [%q{lib}]
|
17
17
|
s.rubyforge_project = %q{redis_orm}
|
18
|
-
s.rubygems_version = %q{1.
|
18
|
+
s.rubygems_version = %q{1.8.5}
|
19
19
|
s.summary = %q{ORM for Redis advanced key-value storage}
|
20
|
-
s.test_files = [
|
20
|
+
s.test_files = [%q{test/options_test.rb}, %q{test/dynamic_finders_test.rb}, %q{test/associations_test.rb}, %q{test/validations_test.rb}, %q{test/test_helper.rb}, %q{test/polymorphic_test.rb}, %q{test/exceptions_test.rb}, %q{test/has_one_has_many_test.rb}, %q{test/indices_test.rb}, %q{test/changes_array_test.rb}, %q{test/callbacks_test.rb}, %q{test/basic_functionality_test.rb}]
|
21
21
|
|
22
22
|
if s.respond_to? :specification_version then
|
23
23
|
s.specification_version = 3
|
data/test/associations_test.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require File.dirname(File.expand_path(__FILE__)) + '/../lib/redis_orm.rb'
|
1
|
+
require File.dirname(File.expand_path(__FILE__)) + '/test_helper.rb'
|
3
2
|
|
4
3
|
class Article < RedisOrm::Base
|
5
4
|
property :title, String
|
@@ -33,17 +32,13 @@ class User < RedisOrm::Base
|
|
33
32
|
has_many :users, :as => :friends
|
34
33
|
end
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
41
|
-
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
|
42
|
-
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
43
|
-
end
|
35
|
+
class Message < RedisOrm::Base
|
36
|
+
property :text, String
|
37
|
+
has_one :message, :as => :replay_to
|
38
|
+
end
|
44
39
|
|
40
|
+
describe "check associations" do
|
45
41
|
before(:each) do
|
46
|
-
$redis.flushall if $redis
|
47
42
|
@article = Article.new
|
48
43
|
@article.title = "DHH drops OpenID on 37signals"
|
49
44
|
@article.save
|
@@ -64,14 +59,6 @@ describe "check associations" do
|
|
64
59
|
@comment2.body.should == "test #2"
|
65
60
|
end
|
66
61
|
|
67
|
-
after(:each) do
|
68
|
-
$redis.flushall if $redis
|
69
|
-
end
|
70
|
-
|
71
|
-
after(:all) do
|
72
|
-
Process.kill 9, $redis_pid.to_i if $redis_pid
|
73
|
-
end
|
74
|
-
|
75
62
|
it "should assign properly from belongs_to side" do
|
76
63
|
@comment1.article.should == nil
|
77
64
|
@comment1.article = @article
|
@@ -303,4 +290,20 @@ describe "check associations" do
|
|
303
290
|
me.friends[0].id == friend2.id
|
304
291
|
User.count.should == 3
|
305
292
|
end
|
293
|
+
|
294
|
+
it "should create self-referencing link for has_one association" do
|
295
|
+
m = Message.create :text => "it should create self-referencing link for has_one association"
|
296
|
+
|
297
|
+
r = Message.create :text => "replay"
|
298
|
+
|
299
|
+
r.replay_to = m
|
300
|
+
|
301
|
+
Message.count.should == 2
|
302
|
+
r.replay_to.should be
|
303
|
+
r.replay_to.id.should == m.id
|
304
|
+
|
305
|
+
rf = Message.last
|
306
|
+
rf.replay_to.should be
|
307
|
+
rf.replay_to.id.should == Message.first.id
|
308
|
+
end
|
306
309
|
end
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require File.dirname(File.expand_path(__FILE__)) + '/../lib/redis_orm.rb'
|
1
|
+
require File.dirname(File.expand_path(__FILE__)) + '/test_helper.rb'
|
3
2
|
|
4
3
|
class User < RedisOrm::Base
|
5
4
|
property :name, String
|
@@ -16,7 +15,8 @@ class DefaultUser < RedisOrm::Base
|
|
16
15
|
property :age, Integer, :default => 26
|
17
16
|
property :wage, Float, :default => 256.25
|
18
17
|
property :male, RedisOrm::Boolean, :default => true
|
19
|
-
|
18
|
+
property :admin, RedisOrm::Boolean, :default => false
|
19
|
+
|
20
20
|
property :created_at, Time
|
21
21
|
property :modified_at, Time
|
22
22
|
end
|
@@ -26,26 +26,6 @@ class TimeStamp < RedisOrm::Base
|
|
26
26
|
end
|
27
27
|
|
28
28
|
describe "check basic functionality" do
|
29
|
-
before(:all) do
|
30
|
-
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
|
31
|
-
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
|
32
|
-
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
33
|
-
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
|
34
|
-
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
35
|
-
end
|
36
|
-
|
37
|
-
before(:each) do
|
38
|
-
$redis.flushall if $redis
|
39
|
-
end
|
40
|
-
|
41
|
-
after(:each) do
|
42
|
-
$redis.flushall if $redis
|
43
|
-
end
|
44
|
-
|
45
|
-
after(:all) do
|
46
|
-
Process.kill 9, $redis_pid.to_i if $redis_pid
|
47
|
-
end
|
48
|
-
|
49
29
|
it "test_simple_creation" do
|
50
30
|
User.count.should == 0
|
51
31
|
|
@@ -160,12 +140,22 @@ describe "check basic functionality" do
|
|
160
140
|
u.modified_at.class.should == Time
|
161
141
|
u.wage.class.should == Float
|
162
142
|
u.male.class.to_s.should match(/TrueClass|FalseClass/)
|
143
|
+
u.admin.class.to_s.should match(/TrueClass|FalseClass/)
|
163
144
|
u.age.class.to_s.should match(/Integer|Fixnum/)
|
164
145
|
|
165
146
|
u.name.should == "german"
|
166
147
|
u.male.should == true
|
167
148
|
u.age.should == 26
|
168
149
|
u.wage.should == 256.25
|
150
|
+
u.admin.should == false
|
151
|
+
|
152
|
+
du = DefaultUser.new
|
153
|
+
du.name = "germaninthetown"
|
154
|
+
du.save
|
155
|
+
|
156
|
+
du_saved = DefaultUser.last
|
157
|
+
du_saved.name.should == "germaninthetown"
|
158
|
+
du_saved.admin.should == false
|
169
159
|
end
|
170
160
|
|
171
161
|
it "should expand timestamps declaration properly" do
|
data/test/callbacks_test.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require File.dirname(File.expand_path(__FILE__)) + '/../lib/redis_orm.rb'
|
1
|
+
require File.dirname(File.expand_path(__FILE__)) + '/test_helper.rb'
|
3
2
|
|
4
3
|
class CutoutAggregator < RedisOrm::Base
|
5
4
|
property :modified_at, Time
|
@@ -72,26 +71,6 @@ class User < RedisOrm::Base
|
|
72
71
|
end
|
73
72
|
|
74
73
|
describe "check callbacks" do
|
75
|
-
before(:all) do
|
76
|
-
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
|
77
|
-
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
|
78
|
-
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
79
|
-
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
|
80
|
-
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
81
|
-
end
|
82
|
-
|
83
|
-
before(:each) do
|
84
|
-
$redis.flushall if $redis
|
85
|
-
end
|
86
|
-
|
87
|
-
after(:each) do
|
88
|
-
$redis.flushall if $redis
|
89
|
-
end
|
90
|
-
|
91
|
-
after(:all) do
|
92
|
-
Process.kill 9, $redis_pid.to_i if $redis_pid
|
93
|
-
end
|
94
|
-
|
95
74
|
it "should fire after_create/after_destroy callbacks" do
|
96
75
|
user = User.new :first_name => "Robert", :last_name => "Pirsig"
|
97
76
|
user.save
|
data/test/changes_array_test.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require File.dirname(File.expand_path(__FILE__)) + '/../lib/redis_orm.rb'
|
1
|
+
require File.dirname(File.expand_path(__FILE__)) + '/test_helper.rb'
|
3
2
|
|
4
3
|
class User < RedisOrm::Base
|
5
4
|
property :name, String
|
@@ -8,40 +7,25 @@ class User < RedisOrm::Base
|
|
8
7
|
end
|
9
8
|
|
10
9
|
describe "check associations" do
|
11
|
-
before(:all) do
|
12
|
-
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
|
13
|
-
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
|
14
|
-
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
15
|
-
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
|
16
|
-
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
17
|
-
end
|
18
|
-
|
19
|
-
before(:each) do
|
20
|
-
$redis.flushall if $redis
|
21
|
-
end
|
22
|
-
|
23
|
-
after(:each) do
|
24
|
-
$redis.flushall if $redis
|
25
|
-
end
|
26
|
-
|
27
|
-
after(:all) do
|
28
|
-
Process.kill 9, $redis_pid.to_i if $redis_pid
|
29
|
-
end
|
30
|
-
|
31
10
|
it "should return correct _changes array" do
|
32
11
|
user = User.new :name => "german"
|
33
|
-
|
12
|
+
user.name_changed?.should == false
|
13
|
+
|
34
14
|
user.name_changes.should == ["german"]
|
35
15
|
user.save
|
16
|
+
|
36
17
|
user.name_changes.should == ["german"]
|
37
18
|
user.name = "germaninthetown"
|
38
19
|
user.name_changes.should == ["german", "germaninthetown"]
|
20
|
+
user.name_changed?.should == true
|
39
21
|
user.save
|
40
22
|
|
41
23
|
user = User.first
|
42
24
|
user.name.should == "germaninthetown"
|
25
|
+
user.name_changed?.should == false
|
43
26
|
user.name_changes.should == ["germaninthetown"]
|
44
27
|
user.name = "german"
|
28
|
+
user.name_changed?.should == true
|
45
29
|
user.name_changes.should == ["germaninthetown", "german"]
|
46
30
|
end
|
47
31
|
end
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require File.dirname(File.expand_path(__FILE__)) + '/../lib/redis_orm.rb'
|
1
|
+
require File.dirname(File.expand_path(__FILE__)) + '/test_helper.rb'
|
3
2
|
|
4
3
|
class User < RedisOrm::Base
|
5
4
|
property :first_name, String
|
@@ -20,26 +19,6 @@ class CustomUser < RedisOrm::Base
|
|
20
19
|
end
|
21
20
|
|
22
21
|
describe "check associations" do
|
23
|
-
before(:all) do
|
24
|
-
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
|
25
|
-
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
|
26
|
-
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
27
|
-
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
|
28
|
-
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
29
|
-
end
|
30
|
-
|
31
|
-
before(:each) do
|
32
|
-
$redis.flushall if $redis
|
33
|
-
end
|
34
|
-
|
35
|
-
after(:each) do
|
36
|
-
$redis.flushall if $redis
|
37
|
-
end
|
38
|
-
|
39
|
-
after(:all) do
|
40
|
-
Process.kill 9, $redis_pid.to_i if $redis_pid
|
41
|
-
end
|
42
|
-
|
43
22
|
it "should create and use indexes to implement dynamic finders" do
|
44
23
|
user1 = User.new
|
45
24
|
user1.first_name = "Dmitrii"
|
data/test/exceptions_test.rb
CHANGED
@@ -1,58 +1,40 @@
|
|
1
|
-
require '
|
2
|
-
require File.dirname(File.expand_path(__FILE__)) + '/../lib/redis_orm.rb'
|
1
|
+
require File.dirname(File.expand_path(__FILE__)) + '/test_helper.rb'
|
3
2
|
|
4
3
|
class User < RedisOrm::Base
|
5
4
|
property :name, String
|
6
5
|
property :age, Integer
|
7
6
|
property :created_at, Time
|
8
7
|
|
8
|
+
index :age
|
9
|
+
|
9
10
|
has_one :profile
|
10
11
|
end
|
11
12
|
|
12
13
|
class Profile < RedisOrm::Base
|
13
14
|
property :title, String
|
14
|
-
|
15
15
|
belongs_to :user
|
16
16
|
end
|
17
17
|
|
18
18
|
class Jigsaw < RedisOrm::Base
|
19
19
|
property :title, String
|
20
|
-
|
21
20
|
belongs_to :user
|
22
21
|
end
|
23
22
|
|
24
23
|
describe "exceptions test" do
|
25
|
-
before(:all) do
|
26
|
-
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
|
27
|
-
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
|
28
|
-
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
29
|
-
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
|
30
|
-
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
31
|
-
end
|
32
|
-
|
33
|
-
before(:each) do
|
34
|
-
$redis.flushall if $redis
|
35
|
-
end
|
36
|
-
|
37
|
-
after(:each) do
|
38
|
-
$redis.flushall if $redis
|
39
|
-
end
|
40
|
-
|
41
|
-
after(:all) do
|
42
|
-
Process.kill 9, $redis_pid.to_i if $redis_pid
|
43
|
-
end
|
44
|
-
|
45
24
|
it "should raise an exception if association is provided with improper class" do
|
46
25
|
User.count.should == 0
|
47
26
|
|
48
|
-
user = User.new
|
49
|
-
user.name = "german"
|
27
|
+
user = User.new :name => "german", :age => 26
|
50
28
|
user.save
|
51
29
|
|
52
30
|
user.should be
|
53
31
|
user.name.should == "german"
|
54
32
|
User.count.should == 1
|
55
33
|
|
34
|
+
lambda{ User.find :all, :conditions => {:name => "german"} }.should raise_error
|
35
|
+
User.find(:all, :conditions => {:age => 26}).size.should == 1
|
36
|
+
lambda{ User.find :all, :conditions => {:name => "german", :age => 26} }.should raise_error
|
37
|
+
|
56
38
|
jigsaw = Jigsaw.new
|
57
39
|
jigsaw.title = "123"
|
58
40
|
jigsaw.save
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require File.dirname(File.expand_path(__FILE__)) + '/../lib/redis_orm.rb'
|
1
|
+
require File.dirname(File.expand_path(__FILE__)) + '/test_helper.rb'
|
3
2
|
|
4
3
|
class Profile < RedisOrm::Base
|
5
4
|
property :name, String
|
@@ -14,26 +13,6 @@ class Location < RedisOrm::Base
|
|
14
13
|
end
|
15
14
|
|
16
15
|
describe "check associations" do
|
17
|
-
before(:all) do
|
18
|
-
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
|
19
|
-
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
|
20
|
-
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
21
|
-
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
|
22
|
-
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
23
|
-
end
|
24
|
-
|
25
|
-
before(:each) do
|
26
|
-
$redis.flushall if $redis
|
27
|
-
end
|
28
|
-
|
29
|
-
after(:each) do
|
30
|
-
$redis.flushall if $redis
|
31
|
-
end
|
32
|
-
|
33
|
-
after(:all) do
|
34
|
-
Process.kill 9, $redis_pid.to_i if $redis_pid
|
35
|
-
end
|
36
|
-
|
37
16
|
it "should save associations properly" do
|
38
17
|
@profile = Profile.new
|
39
18
|
@profile.name = "my profile"
|
data/test/indices_test.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require File.dirname(File.expand_path(__FILE__)) + '/../lib/redis_orm.rb'
|
1
|
+
require File.dirname(File.expand_path(__FILE__)) + '/test_helper.rb'
|
3
2
|
|
4
3
|
class User < RedisOrm::Base
|
5
4
|
property :first_name, String
|
@@ -10,27 +9,16 @@ class User < RedisOrm::Base
|
|
10
9
|
index [:first_name, :last_name]
|
11
10
|
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
|
17
|
-
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
18
|
-
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
|
19
|
-
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
20
|
-
end
|
21
|
-
|
22
|
-
before(:each) do
|
23
|
-
$redis.flushall if $redis
|
24
|
-
end
|
25
|
-
|
26
|
-
after(:each) do
|
27
|
-
$redis.flushall if $redis
|
28
|
-
end
|
12
|
+
class OmniUser < RedisOrm::Base
|
13
|
+
property :email, String
|
14
|
+
property :uid, Integer
|
29
15
|
|
30
|
-
|
31
|
-
|
32
|
-
|
16
|
+
index :email, :case_insensitive => true
|
17
|
+
index :uid
|
18
|
+
index [:email, :uid], :case_insensitive => true
|
19
|
+
end
|
33
20
|
|
21
|
+
describe "check indices" do
|
34
22
|
it "should change index accordingly to the changes in the model" do
|
35
23
|
user = User.new :first_name => "Robert", :last_name => "Pirsig"
|
36
24
|
user.save
|
@@ -73,4 +61,21 @@ describe "check indices" do
|
|
73
61
|
User.find_by_last_name("Robin").id.should == user.id
|
74
62
|
User.find_by_first_name_and_last_name("Christofer", "Robin").id.should == user.id
|
75
63
|
end
|
64
|
+
|
65
|
+
it "should create case insensitive indices too" do
|
66
|
+
ou = OmniUser.new :email => "GERMAN@Ya.ru", :uid => 2718281828
|
67
|
+
ou.save
|
68
|
+
|
69
|
+
OmniUser.count.should == 1
|
70
|
+
OmniUser.find_by_email("german@ya.ru").should be
|
71
|
+
OmniUser.find_all_by_email("german@ya.ru").count.should == 1
|
72
|
+
|
73
|
+
OmniUser.find_by_email_and_uid("german@ya.ru", 2718281828).should be
|
74
|
+
OmniUser.find_all_by_email_and_uid("german@ya.ru", 2718281828).count.should == 1
|
75
|
+
|
76
|
+
OmniUser.find_by_email("geRman@yA.rU").should be
|
77
|
+
OmniUser.find_all_by_email_and_uid("GerMan@Ya.ru", 2718281828).count.should == 1
|
78
|
+
|
79
|
+
OmniUser.find_all_by_email_and_uid("german@ya.ru", 2718281829).count.should == 0
|
80
|
+
end
|
76
81
|
end
|
data/test/options_test.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require File.dirname(File.expand_path(__FILE__)) + '/../lib/redis_orm.rb'
|
1
|
+
require File.dirname(File.expand_path(__FILE__)) + '/test_helper.rb'
|
3
2
|
|
4
3
|
class Album < RedisOrm::Base
|
5
4
|
property :title, String
|
@@ -16,6 +15,10 @@ end
|
|
16
15
|
|
17
16
|
class Photo < RedisOrm::Base
|
18
17
|
property :image, String
|
18
|
+
property :image_type, String
|
19
|
+
|
20
|
+
index :image
|
21
|
+
index [:image, :image_type]
|
19
22
|
|
20
23
|
belongs_to :album
|
21
24
|
belongs_to :user
|
@@ -29,24 +32,7 @@ class User < RedisOrm::Base
|
|
29
32
|
end
|
30
33
|
|
31
34
|
describe "test options" do
|
32
|
-
before(:all) do
|
33
|
-
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
|
34
|
-
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
|
35
|
-
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
36
|
-
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
|
37
|
-
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
38
|
-
end
|
39
|
-
|
40
|
-
after(:all) do
|
41
|
-
Process.kill 9, $redis_pid.to_i if $redis_pid
|
42
|
-
end
|
43
|
-
|
44
|
-
after(:each) do
|
45
|
-
$redis.flushall if $redis
|
46
|
-
end
|
47
|
-
|
48
35
|
before(:each) do
|
49
|
-
$redis.flushall if $redis
|
50
36
|
@album = Album.new
|
51
37
|
@album.title = "my 1st album"
|
52
38
|
@album.save
|
@@ -54,17 +40,17 @@ describe "test options" do
|
|
54
40
|
@album.should be
|
55
41
|
@album.title.should == "my 1st album"
|
56
42
|
|
57
|
-
@photo1 = Photo.new
|
58
|
-
@photo1.image = "facepalm.jpg"
|
43
|
+
@photo1 = Photo.new :image => "facepalm.jpg", :image_type => "jpg"
|
59
44
|
@photo1.save
|
60
45
|
@photo1.should be
|
61
46
|
@photo1.image.should == "facepalm.jpg"
|
47
|
+
@photo1.image_type.should == "jpg"
|
62
48
|
|
63
|
-
@photo2 = Photo.new
|
64
|
-
@photo2.image = "boobs.jpg"
|
49
|
+
@photo2 = Photo.new :image => "boobs.png", :image_type => "png"
|
65
50
|
@photo2.save
|
66
51
|
@photo2.should be
|
67
|
-
@photo2.image.should == "boobs.
|
52
|
+
@photo2.image.should == "boobs.png"
|
53
|
+
@photo2.image_type.should == "png"
|
68
54
|
end
|
69
55
|
|
70
56
|
it "should return correct array when :limit and :offset options are provided" do
|
@@ -82,7 +68,25 @@ describe "test options" do
|
|
82
68
|
@album.photos.all(:limit => 1, :offset => 1).size.should == 1 # [@photo2]
|
83
69
|
@album.photos.all(:limit => 2, :offset => 2).should == []
|
84
70
|
|
85
|
-
@album.photos.find(:all, :limit => 1, :offset => 1).size.should == 1
|
71
|
+
@album.photos.find(:all, :limit => 1, :offset => 1).size.should == 1
|
72
|
+
|
73
|
+
Photo.find(:all, :conditions => {:image => "facepalm.jpg"}).size.should == 1
|
74
|
+
Photo.find(:all, :conditions => {:image => "boobs.png"}).size.should == 1
|
75
|
+
|
76
|
+
Photo.find(:all, :conditions => {:image => "facepalm.jpg", :image_type => "jpg"}).size.should == 1
|
77
|
+
Photo.find(:all, :conditions => {:image => "boobs.png", :image_type => "png"}).size.should == 1
|
78
|
+
|
79
|
+
Photo.find(:first, :conditions => {:image => "facepalm.jpg"}).id.should == @photo1.id
|
80
|
+
Photo.find(:first, :conditions => {:image => "boobs.png"}).id.should == @photo2.id
|
81
|
+
|
82
|
+
Photo.find(:first, :conditions => {:image => "facepalm.jpg", :image_type => "jpg"}).id.should == @photo1.id
|
83
|
+
Photo.find(:first, :conditions => {:image => "boobs.png", :image_type => "png"}).id.should == @photo2.id
|
84
|
+
|
85
|
+
Photo.find(:last, :conditions => {:image => "facepalm.jpg"}).id.should == @photo1.id
|
86
|
+
Photo.find(:last, :conditions => {:image => "boobs.png"}).id.should == @photo2.id
|
87
|
+
|
88
|
+
Photo.find(:last, :conditions => {:image => "facepalm.jpg", :image_type => "jpg"}).id.should == @photo1.id
|
89
|
+
Photo.find(:last, :conditions => {:image => "boobs.png", :image_type => "png"}).id.should == @photo2.id
|
86
90
|
end
|
87
91
|
|
88
92
|
it "should return correct array when :order option is provided" do
|
data/test/polymorphic_test.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require File.dirname(File.expand_path(__FILE__)) + '/../lib/redis_orm.rb'
|
1
|
+
require File.dirname(File.expand_path(__FILE__)) + '/test_helper.rb'
|
3
2
|
|
4
3
|
class CatalogItem < RedisOrm::Base
|
5
4
|
property :title, String
|
@@ -41,26 +40,6 @@ class City < RedisOrm::Base
|
|
41
40
|
end
|
42
41
|
|
43
42
|
describe "check polymorphic property" do
|
44
|
-
before(:all) do
|
45
|
-
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
|
46
|
-
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
|
47
|
-
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
48
|
-
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
|
49
|
-
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
50
|
-
end
|
51
|
-
|
52
|
-
before(:each) do
|
53
|
-
$redis.flushall if $redis
|
54
|
-
end
|
55
|
-
|
56
|
-
after(:each) do
|
57
|
-
$redis.flushall if $redis
|
58
|
-
end
|
59
|
-
|
60
|
-
after(:all) do
|
61
|
-
Process.kill 9, $redis_pid.to_i if $redis_pid
|
62
|
-
end
|
63
|
-
|
64
43
|
it "should provide proper associations and save records correctly for has_one/belongs_to polymorphic" do
|
65
44
|
book = Book.new :title => "Permutation City", :author => "Egan Greg", :price => 1529
|
66
45
|
book.save
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'rspec/autorun'
|
3
|
+
require File.dirname(File.expand_path(__FILE__)) + '/../lib/redis_orm.rb'
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.before(:all) do
|
7
|
+
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
|
8
|
+
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
|
9
|
+
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
10
|
+
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
|
11
|
+
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
12
|
+
end
|
13
|
+
|
14
|
+
config.after(:all) do
|
15
|
+
Process.kill 9, $redis_pid.to_i if $redis_pid
|
16
|
+
end
|
17
|
+
|
18
|
+
config.after(:each) do
|
19
|
+
$redis.flushall if $redis
|
20
|
+
end
|
21
|
+
|
22
|
+
config.before(:each) do
|
23
|
+
$redis.flushall if $redis
|
24
|
+
end
|
25
|
+
end
|
data/test/validations_test.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require File.dirname(File.expand_path(__FILE__)) + '/../lib/redis_orm.rb'
|
1
|
+
require File.dirname(File.expand_path(__FILE__)) + '/test_helper.rb'
|
3
2
|
|
4
3
|
class Photo < RedisOrm::Base
|
5
4
|
property :image, String
|
@@ -10,26 +9,6 @@ class Photo < RedisOrm::Base
|
|
10
9
|
end
|
11
10
|
|
12
11
|
describe "check associations" do
|
13
|
-
before(:all) do
|
14
|
-
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
|
15
|
-
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
|
16
|
-
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
|
17
|
-
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
|
18
|
-
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
|
19
|
-
end
|
20
|
-
|
21
|
-
after(:all) do
|
22
|
-
Process.kill 9, $redis_pid.to_i if $redis_pid
|
23
|
-
end
|
24
|
-
|
25
|
-
after(:each) do
|
26
|
-
$redis.flushall if $redis
|
27
|
-
end
|
28
|
-
|
29
|
-
before(:each) do
|
30
|
-
$redis.flushall if $redis
|
31
|
-
end
|
32
|
-
|
33
12
|
it "should validate presence if image in photo" do
|
34
13
|
p = Photo.new
|
35
14
|
p.save.should == false
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis_orm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.4'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,12 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-06-
|
13
|
-
default_executable:
|
12
|
+
date: 2011-06-15 00:00:00.000000000Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: activesupport
|
17
|
-
requirement: &
|
16
|
+
requirement: &81951070 !ruby/object:Gem::Requirement
|
18
17
|
none: false
|
19
18
|
requirements:
|
20
19
|
- - ! '>='
|
@@ -22,10 +21,10 @@ dependencies:
|
|
22
21
|
version: 3.0.0
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
|
-
version_requirements: *
|
24
|
+
version_requirements: *81951070
|
26
25
|
- !ruby/object:Gem::Dependency
|
27
26
|
name: activemodel
|
28
|
-
requirement: &
|
27
|
+
requirement: &81950820 !ruby/object:Gem::Requirement
|
29
28
|
none: false
|
30
29
|
requirements:
|
31
30
|
- - ! '>='
|
@@ -33,10 +32,10 @@ dependencies:
|
|
33
32
|
version: 3.0.0
|
34
33
|
type: :runtime
|
35
34
|
prerelease: false
|
36
|
-
version_requirements: *
|
35
|
+
version_requirements: *81950820
|
37
36
|
- !ruby/object:Gem::Dependency
|
38
37
|
name: redis
|
39
|
-
requirement: &
|
38
|
+
requirement: &81950570 !ruby/object:Gem::Requirement
|
40
39
|
none: false
|
41
40
|
requirements:
|
42
41
|
- - ! '>='
|
@@ -44,10 +43,10 @@ dependencies:
|
|
44
43
|
version: 2.2.0
|
45
44
|
type: :runtime
|
46
45
|
prerelease: false
|
47
|
-
version_requirements: *
|
46
|
+
version_requirements: *81950570
|
48
47
|
- !ruby/object:Gem::Dependency
|
49
48
|
name: rspec
|
50
|
-
requirement: &
|
49
|
+
requirement: &81950320 !ruby/object:Gem::Requirement
|
51
50
|
none: false
|
52
51
|
requirements:
|
53
52
|
- - ! '>='
|
@@ -55,7 +54,7 @@ dependencies:
|
|
55
54
|
version: 2.5.0
|
56
55
|
type: :development
|
57
56
|
prerelease: false
|
58
|
-
version_requirements: *
|
57
|
+
version_requirements: *81950320
|
59
58
|
description: ORM for Redis advanced key-value storage
|
60
59
|
email: germaninthetown@gmail.com
|
61
60
|
executables: []
|
@@ -96,8 +95,8 @@ files:
|
|
96
95
|
- test/options_test.rb
|
97
96
|
- test/polymorphic_test.rb
|
98
97
|
- test/redis.conf
|
98
|
+
- test/test_helper.rb
|
99
99
|
- test/validations_test.rb
|
100
|
-
has_rdoc: true
|
101
100
|
homepage: https://github.com/german/redis_orm
|
102
101
|
licenses: []
|
103
102
|
post_install_message:
|
@@ -124,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
123
|
version: '1.2'
|
125
124
|
requirements: []
|
126
125
|
rubyforge_project: redis_orm
|
127
|
-
rubygems_version: 1.
|
126
|
+
rubygems_version: 1.8.5
|
128
127
|
signing_key:
|
129
128
|
specification_version: 3
|
130
129
|
summary: ORM for Redis advanced key-value storage
|
@@ -133,6 +132,7 @@ test_files:
|
|
133
132
|
- test/dynamic_finders_test.rb
|
134
133
|
- test/associations_test.rb
|
135
134
|
- test/validations_test.rb
|
135
|
+
- test/test_helper.rb
|
136
136
|
- test/polymorphic_test.rb
|
137
137
|
- test/exceptions_test.rb
|
138
138
|
- test/has_one_has_many_test.rb
|