dm-redis-adapter 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/README.textile +33 -0
  2. data/lib/dm_redis.rb +64 -21
  3. 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("#{resource.model.to_s.downcase}:#{redis_key_for(resource.model)}:all", resource.key)
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 { |r| r.update(attributes) }
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
- collection.query.filter_records(records_for(collection.query)).each do |record|
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("#{collection.query.model.to_s.downcase}:#{redis_key_for(collection.query.model)}:all", record[redis_key_for(collection.query.model)])
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 [Array]
101
- # An Array of Hashes containing the key-value pairs for
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 key value pair to the redis data store
110
+ # Saves each resource to the redis data store
111
111
  #
112
- # @param [Array] resources
113
- # An array of resources to save
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.attributes.each do |property, value|
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
- query.conditions.operands.select {|o| o.is_a?(DataMapper::Query::Conditions::EqualToComparison) && query.model.key.include?(o.subject)}.each do |o|
138
- if @redis.set_member?("#{query.model.to_s.downcase}:#{redis_key_for(query.model)}:all", o.value)
139
- keys << {"#{redis_key_for(query.model)}" => o.value}
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("#{query.model.to_s.downcase}:#{redis_key_for(query.model)}:all", :limit => [query.offset, query.limit]).each do |val|
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("#{query.model.to_s.downcase}:#{redis_key_for(query.model)}:all").each do |val|
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.7
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-02-04 00:00:00 -08:00
12
+ date: 2010-03-01 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency