public
Description: DataMapper Adapters
Homepage: http://www.yehudakatz.com
Clone URL: git://github.com/wycats/dm-adapters.git
Working Salesforce adapter against DM trunk. TODO: DRY up read_*
wycats (author)
Sun Jun 15 01:29:33 -0700 2008
commit  91df8fd2f8b0f4ca57becb6cc4361bdda1917a3f
tree    516229ac3ca0ba9b3490f62e62ac77bec5f58a72
parent  c28d2f2e001d7df2ae087edbb988c38a5b9ecd20
...
131
132
133
134
 
135
136
137
...
141
142
143
144
145
 
 
 
 
 
146
147
148
 
 
 
 
149
150
151
152
153
154
155
156
157
 
158
159
160
 
 
 
 
 
161
162
 
 
 
 
163
164
 
 
 
 
 
165
166
167
168
 
 
 
 
 
169
170
 
 
 
 
 
 
 
 
 
 
 
 
171
172
173
 
 
 
 
 
 
 
 
 
 
 
174
175
176
177
 
 
 
 
 
 
 
 
178
179
180
181
 
 
182
183
 
 
184
185
186
187
188
189
 
 
190
191
192
193
 
 
 
194
195
196
197
198
199
 
 
200
201
202
...
131
132
133
 
134
135
136
137
...
141
142
143
 
 
144
145
146
147
148
149
 
 
150
151
152
153
154
 
 
 
 
 
 
 
 
155
156
 
 
157
158
159
160
161
162
 
163
164
165
166
167
 
168
169
170
171
172
173
 
 
 
174
175
176
177
178
179
 
180
181
182
183
184
185
186
187
188
189
190
191
192
193
 
194
195
196
197
198
199
200
201
202
203
204
205
206
 
 
207
208
209
210
211
212
213
214
215
 
 
 
216
217
218
 
219
220
221
222
223
224
 
 
225
226
227
 
 
 
228
229
230
231
232
233
234
 
 
235
236
237
238
239
0
@@ -131,7 +131,7 @@ module DataMapper
0
         
0
           results.each do |result|
0
             props = properties_with_indexes.inject([]) do |accum, (prop, idx)|
0
- accum[idx] = result.send(soap_attr(prop))
0
+ accum[idx] = result.send(soap_attr(prop, repository))
0
               accum
0
             end
0
             set.load(props)
0
@@ -141,62 +141,99 @@ module DataMapper
0
       end
0
       
0
       def read_one(query)
0
- read_many(query).first
0
- end
0
+ repository = query.repository
0
+ properties = query.fields
0
+ properties_with_indexes = Hash[*properties.zip((0...properties.size).to_a).flatten]
0
+
0
+ conditions = query.conditions.map {|c| SQL.from_condition(c, repository)}.compact.join(") AND (")
0
       
0
- def update(repository, resource)
0
- properties = resource.dirty_attributes
0
+ query_string = "SELECT #{query.fields.map {|f| f.field}.join(", ")} from #{query.model.storage_name(repository.name)}"
0
+ query_string << " WHERE (#{conditions})" unless conditions.empty?
0
+ query_string << " ORDER BY #{SQL.order(query.order[0])}" unless query.order.empty?
0
+ query_string << " LIMIT #{query.limit}" if query.limit
0
 
0
- if properties.empty?
0
- return false
0
- else
0
- obj = make_sforce_obj(resource, properties, resource.key.first)
0
- result = @connection.update([obj])
0
- result[0].success == true
0
- end
0
- end
0
+ DataMapper.logger.debug query_string
0
       
0
- def create(repository, resource)
0
- properties = resource.dirty_attributes
0
+ begin
0
+ results = @connection.query(:queryString => query_string).result
0
+ rescue SOAP::FaultError => e
0
+ raise SalesforceAPI::ReadError, e.message
0
+ end
0
         
