dm-redis-adapter 0.0.7 → 0.0.8
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 +33 -0
- data/lib/dm_redis.rb +64 -21
- metadata +2 -2
data/README.textile
CHANGED
@@ -48,6 +48,39 @@ Setup your adapter, define your models and properties:
|
|
48
48
|
|
49
49
|
Now you can use redis in a ORM style, and take advantage of all of the amazing things that DataMapper offers.
|
50
50
|
|
51
|
+
If you want to do finds on specific String fields, add an index:
|
52
|
+
|
53
|
+
<pre>
|
54
|
+
<code>
|
55
|
+
class Coffee
|
56
|
+
include DataMapper::Resource
|
57
|
+
|
58
|
+
property :id, Serial
|
59
|
+
property :description, String, :index => true
|
60
|
+
end
|
61
|
+
|
62
|
+
Coffee.create(:description => "Notes of crude oil and sulphur")
|
63
|
+
Coffee.first(:description => "Notes of crude oil and sulphur") # will now work
|
64
|
+
</code>
|
65
|
+
</pre>
|
66
|
+
|
67
|
+
Validations on unique fields are now supported through indices and dm-validations:
|
68
|
+
|
69
|
+
<pre>
|
70
|
+
<code>
|
71
|
+
class Crumblecake
|
72
|
+
include DataMapper::Resource
|
73
|
+
validates_is_unique :flavor
|
74
|
+
|
75
|
+
property :id, Serial
|
76
|
+
property :flavor, String, :index => true
|
77
|
+
end
|
78
|
+
|
79
|
+
Crumblecake.create(:flavor => "snozzbler")
|
80
|
+
Crumblecake.new(:flavor => "snozzbler").valid? # false (of course! Who ever heard of a snozzbler crumblecake?)
|
81
|
+
</code>
|
82
|
+
</pre>
|
83
|
+
|
51
84
|
h1. Badass contributors
|
52
85
|
|
53
86
|
* <a href="http://github.com/aeden">Anthony Eden (aeden)</a> Gem cleanup, update to jeweler
|
data/lib/dm_redis.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'redis'
|
2
|
+
require "base64"
|
2
3
|
|
3
4
|
module DataMapper
|
4
5
|
module Adapters
|
5
|
-
Extlib::Inflection.word 'redis'
|
6
|
-
|
7
6
|
class RedisAdapter < AbstractAdapter
|
8
7
|
##
|
9
8
|
# Used by DataMapper to put records into the redis data-store: "INSERT" in SQL-speak.
|
@@ -18,9 +17,8 @@ module DataMapper
|
|
18
17
|
def create(resources)
|
19
18
|
resources.each do |resource|
|
20
19
|
initialize_serial(resource, @redis.incr("#{resource.model.to_s.downcase}:#{redis_key_for(resource.model)}:serial"))
|
21
|
-
@redis.set_add(
|
20
|
+
@redis.set_add(key_set_for(resource.model), resource.key)
|
22
21
|
end
|
23
|
-
|
24
22
|
update_attributes(resources)
|
25
23
|
end
|
26
24
|
|
@@ -63,9 +61,9 @@ module DataMapper
|
|
63
61
|
# @api semipublic
|
64
62
|
def update(attributes, collection)
|
65
63
|
attributes = attributes_as_fields(attributes)
|
66
|
-
|
64
|
+
|
67
65
|
records_to_update = records_for(collection.query)
|
68
|
-
records_to_update.each {
|
66
|
+
records_to_update.each {|r| r.update(attributes)}
|
69
67
|
update_attributes(collection)
|
70
68
|
end
|
71
69
|
|
@@ -81,14 +79,17 @@ module DataMapper
|
|
81
79
|
#
|
82
80
|
# @api semipublic
|
83
81
|
def delete(collection)
|
84
|
-
|
82
|
+
records_for(collection.query).each do |record|
|
85
83
|
collection.query.model.properties.each do |p|
|
86
84
|
@redis.delete("#{collection.query.model.to_s.downcase}:#{record[redis_key_for(collection.query.model)]}:#{p.name}")
|
87
85
|
end
|
88
|
-
@redis.set_delete(
|
86
|
+
@redis.set_delete(key_set_for(collection.query.model), record[redis_key_for(collection.query.model)])
|
87
|
+
collection.query.model.properties.select {|p| p.index}.each do |p|
|
88
|
+
@redis.set_delete("#{collection.query.model.to_s.downcase}:#{p.name}:#{encode(record[p.name])}", record[redis_key_for(collection.query.model)])
|
89
|
+
end
|
89
90
|
end
|
90
91
|
end
|
91
|
-
|
92
|
+
|
92
93
|
private
|
93
94
|
|
94
95
|
##
|
@@ -97,9 +98,8 @@ module DataMapper
|
|
97
98
|
# @param [DataMapper::Model] model
|
98
99
|
# The query used to locate the resources to be deleted.
|
99
100
|
#
|
100
|
-
# @return [
|
101
|
-
#
|
102
|
-
# each record
|
101
|
+
# @return [String]
|
102
|
+
# A string representation of the string key for this model
|
103
103
|
#
|
104
104
|
# @api private
|
105
105
|
def redis_key_for(model)
|
@@ -107,15 +107,19 @@ module DataMapper
|
|
107
107
|
end
|
108
108
|
|
109
109
|
##
|
110
|
-
# Saves each
|
110
|
+
# Saves each resource to the redis data store
|
111
111
|
#
|
112
|
-
# @param [Array]
|
113
|
-
# An array of
|
112
|
+
# @param [Array] Resources
|
113
|
+
# An array of resource to save
|
114
114
|
#
|
115
115
|
# @api private
|
116
116
|
def update_attributes(resources)
|
117
117
|
resources.each do |resource|
|
118
|
-
resource.
|
118
|
+
resource.model.properties.select {|p| p.index}.each do |property|
|
119
|
+
@redis.set_add("#{resource.model.to_s.downcase}:#{property.name}:#{encode(resource[property.name.to_s])}", resource.key)
|
120
|
+
end
|
121
|
+
|
122
|
+
resource.attributes(:field).each do |property, value|
|
119
123
|
next if resource.key.include?(property)
|
120
124
|
@redis["#{resource.model.to_s.downcase}:#{resource.key}:#{property}"] = value unless value.nil?
|
121
125
|
end
|
@@ -134,21 +138,30 @@ module DataMapper
|
|
134
138
|
# @api private
|
135
139
|
def records_for(query)
|
136
140
|
keys = []
|
137
|
-
|
138
|
-
|
139
|
-
|
141
|
+
|
142
|
+
query.conditions.operands.select {|o| o.is_a?(DataMapper::Query::Conditions::EqualToComparison)}.each do |o|
|
143
|
+
if query.model.key.include?(o.subject)
|
144
|
+
if @redis.set_member?(key_set_for(query.model), o.value)
|
145
|
+
keys << {"#{redis_key_for(query.model)}" => o.value}
|
146
|
+
end
|
147
|
+
return keys
|
140
148
|
end
|
149
|
+
find_matches(query, o).each do |k|
|
150
|
+
keys << {"#{redis_key_for(query.model)}" => k, "#{o.subject.name}" => o.value}
|
151
|
+
end
|
152
|
+
return keys
|
141
153
|
end
|
142
154
|
|
143
155
|
if query.limit
|
144
|
-
@redis.sort(
|
156
|
+
@redis.sort(key_set_for(query.model), :limit => [query.offset, query.limit]).each do |val|
|
145
157
|
keys << {"#{redis_key_for(query.model)}" => val.to_i}
|
146
158
|
end
|
159
|
+
return keys
|
147
160
|
end
|
148
161
|
|
149
162
|
# Keys are empty, fall back and load all the values for this model
|
150
163
|
if keys.empty?
|
151
|
-
@redis.set_members(
|
164
|
+
@redis.set_members(key_set_for(query.model)).each do |val|
|
152
165
|
keys << {"#{redis_key_for(query.model)}" => val.to_i}
|
153
166
|
end
|
154
167
|
end
|
@@ -156,6 +169,36 @@ module DataMapper
|
|
156
169
|
keys
|
157
170
|
end
|
158
171
|
|
172
|
+
##
|
173
|
+
# Return the key string for the set that contains all keys for a particular resource
|
174
|
+
#
|
175
|
+
# @return String
|
176
|
+
# The string key for the :all set
|
177
|
+
# @api private
|
178
|
+
def key_set_for(model)
|
179
|
+
"#{model.to_s.downcase}:#{redis_key_for(model)}:all"
|
180
|
+
end
|
181
|
+
|
182
|
+
##
|
183
|
+
# Find a matching entry for a query
|
184
|
+
#
|
185
|
+
# @return [Array]
|
186
|
+
# Array of id's of all members matching the query
|
187
|
+
# @api private
|
188
|
+
def find_matches(query, operand)
|
189
|
+
@redis.set_members("#{query.model.to_s.downcase}:#{operand.subject.name}:#{encode(operand.value)}")
|
190
|
+
end
|
191
|
+
|
192
|
+
##
|
193
|
+
# Base64 encode a value as a string key for an index
|
194
|
+
#
|
195
|
+
# @return String
|
196
|
+
# Base64 representation of a value
|
197
|
+
# @api private
|
198
|
+
def encode(value)
|
199
|
+
Base64.encode64(value.to_s).gsub("\n", "")
|
200
|
+
end
|
201
|
+
|
159
202
|
##
|
160
203
|
# Make a new instance of the adapter. The @redis ivar is the 'data-store'
|
161
204
|
# for this adapter.
|
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.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Herrera
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-03-01 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|