dm-redis-adapter 0.5.3 → 0.6.0
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/README.textile +8 -2
- data/lib/dm-redis-adapter.rb +1 -1
- data/lib/dm-redis-adapter/adapter.rb +66 -51
- data/spec/dm_redis_finding_spec.rb +4 -5
- data/spec/self_referential_spec.rb +50 -0
- metadata +14 -14
data/README.textile
CHANGED
@@ -8,8 +8,13 @@ Redis is a very fast key-value store with some interesting data structures added
|
|
8
8
|
|
9
9
|
Marrying DataMapper to Redis allows for schema-less models, you can add fields at any time without having to create a migration. DataMapper also allows us to store non-native Redis types in the db, like Date fields.
|
10
10
|
|
11
|
+
h1. Upgrading
|
12
|
+
|
13
|
+
Please note that as of version 0.5.3 of the gem, the key names that are used for storage have changed and break compatibility with previous versions!
|
14
|
+
|
11
15
|
h1. Changelog
|
12
16
|
|
17
|
+
* v0.5.3 Support for inheritance via sfeu and ujifgc, this version *breaks compatibility* with previous versions of the gem
|
13
18
|
* v0.4.0 Support for dm-core v1.1.0
|
14
19
|
* v0.3.0 Updates to support ruby 1.9.2 (thanks arbarlow!)
|
15
20
|
* v0.2.1 Fixes to sorting
|
@@ -21,9 +26,9 @@ h1. Install
|
|
21
26
|
|
22
27
|
Prerequisites:
|
23
28
|
* Redis:
|
24
|
-
** <a href="http://code.google.com/p/redis/">Redis, v2.2 series</a>
|
29
|
+
** <a href="http://code.google.com/p/redis/">Redis, >= v2.2 series</a>
|
25
30
|
|
26
|
-
Install the dm-redis
|
31
|
+
Install the dm-redis-adapter:
|
27
32
|
<pre>
|
28
33
|
<code>
|
29
34
|
> gem install dm-redis-adapter
|
@@ -98,4 +103,5 @@ h1. Badass contributors
|
|
98
103
|
* <a href="http://github.com/bpo">brian p o'rourke (bpo)</a> Updates for newer versions of redis client and DM JSON type support, move to hash storage
|
99
104
|
* <a href="http://github.com/arbarlow">Alex Barlow (arbarlow)</a> Fixes for ruby 1.9.2
|
100
105
|
* <a href="http://github.com/jof">Jonathan Lassoff (jof)</a> Fixes to support textual keys
|
106
|
+
* <a href="http://github.com/sfeu">Sebastian Feuerstack (sfeu)</a> Fixes to support inheritance
|
101
107
|
|
data/lib/dm-redis-adapter.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require 'dm-redis-adapter/adapter'
|
1
|
+
require 'dm-redis-adapter/adapter'
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'redis/connection/hiredis'
|
2
2
|
require 'redis'
|
3
3
|
require 'base64'
|
4
|
-
require 'dm-core'
|
5
4
|
|
6
5
|
module DataMapper
|
7
6
|
module Adapters
|
@@ -92,12 +91,11 @@ module DataMapper
|
|
92
91
|
#
|
93
92
|
# @api semipublic
|
94
93
|
def delete(collection)
|
95
|
-
storage_name = collection.query.model.storage_name
|
96
94
|
collection.each do |record|
|
97
|
-
@redis.del("#{
|
95
|
+
@redis.del("#{collection.query.model.to_s.downcase}:#{record[redis_key_for(collection.query.model)]}")
|
98
96
|
@redis.srem(key_set_for(collection.query.model), record[redis_key_for(collection.query.model)])
|
99
97
|
record.model.properties.select {|p| p.index}.each do |p|
|
100
|
-
@redis.srem("#{
|
98
|
+
@redis.srem("#{collection.query.model.to_s.downcase}:#{p.name}:#{encode(record[p.name])}", record[redis_key_for(collection.query.model)])
|
101
99
|
end
|
102
100
|
end
|
103
101
|
end
|
@@ -114,6 +112,7 @@ module DataMapper
|
|
114
112
|
def update_attributes(resources)
|
115
113
|
storage_name = resources.first.model.storage_name
|
116
114
|
resources.each do |resource|
|
115
|
+
|
117
116
|
model = resource.model
|
118
117
|
attributes = resource.dirty_attributes
|
119
118
|
|
@@ -124,6 +123,7 @@ module DataMapper
|
|
124
123
|
properties_to_set = []
|
125
124
|
properties_to_del = []
|
126
125
|
|
126
|
+
|
127
127
|
fields = model.properties(self.name).select {|property| attributes.key?(property)}
|
128
128
|
fields.each do |property|
|
129
129
|
value = attributes[property]
|
@@ -171,29 +171,14 @@ module DataMapper
|
|
171
171
|
keys
|
172
172
|
end
|
173
173
|
|
174
|
-
|
175
|
-
# Find records that match have a matching value
|
176
|
-
#
|
177
|
-
# @param [DataMapper::Query] query
|
178
|
-
# The query used to locate the resources to be deleted.
|
179
|
-
#
|
180
|
-
# @param [DataMapper::Operation] the operation for the query
|
181
|
-
#
|
182
|
-
# @api private
|
183
|
-
def perform_query(query, operand)
|
184
|
-
storage_name = query.model.storage_name
|
185
|
-
|
186
|
-
matched_records = []
|
187
|
-
#p 'query: ' + query.inspect
|
188
|
-
#p 'operand: ' + operand.inspect
|
189
|
-
|
174
|
+
def find_subject_and_value(query, operand)
|
190
175
|
if operand.is_a?(DataMapper::Query::Conditions::NotOperation)
|
191
176
|
subject = operand.first.subject
|
192
177
|
value = operand.first.value
|
193
178
|
elsif operand.subject.is_a?(DataMapper::Associations::ManyToOne::Relationship)
|
194
179
|
subject = operand.subject.child_key.first
|
195
180
|
value = if operand.is_a?(DataMapper::Query::Conditions::InclusionComparison)
|
196
|
-
operand.value.map{|v|v[operand.subject.parent_key.first.name]}
|
181
|
+
operand.value.map{|v| v[operand.subject.parent_key.first.name]}
|
197
182
|
else
|
198
183
|
operand.value[operand.subject.parent_key.first.name]
|
199
184
|
end
|
@@ -206,46 +191,76 @@ module DataMapper
|
|
206
191
|
subject = subject.child_key.first
|
207
192
|
end
|
208
193
|
|
209
|
-
|
210
|
-
|
194
|
+
return subject, value
|
195
|
+
end
|
196
|
+
|
197
|
+
##
|
198
|
+
# Find records that match have a matching value
|
199
|
+
#
|
200
|
+
# @param [DataMapper::Query] query
|
201
|
+
# The query used to locate the resources to be deleted.
|
202
|
+
#
|
203
|
+
# @param [DataMapper::Operation] the operation for the query
|
204
|
+
#
|
205
|
+
# @api private
|
206
|
+
def perform_query(query, operand)
|
207
|
+
storage_name = query.model.storage_name
|
208
|
+
matched_records = []
|
209
|
+
subject, value = find_subject_and_value(query, operand)
|
211
210
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
211
|
+
case operand
|
212
|
+
when DataMapper::Query::Conditions::NotOperation
|
213
|
+
if query.model.key.include?(subject)
|
214
|
+
@redis.smembers(key_set_for(query.model)).each do |key|
|
215
|
+
if operand.matches?(subject.typecast(key))
|
216
|
+
matched_records << {redis_key_for(query.model) => key}
|
217
|
+
end
|
217
218
|
end
|
219
|
+
else
|
220
|
+
search_all_resources(query, operand, subject, matched_records)
|
218
221
|
end
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
222
|
+
when DataMapper::Query::Conditions::InclusionComparison
|
223
|
+
if query.model.key.include?(subject)
|
224
|
+
value.each do |val|
|
225
|
+
if @redis.sismember(key_set_for(query.model), val)
|
226
|
+
matched_records << {redis_key_for(query.model) => val}
|
227
|
+
end
|
223
228
|
end
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
if operand.is_a?(DataMapper::Query::Conditions::NotOperation)
|
230
|
-
elsif operand.is_a?(DataMapper::Query::Conditions::InclusionComparison)
|
231
|
-
value.each do |val|
|
232
|
-
find_indexed_matches(subject, val).each do |k|
|
233
|
-
matched_records << {redis_key_for(query.model) => k, "#{subject.name}" => val}
|
229
|
+
elsif subject.respond_to?(:index) && subject.index
|
230
|
+
value.each do |val|
|
231
|
+
find_indexed_matches(subject, val).each do |k|
|
232
|
+
matched_records << {redis_key_for(query.model) => k, "#{subject.name}" => val}
|
233
|
+
end
|
234
234
|
end
|
235
|
+
else
|
236
|
+
search_all_resources(query, operand, subject, matched_records)
|
235
237
|
end
|
236
|
-
|
237
|
-
|
238
|
-
|
238
|
+
when DataMapper::Query::Conditions::EqualToComparison
|
239
|
+
if query.model.key.include?(subject)
|
240
|
+
if @redis.sismember(key_set_for(query.model), value)
|
241
|
+
matched_records << {redis_key_for(query.model) => value}
|
242
|
+
end
|
243
|
+
elsif subject.respond_to?(:index) && subject.index
|
244
|
+
find_indexed_matches(subject, value).each do |k|
|
245
|
+
matched_records << {redis_key_for(query.model) => k, "#{subject.name}" => value}
|
246
|
+
end
|
239
247
|
end
|
248
|
+
else # worst case here, loop through all members, typecast and match
|
249
|
+
search_all_resources(query, operand, subject, matched_records)
|
240
250
|
end
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
251
|
+
matched_records
|
252
|
+
end
|
253
|
+
|
254
|
+
##
|
255
|
+
# Searches through each key :(
|
256
|
+
#
|
257
|
+
# @api private
|
258
|
+
def search_all_resources(query, operand, subject, matched_records)
|
259
|
+
@redis.smembers(key_set_for(query.model)).each do |key|
|
260
|
+
if operand.matches?(subject.typecast(@redis.hget("#{subject.model.storage_name}:#{key}", subject.name)))
|
261
|
+
matched_records << {redis_key_for(query.model) => key}
|
246
262
|
end
|
247
263
|
end
|
248
|
-
matched_records
|
249
264
|
end
|
250
265
|
|
251
266
|
##
|
@@ -38,11 +38,10 @@ describe DataMapper::Adapters::RedisAdapter do
|
|
38
38
|
found.should == [@b,@c,@d]
|
39
39
|
end
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
#end
|
41
|
+
it 'should find Page.all :parent_id.not => @a.id' do
|
42
|
+
found = Page.all :parent_id.not => @a.id
|
43
|
+
found.should == [@a,@d]
|
44
|
+
end
|
46
45
|
|
47
46
|
it 'should find Page.all :parent => @a' do
|
48
47
|
found = Page.all :parent => @a
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DataMapper::Adapters::RedisAdapter do
|
4
|
+
before(:all) do
|
5
|
+
@adapter = DataMapper.setup(:default, {
|
6
|
+
:adapter => "redis",
|
7
|
+
:db => 15
|
8
|
+
})
|
9
|
+
end
|
10
|
+
|
11
|
+
after(:all) do
|
12
|
+
Redis.new(:db => 15).flushdb
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "referential assosciations" do
|
16
|
+
it "should allow the assosciation to go both ways" do
|
17
|
+
class User
|
18
|
+
class Link
|
19
|
+
include DataMapper::Resource
|
20
|
+
|
21
|
+
# the person who is doing the following
|
22
|
+
belongs_to :follower, 'User', :key => true
|
23
|
+
|
24
|
+
# the person who is being followed
|
25
|
+
belongs_to :followed, 'User', :key => true
|
26
|
+
end
|
27
|
+
|
28
|
+
include DataMapper::Resource
|
29
|
+
|
30
|
+
property :id, Serial
|
31
|
+
property :full_name, String, :length => 255, :required => true
|
32
|
+
property :email, String, :length => 320, :required => true
|
33
|
+
|
34
|
+
has n, :links_to_followed_users, 'User::Link', :child_key => [:follower_id]
|
35
|
+
has n, :links_to_followers, 'User::Link', :child_key => [:followed_id]
|
36
|
+
has n, :followed_users, User, :through => :links_to_followed_users, :via => :followed
|
37
|
+
has n, :followers, User, :through => :links_to_followers, :via => :follower
|
38
|
+
end
|
39
|
+
|
40
|
+
DataMapper.finalize
|
41
|
+
|
42
|
+
user1 = User.create(:email => "joe@example.com", :full_name => "joe")
|
43
|
+
user2 = User.create(:email => "bob@example.com", :full_name => "bob")
|
44
|
+
|
45
|
+
user1.followed_users << user2
|
46
|
+
user1.save
|
47
|
+
#user2.links_to_followers.count.should == 1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-redis-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
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: 2012-02-
|
13
|
-
default_executable:
|
12
|
+
date: 2012-02-13 00:00:00.000000000Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: dm-core
|
17
|
-
requirement: &
|
16
|
+
requirement: &70281536321700 !ruby/object:Gem::Requirement
|
18
17
|
none: false
|
19
18
|
requirements:
|
20
19
|
- - ! '>='
|
@@ -22,10 +21,10 @@ dependencies:
|
|
22
21
|
version: 1.2.0
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
|
-
version_requirements: *
|
24
|
+
version_requirements: *70281536321700
|
26
25
|
- !ruby/object:Gem::Dependency
|
27
26
|
name: dm-types
|
28
|
-
requirement: &
|
27
|
+
requirement: &70281536319260 !ruby/object:Gem::Requirement
|
29
28
|
none: false
|
30
29
|
requirements:
|
31
30
|
- - ! '>='
|
@@ -33,10 +32,10 @@ dependencies:
|
|
33
32
|
version: 1.2.0
|
34
33
|
type: :runtime
|
35
34
|
prerelease: false
|
36
|
-
version_requirements: *
|
35
|
+
version_requirements: *70281536319260
|
37
36
|
- !ruby/object:Gem::Dependency
|
38
37
|
name: hiredis
|
39
|
-
requirement: &
|
38
|
+
requirement: &70281536311280 !ruby/object:Gem::Requirement
|
40
39
|
none: false
|
41
40
|
requirements:
|
42
41
|
- - ~>
|
@@ -44,10 +43,10 @@ dependencies:
|
|
44
43
|
version: 0.3.0
|
45
44
|
type: :runtime
|
46
45
|
prerelease: false
|
47
|
-
version_requirements: *
|
46
|
+
version_requirements: *70281536311280
|
48
47
|
- !ruby/object:Gem::Dependency
|
49
48
|
name: redis
|
50
|
-
requirement: &
|
49
|
+
requirement: &70281536305900 !ruby/object:Gem::Requirement
|
51
50
|
none: false
|
52
51
|
requirements:
|
53
52
|
- - ~>
|
@@ -55,7 +54,7 @@ dependencies:
|
|
55
54
|
version: '2.2'
|
56
55
|
type: :runtime
|
57
56
|
prerelease: false
|
58
|
-
version_requirements: *
|
57
|
+
version_requirements: *70281536305900
|
59
58
|
description: DataMapper adapter for the Redis key-value database
|
60
59
|
email: whoahbot@gmail.com
|
61
60
|
executables: []
|
@@ -74,9 +73,9 @@ files:
|
|
74
73
|
- spec/dm_redis_inheritenance_spec.rb
|
75
74
|
- spec/dm_redis_spec.rb
|
76
75
|
- spec/dm_redis_validations_spec.rb
|
76
|
+
- spec/self_referential_spec.rb
|
77
77
|
- spec/spec_helper.rb
|
78
78
|
- spec/textual_keys_spec.rb
|
79
|
-
has_rdoc: true
|
80
79
|
homepage: http://github.com/whoahbot/dm-redis-adapter
|
81
80
|
licenses: []
|
82
81
|
post_install_message:
|
@@ -92,7 +91,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
92
91
|
version: '0'
|
93
92
|
segments:
|
94
93
|
- 0
|
95
|
-
hash:
|
94
|
+
hash: 3387811137579107358
|
96
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
96
|
none: false
|
98
97
|
requirements:
|
@@ -101,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
100
|
version: '0'
|
102
101
|
requirements: []
|
103
102
|
rubyforge_project:
|
104
|
-
rubygems_version: 1.
|
103
|
+
rubygems_version: 1.8.16
|
105
104
|
signing_key:
|
106
105
|
specification_version: 3
|
107
106
|
summary: DataMapper adapter for the Redis key-value database
|
@@ -111,5 +110,6 @@ test_files:
|
|
111
110
|
- spec/dm_redis_inheritenance_spec.rb
|
112
111
|
- spec/dm_redis_spec.rb
|
113
112
|
- spec/dm_redis_validations_spec.rb
|
113
|
+
- spec/self_referential_spec.rb
|
114
114
|
- spec/spec_helper.rb
|
115
115
|
- spec/textual_keys_spec.rb
|