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.
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