0
- obj = make_sforce_obj(resource, properties, nil)
0
+ results = results.size > 0 ? results.records : []
0
+
0
+ result = results.first
0
+ return nil unless result
0
         
0
- results = @connection.create([obj])
0
+ props = properties_with_indexes.inject([]) do |accum, (prop, idx)|
0
+ accum[idx] = result.send(soap_attr(prop, repository))
0
+ accum
0
+ end
0
+ return query.model.load(props, query)
0
         
0
- if results[0].success
0
- key = resource.class.key(repository.name).first
0
- resource.instance_variable_set(key.instance_variable_name, results[0].id)
0
+ end
0
+
0
+ def update(attributes, query)
0
+ arr = if key_condition = query.conditions.find {|op,prop,val| prop.key?}
0
+ [ make_sforce_obj(query, attributes, key_condition.last) ]
0
         else
0
- raise SalesforceAPI::CreateError, results[0].errors.map {|e| "#{e.statusCode}: #{e.message}"}.join(", ")
0
+ read_many(query).map do |obj|
0
+ obj = make_salesforce_obj(query, attributes, x.key)
0
+ end
0
+ end
0
+ results = @connection.update(arr)
0
+ results.select {|r| r.success == true}.size
0
+ end
0
+
0
+ def create(resources)
0
+ map = {}
0
+ arr = resources.map do |resource|
0
+ obj = make_sforce_obj(resource, resource.dirty_attributes, nil)
0
         end
0
         
0
- true
0
+ @connection.create(arr).each_with_index do |result, i|
0
+ if result.success
0
+ resource = resources[i]
0
+ key = resource.class.key(repository.name).first
0
+ resource.instance_variable_set(key.instance_variable_name, result.id)
0
+ else
0
+ raise SalesforceAPI::CreateError,
0
+ results.errors.map {|e| "#{e.statusCode}: #{e.message}"}.join(", ")
0
+ end
0
+ end.size
0
+
0
       end
0
       
0
- def delete(repository, resource)
0
- key = resource.key.first
0
+ def delete(query)
0
+ keys = if key_condition = query.conditions.find {|op,prop,val| prop.key?}
0
+ [key_condition.last]
0
+ else
0
+ query.read_many.map {|r| r.key}
0
+ end
0
+
0
+ results = @connection.delete(keys)
0
         
0
- results = @connection.delete([key])
0
- if results[0].success
0
- true
0
+ if results.all? {|r| r.success}
0
+ results.size
0
         else
0
- raise SalesforceAPI::DeleteError, results[0].errors.map {|e| "#{e.statusCode}: #{e.message}"}.join(", ")
0
+ raise SalesforceAPI::DeleteError,
0
+ results.find {|r| r.success == false}.errors.map {|e| "#{e.statusCode}: #{e.message}"}.join(", ")
0
         end
0
       end
0
       
0
       private
0
- def make_sforce_obj(resource, props, key = nil)
0
- klass = SalesforceAPI.const_get(resource.class.storage_name(resource.repository.name))
0
+ def make_sforce_obj(query, attrs, key = nil)
0
+ klass = SalesforceAPI.const_get(query.model.storage_name(query.repository.name))
0
         obj = klass.new
0
- obj.id = key if key
0
- props.each do |prop|
0
- obj.send("#{soap_attr(prop)}=", resource.instance_variable_get(prop.instance_variable_name))
0
+ obj.id = query.conditions.find {|op,prop,val| prop.key?}.last if key
0
+ attrs.each do |prop,val|
0
+ obj.send("#{soap_attr(prop, query.repository)}=", val)
0
         end
0
         obj
0
       end
0
       
0
- def soap_attr(prop)
0
- prop.field.gsub(/^[A-Z]/) {|m| m.downcase}
0
+ def soap_attr(prop, repository)
0
+ prop.field(repository.name).gsub(/^[A-Z]/) {|m| m.downcase}
0
       end
0
       
0
     end

Comments

    No one has commented yet.