datamapper4rails 0.3.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.
Files changed (38) hide show
  1. data/History.txt +6 -0
  2. data/Manifest.txt +37 -0
  3. data/README.txt +151 -0
  4. data/Rakefile +48 -0
  5. data/datamapper_rails_templates.rb +114 -0
  6. data/generators/datamapper_install/datamapper_install_generator.rb +12 -0
  7. data/generators/datamapper_install/templates/datamapper.rake +88 -0
  8. data/generators/datamapper_model/datamapper_model_generator.rb +18 -0
  9. data/generators/datamapper_model/templates/migration.rb +18 -0
  10. data/generators/datamapper_model/templates/model.rb +14 -0
  11. data/generators/datamapper_rspec_model/datamapper_rspec_model_generator.rb +18 -0
  12. data/generators/datamapper_rspec_model/templates/model_spec.rb +44 -0
  13. data/generators/datamapper_rspec_scaffold/datamapper_rspec_scaffold_generator.rb +20 -0
  14. data/generators/datamapper_rspec_scaffold/templates/controller_spec.rb +171 -0
  15. data/generators/datamapper_rspec_scaffold/templates/edit_erb_spec.rb +25 -0
  16. data/generators/datamapper_scaffold/datamapper_scaffold_generator.rb +31 -0
  17. data/generators/datamapper_scaffold/templates/controller.rb +90 -0
  18. data/generators/datamapper_scaffold/templates/functional_test.rb +49 -0
  19. data/generators/datamapper_scaffold/templates/view_edit.html.erb +18 -0
  20. data/generators/datamapper_scaffold/templates/view_index.html.erb +24 -0
  21. data/generators/datamapper_scaffold/templates/view_new.html.erb +17 -0
  22. data/generators/datamapper_scaffold/templates/view_show.html.erb +10 -0
  23. data/lib/datamapper4rails.rb +14 -0
  24. data/lib/datamapper4rails/adapters/base_adapter.rb +198 -0
  25. data/lib/datamapper4rails/adapters/restful_adapter.rb +320 -0
  26. data/lib/datamapper4rails/datamapper_store.rb +28 -0
  27. data/lib/datamapper4rails/identity_maps.rb +25 -0
  28. data/lib/datamapper4rails/integration_test.rb +45 -0
  29. data/lib/datamapper4rails/overlay.rb +69 -0
  30. data/lib/datamapper4rails/preload_models.rb +26 -0
  31. data/lib/datamapper4rails/restful_transactions.rb +43 -0
  32. data/lib/datamapper4rails/rspec.rb +8 -0
  33. data/lib/datamapper4rails/rspec_default_values.rb +23 -0
  34. data/lib/datamapper4rails/version.rb +3 -0
  35. data/spec/datamapper_store_spec.rb +23 -0
  36. data/spec/spec.opts +1 -0
  37. data/spec/spec_helper.rb +34 -0
  38. metadata +124 -0
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+
3
+ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
4
+ test "should get index" do
5
+ get :index
6
+ assert_response :success
7
+ assert_not_nil assigns(:<%= table_name %>)
8
+ end
9
+
10
+ test "should get new" do
11
+ get :new
12
+ assert_response :success
13
+ end
14
+
15
+ test "should create <%= file_name %>" do
16
+ assert_difference('<%= class_name %>.all.size') do
17
+ post :create, :<%= file_name %> => {
18
+ <% attributes.each_with_index do |attribute, attribute_index| -%>
19
+ :<%= attribute.name %> => <%= attribute.default_value %><%= attribute_index == attributes.length - 1 ? '' : ','%>
20
+ <% end -%>
21
+ }
22
+ end
23
+
24
+ assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>).key)
25
+ end
26
+
27
+ test "should show <%= file_name %>" do
28
+ get :show, :id => <%= table_name %>(:one).to_param
29
+ assert_response :success
30
+ end
31
+
32
+ test "should get edit" do
33
+ get :edit, :id => <%= table_name %>(:one).to_param
34
+ assert_response :success
35
+ end
36
+
37
+ test "should update <%= file_name %>" do
38
+ put :update, :id => <%= table_name %>(:one).to_param, :<%= file_name %> => { }
39
+ assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>).key)
40
+ end
41
+
42
+ test "should destroy <%= file_name %>" do
43
+ assert_difference('<%= class_name %>.all.size', -1) do
44
+ delete :destroy, :id => <%= table_name %>(:one).to_param
45
+ end
46
+
47
+ assert_redirected_to <%= table_name %>_path
48
+ end
49
+ end
@@ -0,0 +1,18 @@
1
+ <h1>Editing <%= singular_name %></h1>
2
+
3
+ <%% form_for(:<%= singular_name %>, :url => <%= singular_name %>_path(@<%= singular_name %>.key), :html => {:method => :put}) do |f| %>
4
+ <%%= f.error_messages %>
5
+
6
+ <% for attribute in attributes -%>
7
+ <p>
8
+ <%%= f.label :<%= attribute.name %> %><br />
9
+ <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
10
+ </p>
11
+ <% end -%>
12
+ <p>
13
+ <%%= f.submit 'Update' %>
14
+ </p>
15
+ <%% end %>
16
+
17
+ <%%= link_to 'Show', <%= singular_name %>_path(@<%= singular_name %>.key) %> |
18
+ <%%= link_to 'Back', <%= plural_name %>_path %>
@@ -0,0 +1,24 @@
1
+ <h1>Listing <%= plural_name %></h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <% for attribute in attributes -%>
6
+ <th><%= attribute.column.human_name %></th>
7
+ <% end -%>
8
+ </tr>
9
+
10
+ <%% @<%= plural_name %>.each do |<%= singular_name %>| %>
11
+ <tr>
12
+ <% for attribute in attributes -%>
13
+ <td><%%=h <%= singular_name %>.<%= attribute.name %> %></td>
14
+ <% end -%>
15
+ <td><%%= link_to 'Show', <%= singular_name %>_path(<%= singular_name %>.key) %></td>
16
+ <td><%%= link_to 'Edit', edit_<%= singular_name %>_path(<%= singular_name %>.key) %></td>
17
+ <td><%%= link_to 'Destroy', <%= singular_name %>_path(<%= singular_name %>.key), :confirm => 'Are you sure?', :method => :delete %></td>
18
+ </tr>
19
+ <%% end %>
20
+ </table>
21
+
22
+ <br />
23
+
24
+ <%%= link_to 'New <%= singular_name %>', new_<%= singular_name %>_path %>
@@ -0,0 +1,17 @@
1
+ <h1>New <%= singular_name %></h1>
2
+
3
+ <%% form_for(@<%= singular_name %>) do |f| %>
4
+ <%%= f.error_messages %>
5
+
6
+ <% for attribute in attributes -%>
7
+ <p>
8
+ <%%= f.label :<%= attribute.name %> %><br />
9
+ <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
10
+ </p>
11
+ <% end -%>
12
+ <p>
13
+ <%%= f.submit 'Create' %>
14
+ </p>
15
+ <%% end %>
16
+
17
+ <%%= link_to 'Back', <%= plural_name %>_path %>
@@ -0,0 +1,10 @@
1
+ <% for attribute in attributes -%>
2
+ <p>
3
+ <b><%= attribute.column.human_name %>:</b>
4
+ <%%=h @<%= singular_name %>.<%= attribute.name %> %>
5
+ </p>
6
+
7
+ <% end -%>
8
+
9
+ <%%= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>.key) %> |
10
+ <%%= link_to 'Back', <%= plural_name %>_path %>
@@ -0,0 +1,14 @@
1
+ require 'rails_datamapper'
2
+ require 'rack-datamapper'
3
+ require 'datamapper4rails/datamapper_store'
4
+
5
+ # keep this here until rails_datamapper has it included
6
+ module DataMapper
7
+ module Validate
8
+ class ValidationErrors
9
+ def count
10
+ size
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,198 @@
1
+ require 'dm-core'
2
+ require 'slf4r'
3
+
4
+ module DataMapper
5
+ module Adapters
6
+ class NoopTransaction
7
+
8
+ def close ; end
9
+ def begin ; end
10
+ def prepare ; end
11
+ def commit ; end
12
+ def rollback ; end
13
+ def rollback_prepared ; end
14
+
15
+ end
16
+ class BaseAdapter < AbstractAdapter
17
+
18
+ include Slf4r::Logger
19
+
20
+ # @see AbstractAdapter
21
+ def transaction_primitive
22
+ NoopTransaction.new
23
+ end
24
+
25
+ def initialize(name, uri_or_options)
26
+ super(name, uri_or_options)
27
+ end
28
+
29
+ protected
30
+
31
+ # checks whether a given resource fullfils the conditions
32
+ # @param [DataMapper::Resource] resource
33
+ # @param [Array<Condition>] conditions
34
+ # @return [Boolean]
35
+ # true if the resource are within the conditions otherwise false
36
+ def filter_resource(resource, conditions)
37
+ #puts "condi"
38
+ #p conditions
39
+ # no conditation => no filter
40
+ if conditions.size == 0
41
+ true
42
+ else
43
+ conditions.all? do |tuple|
44
+ operator, property, bind_value = *tuple
45
+
46
+ value = property.get!(resource)
47
+ case operator
48
+ when :eql, :in then equality_comparison(bind_value, value)
49
+ when :not then !equality_comparison(bind_value, value)
50
+ when :like then Regexp.new(bind_value.gsub(/%/, ".*")) =~ value
51
+ when :gt then !value.nil? && value > bind_value
52
+ when :gte then !value.nil? && value >= bind_value
53
+ when :lt then !value.nil? && value < bind_value
54
+ when :lte then !value.nil? && value <= bind_value
55
+ else raise "Invalid query operator: #{operator.inspect}"
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ # helper method to dispatch the equality test for different
62
+ # classes
63
+ def equality_comparison(bind_value, value)
64
+ case bind_value
65
+ when Array, Range then bind_value.include?(value)
66
+ when NilClass then value.nil?
67
+ else bind_value == value
68
+ end
69
+ end
70
+
71
+ public
72
+
73
+ # @see AbstractAdapter
74
+ # @param [Array<DataMapper::Resources>] resources
75
+ # aaaa
76
+ # @return [Fixnum]
77
+ # number of the newly created resources
78
+ def create(resources)
79
+ resources.select do |resource|
80
+
81
+ create_resource(resource)
82
+
83
+ end.size # just return the number of create resources
84
+ end
85
+
86
+ # @see AbstractAdapter
87
+ # @param [Hash] attributes
88
+ # collection of attribute, i.e. the name/value pairs which
89
+ # needs to be updated
90
+ # @param [Query]
91
+ # on all resources which are selected by that query the
92
+ # update will be applied
93
+ # @return [Fixnum]
94
+ # number of the updated resources
95
+ def update(attributes, query)
96
+ read_many(query).select do |resource|
97
+
98
+ update_resource(resource, attributes)
99
+
100
+ end.size
101
+ end
102
+
103
+ # @see AbstractAdapter
104
+ # @param [DataMapper::Query] query
105
+ # which selects the resource
106
+ # @return [DataMapper::Resource]
107
+ # the found Resource or nil
108
+ def read_one(query)
109
+ result = read_resource(query)
110
+ if result.is_a? Resource
111
+ result
112
+ elsif result # assume result to be Array with the values
113
+ #puts "------------------"
114
+ #p result
115
+ query.model.load(result, query)
116
+ end
117
+ end
118
+
119
+ # @see AbstractAdapter
120
+ # @param [DataMapper::Query] query
121
+ # which selects the resources
122
+ # @return [DataMapper::Collection]
123
+ # collection of Resources
124
+ def read_many(query)
125
+ Collection.new(query) do |set|
126
+ result = read_resources(query)
127
+ #puts "read_many"
128
+ #p result
129
+ if result.size > 0 and result.first.is_a? Resource
130
+ set.replace(result)
131
+ else
132
+ result.each do |values|
133
+ set.load(values)
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ # @see AbstractAdapter
140
+ # @param [Query] query
141
+ # which selects the resources to be deleted
142
+ # @return [Fixnum]
143
+ # number of the deleted resources
144
+ def delete(query)
145
+ read_many(query).each do |resource|
146
+
147
+ delete_resource(resource)
148
+
149
+ end.size
150
+ end
151
+
152
+ private
153
+
154
+ # @param [DataMapper::Resource] resource
155
+ # which will be created
156
+ # @return [DataMapper::Resource]
157
+ # either the resource itself if the creation was successful or nil
158
+ def create_resource(resource)
159
+ raise NotImplementedError.new
160
+ end
161
+
162
+ # @param [DataMapper::Query] query
163
+ # which selects the resource
164
+ # @return [DataMapper::Resource,Array<String>]
165
+ # the resource or a set of values ordered in the same manner as query.fields attributes
166
+ def read_resource(query)
167
+ raise NotImplementedError.new
168
+ end
169
+
170
+ # @param [DataMapper::Query] query
171
+ # which selects the resources
172
+ # @return [Array<DataMapper::Resource>,Array<String>]
173
+ # resources or ordered values
174
+ # @see #read_resource
175
+ def read_resources(query)
176
+ raise NotImplementedError.new
177
+ end
178
+
179
+ # @param [DataMapper::Resource] resource
180
+ # which will be updated with the given attributes.
181
+ # @param [Hash] attributes
182
+ # the keys are the property names and the values are the new values of that property.
183
+ # @return [DataMapper::Resource]
184
+ # resource on success otherwise nil
185
+ def update_resource(resource, attributes)
186
+ raise NotImplementedError.new
187
+ end
188
+
189
+ # @param [DataMapper::Resource] resource
190
+ # which will be deleted
191
+ # @return [DataMapper::Resource]
192
+ # either the resource if the deletion was successful or nil
193
+ def delete_resource(resource)
194
+ raise NotImplementedError.new
195
+ end
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,320 @@
1
+ require 'datamapper4rails/adapters/base_adapter'
2
+ require 'net/http'
3
+ require 'extlib/inflection'
4
+ require 'extlib/module'
5
+ require 'dm-serializer'
6
+
7
+ module DataMapper
8
+ module Adapters
9
+ class RestfulAdapter < BaseAdapter
10
+
11
+ include ::Slf4r::Logger
12
+
13
+ def resource_name_from_model(model)
14
+ ::Extlib::Inflection.underscore(model.name)
15
+ end
16
+
17
+ def resource_name_from_query(query)
18
+ resource_name_from_model(query.model)
19
+ end
20
+
21
+ def keys_from_query(query)
22
+ keys = query.model.key
23
+ # work around strange missing of properties in model
24
+ # but the query has still the fields :P
25
+ if keys.size == 0
26
+ query.fields.select do |f|
27
+ f.key?
28
+ end
29
+ else
30
+ keys
31
+ end
32
+ end
33
+
34
+ def key_value_from_query(query)
35
+ keys = keys_from_query(query)
36
+ logger.debug { "keys=#{keys.inspect}" }
37
+ if keys.size == 1
38
+ key = keys[0]
39
+ # return the third element of the condition array
40
+ # which belongs to the key
41
+ query.conditions.detect do |c|
42
+ c[1] == key
43
+ end[2]
44
+ else
45
+ raise "compound keys are not supported"
46
+ end
47
+ end
48
+
49
+ def single_entity_query?(query)
50
+ query.conditions.count {|c| c[1].key? and c[0] == :eql} == query.model.key.size
51
+ end
52
+
53
+ def attributes_to_xml(name, attributes)
54
+ xml = "<#{name}>"
55
+ attributes.each do |attr, val|
56
+ xml += "<#{attr.name}>#{val}</#{attr.name}>"
57
+ end
58
+ xml += "</#{name}>"
59
+ end
60
+
61
+ def http_get(uri)
62
+ send_request do |http|
63
+ request = Net::HTTP::Get.new(uri)
64
+ request.basic_auth(@uri[:login],
65
+ @uri[:password]) unless @uri[:login].blank?
66
+ http.request(request)
67
+ end
68
+ end
69
+
70
+ def http_post(uri, data = nil)
71
+ send_request do |http|
72
+ request = Net::HTTP::Post.new(uri, {
73
+ 'content-type' => 'application/xml',
74
+ 'content-length' => data.length.to_s
75
+ })
76
+ request.basic_auth(@uri[:login],
77
+ @uri[:password]) unless @uri[:login].blank?
78
+ http.request(request, data)
79
+ end
80
+ end
81
+
82
+ def http_put(uri, data = nil)
83
+ send_request do |http|
84
+ request = Net::HTTP::Put.new(uri, {
85
+ 'content-type' => 'application/xml',
86
+ 'content-length' => data.length.to_s
87
+ })
88
+ request.basic_auth(@uri[:login],
89
+ @uri[:password]) unless @uri[:login].blank?
90
+ # request.set_form_data(data)
91
+ http.request(request, data)
92
+ end
93
+ end
94
+
95
+ def http_delete(uri)
96
+ send_request do |http|
97
+ request = Net::HTTP::Delete.new(uri)
98
+ request.basic_auth(@uri[:login],
99
+ @uri[:password]) unless @uri[:login].blank?
100
+ http.request(request)
101
+ end
102
+ end
103
+
104
+ def send_request(&block)
105
+ res = nil
106
+ Net::HTTP.start(@uri[:host], @uri[:port].to_i) do |http|
107
+ res = yield(http)
108
+ end
109
+ logger.debug { "response=" + res.code }
110
+ res
111
+ end
112
+
113
+ def parse_resource(xml, model, query = nil)
114
+ elements = {}
115
+ associations = {}
116
+ many_to_many = {}
117
+ xml.elements.collect do |element|
118
+ if element.text.nil?
119
+ if element.attributes['type'] == 'array'
120
+ many_to_many[element.name.gsub('-','_').to_sym] = element
121
+ else
122
+ associations[element.name.gsub('-','_').to_sym] = element
123
+ end
124
+ else
125
+ elements[element.name.gsub('-','_').to_sym] = element.text
126
+ end
127
+ end
128
+ #puts
129
+ #puts "elements"
130
+ #p elements
131
+ #p query
132
+ #p model.properties
133
+ props = model.properties.length == 0 ? query.fields : model.properties
134
+ #p props
135
+ resource = model.load(props.collect do |f| #model.properties.collect do |f|
136
+ elements[f.name]
137
+ end, query)
138
+ #p resource
139
+ #p query
140
+ resource.send("#{keys_from_query(query)[0].name}=".to_sym, elements[keys_from_query(query)[0].name] )
141
+ #p resource
142
+ #p associations
143
+ associations.each do |name, association|
144
+ # puts "asso"
145
+ # p model
146
+ # p name
147
+ # p association
148
+ #p model.relationships
149
+ is_one_to_one = false
150
+ asso_model =
151
+ if rel = model.relationships[name]
152
+ #puts "rel"
153
+ #p rel
154
+ if rel.child_model == model
155
+ rel.parent_model
156
+ else
157
+ rel.child_model
158
+ end
159
+ # else
160
+ #::Extlib::Inflection.constantize(::Extlib::Inflection.classify(name))
161
+ # model.find_const(::Extlib::Inflection.classify(name))
162
+ end
163
+ # p asso_model
164
+ if resource.respond_to? "#{name}=".to_sym
165
+ # puts
166
+ # puts "association"
167
+ # puts name
168
+ # p model
169
+ # p asso_model
170
+ resource.send("#{name}=".to_sym,
171
+ parse_resource(association, asso_model,
172
+ ::DataMapper::Query.new(query.repository, asso_model ))) unless asso_model.nil?
173
+ else
174
+ resource.send("#{name.to_s.pluralize}".to_sym).send(:<<,
175
+ parse_resource(association, asso_model,
176
+ ::DataMapper::Query.new(query.repository, asso_model ))) unless asso_model.nil?
177
+ end
178
+ end
179
+
180
+ #puts "many 2 many"
181
+ #p many_to_many
182
+ many_to_many.each do |name, many|
183
+ if model.relationships[name]
184
+ # TODO
185
+ puts "TODO"
186
+ else
187
+ # p ::Extlib::Inflection.classify(name.to_s.singularize)
188
+ many_model = Object.const_get(::Extlib::Inflection.classify(name.to_s.singularize))
189
+ #p resource
190
+ #p many_model
191
+ #puts "many"
192
+ #p(parse_resource(many, many_model,
193
+ # ::DataMapper::Query.new(query.repository, many_model ))) unless many_model.nil?
194
+ set = resource.send(name)
195
+ # p set
196
+ many.elements.each do |element|
197
+ set << parse_resource(element, many_model,
198
+ ::DataMapper::Query.new(query.repository, many_model ))
199
+ end unless many_model.nil?
200
+ # p set
201
+ end
202
+ end
203
+ resource.instance_variable_set(:@new_record, false)
204
+ #p resource
205
+ resource
206
+ end
207
+
208
+ # @see BaseAdapter
209
+ def create_resource(resource)
210
+ name = resource.model.name
211
+ uri = "/#{name.pluralize}.xml"
212
+ logger.debug { "post #{uri}" }
213
+ response = http_post(uri, resource.to_xml )
214
+ logger.debug { response.body.to_s }
215
+ resource_new = parse_resource(REXML::Document::new(response.body).root,
216
+ resource.model,
217
+ ::DataMapper::Query.new(resource.repository,
218
+ resource.model ))
219
+
220
+ # copy all attributes/associations from the downloaded resource
221
+ # to the given resource
222
+ # TODO better pass the given resource into parse_resource
223
+ resource_new.attributes.each do |key, value|
224
+ resource.send(:properties)[key].set!(resource, value)
225
+ end
226
+ resource_new.send(:relationships).each do |key, value|
227
+ resource.send("#{key}=".to_sym, resource_new.send(key))
228
+ end
229
+ resource_new
230
+ end
231
+
232
+ # @see BaseAdapter
233
+ def read_resource(query)
234
+ key = key_value_from_query(query)
235
+ uri = "/#{resource_name_from_query(query).pluralize}/#{key}.xml"
236
+ logger.debug { "get #{uri}" }
237
+ response = http_get(uri)
238
+ if response.kind_of?(Net::HTTPSuccess)
239
+ logger.debug { response.body.to_s }
240
+ parse_resource(REXML::Document::new(response.body).root,
241
+ query.model,
242
+ query)
243
+ else
244
+ #TODO may act on different response codes differently
245
+ end
246
+ end
247
+
248
+ # @see BaseAdapter
249
+ def read_resources(query)
250
+ if single_entity_query?(query)
251
+ [read_resource(query)]
252
+ else
253
+ uri = "/#{resource_name_from_query(query).pluralize}.xml"
254
+ logger.debug { "get #{uri}" }
255
+ response = http_get(uri)
256
+ if response.kind_of?(Net::HTTPSuccess)
257
+ result = []
258
+ logger.debug { response.body.to_s }
259
+ REXML::Document::new(response.body).root.each do |element|
260
+ result << parse_resource(element,
261
+ query.model,
262
+ query)
263
+ end
264
+ result
265
+ else
266
+ #TODO may act on different response codes differently
267
+ end
268
+ end
269
+ end
270
+
271
+ # @overwrite BaseAdapter
272
+ def update(attributes, query)
273
+ if query.limit == 1 or single_entity_query?(query)
274
+ xml = attributes_to_xml(resource_name_from_query(query), attributes)
275
+ key = key_value_from_query(query)
276
+ uri = "/#{resource_name_from_query(query).pluralize}/#{key}.xml"
277
+ logger.debug { "put #{uri}" }
278
+ response = http_put(uri, xml)
279
+ response.kind_of?(Net::HTTPSuccess)
280
+ else
281
+ super
282
+ end
283
+ end
284
+
285
+ # @see BaseAdapter
286
+ def update_resource(resource, attributes)
287
+ query = resource.to_query
288
+ xml = attributes_to_xml(resource.name, attributes)
289
+ key = key_value_from_query(query)
290
+ logger.debug {resource.to_xml}
291
+ response = http_put("/#{resource_name_from_query(query).pluralize}/#{key}.xml", xml)
292
+ response.kind_of?(Net::HTTPSuccess)
293
+ end
294
+
295
+ # @overwrite BaseAdapter
296
+ def delete(query)
297
+ if query.limit == 1 or single_entity_query?(query)
298
+ name = resource_name_from_query(query)
299
+ key = key_value_from_query(query)
300
+ uri = "/#{name.pluralize}/#{key}.xml"
301
+ logger.debug { "delete #{uri}" }
302
+ response = http_delete(uri)
303
+ response.kind_of?(Net::HTTPSuccess)
304
+ else
305
+ super
306
+ end
307
+ end
308
+
309
+ # @see BaseAdapter
310
+ def delete_resource(resource)
311
+ name = resource.name
312
+ key = key_value_from_query(resource.to_query)
313
+ uri = "/#{name.pluralize}/#{key}.xml"
314
+ logger.debug { "delete #{uri}" }
315
+ response = http_delete(uri)
316
+ response.kind_of?(Net::HTTPSuccess)
317
+ end
318
+ end
319
+ end
320
+ end