dm-persevere-adapter 0.17.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.17.0
1
+ 0.18.0
@@ -0,0 +1,51 @@
1
+ module DataMapper
2
+ module Model
3
+ # module Json
4
+ def to_json_schema(repository_name = default_repository_name)
5
+ to_json_schema_compatible_hash(repository_name).to_json
6
+ end
7
+
8
+ #TODO: Add various options in.
9
+ def to_json_schema_compatible_hash(repository_name = default_repository_name)
10
+ usable_properties = properties.select{|p| p.name != :id }
11
+ schema_hash = {}
12
+ schema_hash['id'] = self.storage_name(repository_name)
13
+ properties_hash = {}
14
+ usable_properties.each{|p| properties_hash[p.name] = p.to_json_schema_hash if p.name != :id }
15
+ schema_hash['properties'] = properties_hash
16
+ return schema_hash
17
+ end
18
+
19
+ end
20
+
21
+ class Property
22
+ def to_json_schema_hash
23
+ json_hash = { "type" => to_json_type }
24
+ { "optional" => true }.merge(json_hash) unless required? == true
25
+ # MIN
26
+ # MAX
27
+ end
28
+
29
+ private
30
+
31
+ def to_json_type
32
+ # A case statement doesn't seem to be working when comparing classes.
33
+ # That's why we're using a if elseif block.
34
+ if type == DataMapper::Types::Serial
35
+ return "string"
36
+ elsif type == String
37
+ return "string"
38
+ elsif type == Float
39
+ return "number"
40
+ elsif type == DataMapper::Types::Boolean
41
+ return "boolean"
42
+ elsif type == DataMapper::Types::Text
43
+ elsif type == "string"
44
+ elsif type == Integer
45
+ return "integer"
46
+ else
47
+ return"string"
48
+ end
49
+ end
50
+ end
51
+ end
@@ -34,10 +34,9 @@ class PersevereResult
34
34
  end
35
35
 
36
36
  class Persevere
37
- VERSION = '1.1'
38
37
  HEADERS = { 'Accept' => 'application/json',
39
38
  'Content-Type' => 'application/json'
40
- }
39
+ } unless defined?(HEADERS)
41
40
 
42
41
  attr_accessor :server_url, :pservr
43
42
 
@@ -49,12 +48,12 @@ class Persevere
49
48
  end
50
49
 
51
50
  # Pass in a resource hash
52
- def create(path, resource)
51
+ def create(path, resource, headers = {})
53
52
  json_blob = resource.to_json
54
53
  response = nil
55
54
  while response.nil?
56
55
  begin
57
- response = @persevere.send_request('POST', path, json_blob, HEADERS)
56
+ response = @persevere.send_request('POST', path, json_blob, HEADERS.merge(headers))
58
57
  rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
59
58
  Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
60
59
  puts "Persevere Create Failed: #{e}, Trying again."
@@ -63,11 +62,11 @@ class Persevere
63
62
  return PersevereResult.make(response)
64
63
  end
65
64
 
66
- def retrieve(path)
65
+ def retrieve(path, headers = {})
67
66
  response = nil
68
67
  while response.nil?
69
68
  begin
70
- response = @persevere.send_request('GET', path, nil, HEADERS)
69
+ response = @persevere.send_request('GET', path, nil, HEADERS.merge(headers))
71
70
  rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
72
71
  Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
73
72
  puts "Persevere Create Failed: #{e}, Trying again."
@@ -76,13 +75,13 @@ class Persevere
76
75
  return PersevereResult.make(response)
77
76
  end
78
77
 
79
- def update(path, resource)
78
+ def update(path, resource, headers = {})
80
79
  json_blob = resource.to_json
81
80
  # puts "JSON to PERSEVERE: #{json_blob}"
82
81
  response = nil
83
82
  while response.nil?
84
83
  begin
85
- response = @persevere.send_request('PUT', path, json_blob, HEADERS)
84
+ response = @persevere.send_request('PUT', path, json_blob, HEADERS.merge(headers))
86
85
  rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
87
86
  Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
88
87
  puts "Persevere Create Failed: #{e}, Trying again."
@@ -91,11 +90,11 @@ class Persevere
91
90
  return PersevereResult.make(response)
92
91
  end
93
92
 
94
- def delete(path)
93
+ def delete(path, headers = {})
95
94
  response = nil
96
95
  while response.nil?
97
96
  begin
98
- response = @persevere.send_request('DELETE', path, nil, HEADERS)
97
+ response = @persevere.send_request('DELETE', path, nil, HEADERS.merge(headers))
99
98
  rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
100
99
  Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
101
100
  puts "Persevere Create Failed: #{e}, Trying again."
@@ -3,11 +3,99 @@ require 'dm-core'
3
3
  require 'extlib'
4
4
  require 'json'
5
5
 
6
+ require 'model_json_support'
6
7
  require 'persevere'
7
8
 
8
9
  module DataMapper
10
+ module Migrations
11
+ module PersevereAdapter
12
+ # @api private
13
+ def self.included(base)
14
+ DataMapper.extend(Migrations::SingletonMethods)
15
+
16
+ [ :Repository, :Model ].each do |name|
17
+ DataMapper.const_get(name).send(:include, Migrations.const_get(name))
18
+ end
19
+ end
20
+
21
+ # Returns whether the storage_name exists.
22
+ #
23
+ # @param [String] storage_name
24
+ # a String defining the name of a storage, for example a table name.
25
+ #
26
+ # @return [Boolean]
27
+ # true if the storage exists
28
+ #
29
+ # @api semipublic
30
+ def storage_exists?(storage_name)
31
+ class_names = JSON.parse(@persevere.retrieve('/Class/[=id]').body)
32
+ return true if class_names.include?("Class/"+storage_name)
33
+ false
34
+ end
35
+
36
+ ##
37
+ # Creates the persevere schema from the model.
38
+ #
39
+ # @param [DataMapper::Model] model
40
+ # The model that corresponds to the storage schema that needs to be created.
41
+ #
42
+ # @api semipublic
43
+ def create_model_storage(model)
44
+ name = self.name
45
+ properties = model.properties_with_subclasses(name)
46
+
47
+ return false if storage_exists?(model.storage_name(name))
48
+ return false if properties.empty?
49
+
50
+ schema_hash = model.to_json_schema_compatible_hash
51
+
52
+ return true unless put_schema(schema_hash).nil?
53
+ false
54
+ end
55
+
56
+ ##
57
+ # Updates the persevere schema from the model.
58
+ #
59
+ # @param [DataMapper::Model] model
60
+ # The model that corresponds to the storage schema that needs to be updated.
61
+ #
62
+ # @api semipublic
63
+ def upgrade_model_storage(model)
64
+ name = self.name
65
+ properties = model.properties_with_subclasses(name)
66
+
67
+ if success = create_model_storage(model)
68
+ return properties
69
+ end
70
+
71
+ table_name = model.storage_name(name)
72
+ schema_hash = model.to_json_schema_compatible_hash
73
+ end
74
+
75
+ ##
76
+ # Destroys the persevere schema from the model.
77
+ #
78
+ # @param [DataMapper::Model] model
79
+ # The model that corresponds to the storage schema that needs to be destroyed.
80
+ #
81
+ # @api semipublic
82
+ def destroy_model_storage(model)
83
+ return true unless storage_exists?(model.storage_name(name))
84
+ schema_hash = model.to_json_schema_compatible_hash
85
+ return true unless delete_schema(schema_hash).nil?
86
+ false
87
+ end
88
+
89
+ end # module PersevereAdapter
90
+ end # module Migrations
91
+
9
92
  module Adapters
10
93
  class PersevereAdapter < AbstractAdapter
94
+ extend Chainable
95
+ extend Deprecate
96
+
97
+ include Migrations::PersevereAdapter
98
+
11
99
  ##
12
100
  # Used by DataMapper to put records into a data-store: "INSERT"
13
101
  # in SQL-speak. It takes an array of the resources (model
@@ -37,7 +125,7 @@ module DataMapper
37
125
  tblname = resource.model.storage_name
38
126
 
39
127
  path = "/#{tblname}/"
40
- payload = resource.attributes
128
+ payload = resource.attributes.reject{ |key,value| value.nil? }
41
129
  payload.delete(:id)
42
130
 
43
131
  response = @persevere.create(path, payload)
@@ -98,7 +186,9 @@ module DataMapper
98
186
  tblname = resource.model.storage_name
99
187
  path = "/#{tblname}/#{resource.id}"
100
188
 
101
- result = @persevere.update(path, resource.attributes)
189
+ payload = resource.attributes.reject{ |key,value| value.nil? }
190
+
191
+ result = @persevere.update(path, payload)
102
192
 
103
193
  if result.code == "200"
104
194
  updated += 1
@@ -193,8 +283,6 @@ module DataMapper
193
283
  resources = read_many(query)
194
284
  end
195
285
 
196
- puts resources.inspect
197
-
198
286
  resources.each do |resource|
199
287
  tblname = resource.model.storage_name
200
288
  path = "/#{tblname}/#{resource.id}"
@@ -225,13 +313,13 @@ module DataMapper
225
313
  path = "/Class/#{project}/#{name}"
226
314
  end
227
315
 
228
- response = @persevere.retrieve(path)
229
-
230
- if response.code == "200"
231
- return JSON.parse(response.body)
316
+ result = @persevere.retrieve(path)
317
+
318
+ if result.code == "200"
319
+ return result.body
232
320
  else
233
- return nil
234
- end
321
+ return false
322
+ end
235
323
  end
236
324
 
237
325
  def put_schema(schema_hash, project = nil)
@@ -246,16 +334,56 @@ module DataMapper
246
334
  puts "You need an id key/value in the hash"
247
335
  end
248
336
  end
249
-
250
- response = @persevere.create(path, schema_hash)
337
+
338
+ result = @persevere.create(path, schema_hash)
339
+ if result.code == '201'
340
+ return JSON.parse(result.body)
341
+ else
342
+ return false
343
+ end
344
+ end
345
+
346
+ def update_schema(schema_hash, project = nil)
347
+
348
+ id = schema_hash['id']
349
+ payload = schema_hash.reject{|key,value| key.to_sym.eql?(:id) }
350
+
251
351
 
252
- if response.code == "201"
253
- return JSON.parse(response.body)
352
+ if project.nil?
353
+ path = "/Class/#{id}"
254
354
  else
255
- return nil
256
- end
355
+ path = "/Class/#{project}/#{id}"
356
+ end
357
+ # debugger
358
+ result = @persevere.update(path, payload)
359
+
360
+ if result.code == '200'
361
+ return result.body
362
+ else
363
+ return false
364
+ end
257
365
  end
258
366
 
367
+ def delete_schema(schema_hash, project = nil)
368
+ if ! project.nil?
369
+ if schema_hash.has_key?("id")
370
+ if ! schema_hash['id'].index(project)
371
+ schema_hash['id'] = "#{project}/#{schema_hash['id']}"
372
+ end
373
+ else
374
+ puts "You need an id key/value in the hash"
375
+ end
376
+ end
377
+ path = "/Class/#{schema_hash['id']}"
378
+ result = @persevere.delete(path)
379
+
380
+ if result.code == "204"
381
+ return true
382
+ else
383
+ return false
384
+ end
385
+ end
386
+
259
387
  private
260
388
 
261
389
  ##
@@ -383,6 +511,9 @@ module DataMapper
383
511
 
384
512
  query
385
513
  end
386
- end
387
- end
388
- end
514
+ end # class PersevereAdapter
515
+ const_added(:PersevereAdapter)
516
+ end # module Adapters
517
+
518
+
519
+ end # module DataMapper
@@ -0,0 +1,311 @@
1
+ share_examples_for 'An Adapter Foo' do
2
+
3
+ def self.adapter_supports?(*methods)
4
+ methods.all? do |method|
5
+ # TODO: figure out a way to see if the instance method is only inherited
6
+ # from the Abstract Adapter, and not defined in it's class. If that is
7
+ # the case return false
8
+
9
+ # CRUD methods can be inherited from parent class
10
+ described_type.instance_methods.any? { |instance_method| method.to_s == instance_method.to_s }
11
+ end
12
+ end
13
+
14
+ before :all do
15
+ raise '+@adapter+ should be defined in before block' unless instance_variable_get('@adapter')
16
+
17
+ class ::Heffalump
18
+ include DataMapper::Resource
19
+
20
+ property :id, Serial
21
+ property :color, String
22
+ property :num_spots, Integer
23
+ property :striped, Boolean
24
+ end
25
+
26
+ # create all tables and constraints before each spec
27
+
28
+ # if @repository.respond_to?(:auto_migrate!)
29
+ Heffalump.auto_migrate!
30
+ # end
31
+ end
32
+
33
+ if adapter_supports?(:create)
34
+ describe '#create' do
35
+ it 'should not raise any errors' do
36
+ lambda {
37
+ Heffalump.create(:color => 'peach')
38
+ }.should_not raise_error
39
+ end
40
+
41
+ it 'should set the identity field for the resource' do
42
+ heffalump = Heffalump.new(:color => 'peach')
43
+ heffalump.id.should be_nil
44
+ heffalump.save
45
+ heffalump.id.should_not be_nil
46
+ end
47
+ end
48
+ else
49
+ it 'needs to support #create'
50
+ end
51
+
52
+ if adapter_supports?(:read)
53
+ describe '#read' do
54
+ before :all do
55
+ @heffalump = Heffalump.create(:color => 'brownish hue')
56
+ #just going to borrow this, so I can check the return values
57
+ @query = Heffalump.all.query
58
+ end
59
+
60
+ it 'should not raise any errors' do
61
+ lambda {
62
+ Heffalump.all()
63
+ }.should_not raise_error
64
+ end
65
+
66
+ it 'should return stuff' do
67
+ Heffalump.all.should be_include(@heffalump)
68
+ end
69
+ end
70
+ else
71
+ it 'needs to support #read'
72
+ end
73
+
74
+ if adapter_supports?(:update)
75
+ describe '#update' do
76
+ before do
77
+ @heffalump = Heffalump.create(:color => 'indigo')
78
+ end
79
+
80
+ it 'should not raise any errors' do
81
+ lambda {
82
+ @heffalump.color = 'violet'
83
+ @heffalump.save
84
+ }.should_not raise_error
85
+ end
86
+
87
+ it 'should not alter the identity field' do
88
+ id = @heffalump.id
89
+ @heffalump.color = 'violet'
90
+ @heffalump.save
91
+ @heffalump.id.should == id
92
+ end
93
+
94
+ it 'should update altered fields' do
95
+ @heffalump.color = 'violet'
96
+ @heffalump.save
97
+ Heffalump.get(*@heffalump.key).color.should == 'violet'
98
+ end
99
+
100
+ it 'should not alter other fields' do
101
+ color = @heffalump.color
102
+ @heffalump.num_spots = 3
103
+ @heffalump.save
104
+ Heffalump.get(*@heffalump.key).color.should == color
105
+ end
106
+ end
107
+ else
108
+ it 'needs to support #update'
109
+ end
110
+
111
+ if adapter_supports?(:delete)
112
+ describe '#delete' do
113
+ before do
114
+ @heffalump = Heffalump.create(:color => 'forest green')
115
+ end
116
+
117
+ it 'should not raise any errors' do
118
+ lambda {
119
+ @heffalump.destroy
120
+ }.should_not raise_error
121
+ end
122
+
123
+ it 'should delete the requested resource' do
124
+ id = @heffalump.id
125
+ @heffalump.destroy
126
+ Heffalump.get(id).should be_nil
127
+ end
128
+ end
129
+ else
130
+ it 'needs to support #delete'
131
+ end
132
+
133
+ if adapter_supports?(:read, :create)
134
+ describe 'query matching' do
135
+ before :all do
136
+ @red = Heffalump.create(:color => 'red')
137
+ @two = Heffalump.create(:num_spots => 2)
138
+ @five = Heffalump.create(:num_spots => 5)
139
+ end
140
+
141
+ describe 'conditions' do
142
+ describe 'eql' do
143
+ it 'should be able to search for objects included in an inclusive range of values' do
144
+ Heffalump.all(:num_spots => 1..5).should be_include(@five)
145
+ end
146
+
147
+ it 'should be able to search for objects included in an exclusive range of values' do
148
+ Heffalump.all(:num_spots => 1...6).should be_include(@five)
149
+ end
150
+
151
+ it 'should not be able to search for values not included in an inclusive range of values' do
152
+ Heffalump.all(:num_spots => 1..4).should_not be_include(@five)
153
+ end
154
+
155
+ it 'should not be able to search for values not included in an exclusive range of values' do
156
+ Heffalump.all(:num_spots => 1...5).should_not be_include(@five)
157
+ end
158
+ end
159
+
160
+ describe 'not' do
161
+ it 'should be able to search for objects with not equal value' do
162
+ Heffalump.all(:color.not => 'red').should_not be_include(@red)
163
+ end
164
+
165
+ it 'should include objects that are not like the value' do
166
+ Heffalump.all(:color.not => 'black').should be_include(@red)
167
+ end
168
+
169
+ it 'should be able to search for objects with not nil value' do
170
+ Heffalump.all(:color.not => nil).should be_include(@red)
171
+ end
172
+
173
+ it 'should not include objects with a nil value' do
174
+ Heffalump.all(:color.not => nil).should_not be_include(@two)
175
+ end
176
+
177
+ it 'should be able to search for object with a nil value using required properties' do
178
+ Heffalump.all(:id.not => nil).should == [ @red, @two, @five ]
179
+ end
180
+
181
+ it 'should be able to search for objects not in an empty list (match all)' do
182
+ Heffalump.all(:color.not => []).should == [ @red, @two, @five ]
183
+ end
184
+
185
+ it 'should be able to search for objects in an empty list and another OR condition (match none on the empty list)' do
186
+ Heffalump.all(:conditions => DataMapper::Query::Conditions::Operation.new(
187
+ :or,
188
+ DataMapper::Query::Conditions::Comparison.new(:in, Heffalump.properties[:color], []),
189
+ DataMapper::Query::Conditions::Comparison.new(:in, Heffalump.properties[:num_spots], [5]))).should == [ @five ]
190
+ end
191
+
192
+ it 'should be able to search for objects not included in an array of values' do
193
+ Heffalump.all(:num_spots.not => [ 1, 3, 5, 7 ]).should be_include(@two)
194
+ end
195
+
196
+ it 'should be able to search for objects not included in an array of values' do
197
+ Heffalump.all(:num_spots.not => [ 1, 3, 5, 7 ]).should_not be_include(@five)
198
+ end
199
+
200
+ it 'should be able to search for objects not included in an inclusive range of values' do
201
+ Heffalump.all(:num_spots.not => 1..4).should be_include(@five)
202
+ end
203
+
204
+ it 'should be able to search for objects not included in an exclusive range of values' do
205
+ Heffalump.all(:num_spots.not => 1...5).should be_include(@five)
206
+ end
207
+
208
+ it 'should not be able to search for values not included in an inclusive range of values' do
209
+ Heffalump.all(:num_spots.not => 1..5).should_not be_include(@five)
210
+ end
211
+
212
+ it 'should not be able to search for values not included in an exclusive range of values' do
213
+ Heffalump.all(:num_spots.not => 1...6).should_not be_include(@five)
214
+ end
215
+ end
216
+
217
+ describe 'like' do
218
+ it 'should be able to search for objects that match value' do
219
+ Heffalump.all(:color.like => '%ed').should be_include(@red)
220
+ end
221
+
222
+ it 'should not search for objects that do not match the value' do
223
+ Heffalump.all(:color.like => '%blak%').should_not be_include(@red)
224
+ end
225
+ end
226
+
227
+ describe 'regexp' do
228
+ before do
229
+ if (defined?(DataMapper::Adapters::Sqlite3Adapter) && @adapter.kind_of?(DataMapper::Adapters::Sqlite3Adapter) ||
230
+ defined?(DataMapper::Adapters::SqlserverAdapter) && @adapter.kind_of?(DataMapper::Adapters::SqlserverAdapter))
231
+ pending 'delegate regexp matches to same system that the InMemory and YAML adapters use'
232
+ end
233
+ end
234
+
235
+ it 'should be able to search for objects that match value' do
236
+ Heffalump.all(:color => /ed/).should be_include(@red)
237
+ end
238
+
239
+ it 'should not be able to search for objects that do not match the value' do
240
+ Heffalump.all(:color => /blak/).should_not be_include(@red)
241
+ end
242
+
243
+ it 'should be able to do a negated search for objects that match value' do
244
+ Heffalump.all(:color.not => /blak/).should be_include(@red)
245
+ end
246
+
247
+ it 'should not be able to do a negated search for objects that do not match value' do
248
+ Heffalump.all(:color.not => /ed/).should_not be_include(@red)
249
+ end
250
+
251
+ end
252
+
253
+ describe 'gt' do
254
+ it 'should be able to search for objects with value greater than' do
255
+ Heffalump.all(:num_spots.gt => 1).should be_include(@two)
256
+ end
257
+
258
+ it 'should not find objects with a value less than' do
259
+ Heffalump.all(:num_spots.gt => 3).should_not be_include(@two)
260
+ end
261
+ end
262
+
263
+ describe 'gte' do
264
+ it 'should be able to search for objects with value greater than' do
265
+ Heffalump.all(:num_spots.gte => 1).should be_include(@two)
266
+ end
267
+
268
+ it 'should be able to search for objects with values equal to' do
269
+ Heffalump.all(:num_spots.gte => 2).should be_include(@two)
270
+ end
271
+
272
+ it 'should not find objects with a value less than' do
273
+ Heffalump.all(:num_spots.gte => 3).should_not be_include(@two)
274
+ end
275
+ end
276
+
277
+ describe 'lt' do
278
+ it 'should be able to search for objects with value less than' do
279
+ Heffalump.all(:num_spots.lt => 3).should be_include(@two)
280
+ end
281
+
282
+ it 'should not find objects with a value less than' do
283
+ Heffalump.all(:num_spots.gt => 2).should_not be_include(@two)
284
+ end
285
+ end
286
+
287
+ describe 'lte' do
288
+ it 'should be able to search for objects with value less than' do
289
+ Heffalump.all(:num_spots.lte => 3).should be_include(@two)
290
+ end
291
+
292
+ it 'should be able to search for objects with values equal to' do
293
+ Heffalump.all(:num_spots.lte => 2).should be_include(@two)
294
+ end
295
+
296
+ it 'should not find objects with a value less than' do
297
+ Heffalump.all(:num_spots.lte => 1).should_not be_include(@two)
298
+ end
299
+ end
300
+ end
301
+
302
+ describe 'limits' do
303
+ it 'should be able to limit the objects' do
304
+ Heffalump.all(:limit => 2).length.should == 2
305
+ end
306
+ end
307
+ end
308
+ else
309
+ it 'needs to support #read and #create to test query matching'
310
+ end
311
+ end
@@ -0,0 +1,105 @@
1
+ require "benchmark"
2
+
3
+ module DataMapper::Spec
4
+ module AdapterHelpers
5
+ def self.current_adapters
6
+ @current_adapters ||= []
7
+ end
8
+
9
+ def supported_by(*adapters, &block)
10
+ adapters = get_adapters(*adapters)
11
+
12
+ PRIMARY.only(*adapters).each do |adapter, connection_uri|
13
+ # keep track of the current adapters
14
+ AdapterHelpers.current_adapters << adapters
15
+
16
+ describe("with #{adapter}") do
17
+
18
+ before :all do
19
+ # store these in instance vars for the shared adapter specs
20
+ @adapter = DataMapper.setup(:default, connection_uri)
21
+ @repository = DataMapper.repository(@adapter.name)
22
+
23
+ # create all tables and constraints before each spec
24
+ if @repository.respond_to?(:auto_migrate!)
25
+ @repository.auto_migrate!
26
+ end
27
+ end
28
+
29
+ after :all do
30
+ # remove all tables and constraints after each spec
31
+ if DataMapper.respond_to?(:auto_migrate_down!, true)
32
+ DataMapper.send(:auto_migrate_down!, @repository.name)
33
+ end
34
+ end
35
+
36
+ # TODO: add destroy_model_storage and migrations code
37
+ # that removes the YAML file and remove this code
38
+ after :all do
39
+ if defined?(DataMapper::Adapters::YamlAdapter) && @adapter.kind_of?(DataMapper::Adapters::YamlAdapter)
40
+ descendants = DataMapper::Model.descendants.to_a
41
+ while model = descendants.shift
42
+ descendants.concat(model.descendants.to_a - [ model ])
43
+
44
+ model.default_scope.clear
45
+ model.all(:repository => @repository).destroy!
46
+ end
47
+ end
48
+ end
49
+
50
+ self.instance_eval(&block)
51
+ end
52
+
53
+ AdapterHelpers.current_adapters.pop
54
+ end
55
+ end
56
+
57
+ def with_alternate_adapter(&block)
58
+ adapters = AdapterHelpers.current_adapters.last
59
+
60
+ ALTERNATE.only(*adapters).each do |adapter, connection_uri|
61
+ describe("and #{adapter}") do
62
+
63
+ before :all do
64
+ @alternate_adapter = DataMapper.setup(:alternate, connection_uri)
65
+ @alternate_repository = DataMapper.repository(@alternate_adapter.name)
66
+
67
+ # create all tables and constraints before each spec
68
+ if @alternate_repository.respond_to?(:auto_migrate!)
69
+ @alternate_repository.auto_migrate!
70
+ end
71
+ end
72
+
73
+ after :all do
74
+ # remove all tables and constraints after each spec
75
+ if DataMapper.respond_to?(:auto_migrate_down!, true)
76
+ DataMapper.send(:auto_migrate_down!, @alternate_repository.name)
77
+ end
78
+ end
79
+
80
+ # TODO: add destroy_model_storage and migrations code
81
+ # that removes the YAML file and remove this code
82
+ after :all do
83
+ if defined?(DataMapper::Adapters::YamlAdapter) && @alternate_adapter.kind_of?(DataMapper::Adapters::YamlAdapter)
84
+ descendants = DataMapper::Model.descendants.to_a
85
+ while model = descendants.shift
86
+ descendants.concat(model.descendants.to_a - [ model ])
87
+
88
+ model.default_scope.clear
89
+ model.all(:repository => @alternate_repository).destroy!
90
+ end
91
+ end
92
+ end
93
+
94
+ self.instance_eval(&block)
95
+ end
96
+ end
97
+ end
98
+
99
+ def get_adapters(*adapters)
100
+ adapters.map! { |adapter_name| adapter_name.to_s }
101
+ adapters = ADAPTERS if adapters.include?('all')
102
+ ADAPTERS & adapters
103
+ end
104
+ end
105
+ end
@@ -1,47 +1,26 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
- require 'pathname'
3
- require 'rubygems'
4
-
1
+ require File.dirname(__FILE__) + '/spec_helper'
5
2
  gem 'rspec'
6
3
  require 'spec'
7
-
8
- require Pathname(__FILE__).dirname.expand_path.parent + 'lib/persevere_adapter'
9
-
10
- DataMapper.setup(:default, {
11
- :adapter => 'persevere',
12
- :host => 'localhost',
13
- :port => '8080',
14
- :uri => 'http://localhost:8080'
15
- })
16
-
17
- #
18
- # I need to make the Book class for Books to relate to
19
- #
20
-
21
- class Book
22
- include DataMapper::Resource
23
-
24
- # Persevere only does id's as strings.
25
- property :id, String, :serial => true
26
- property :author, String
27
- property :created_at, DateTime
28
- property :title, String
29
- end
30
-
31
- require 'dm-core'
32
- require 'extlib'
33
4
 
5
+ require 'ruby-debug'
34
6
  require DataMapper.root / 'lib' / 'dm-core' / 'spec' / 'adapter_shared_spec'
35
7
  require Pathname(__FILE__).dirname.expand_path.parent + 'lib/persevere_adapter'
36
8
 
37
9
  describe DataMapper::Adapters::PersevereAdapter do
38
10
  before :all do
39
11
  # This needs to point to a valid persevere server
40
- @adapter = DataMapper.setup(:default, { :adapter => 'persevere',
41
- :host => 'localhost',
42
- :port => '8080' }
43
- )
44
-
12
+ @adapter = DataMapper.setup(:default, { :adapter => 'persevere', :host => 'localhost', :port => '8080' })
13
+
14
+ class Bozon
15
+ include DataMapper::Resource
16
+
17
+ # Persevere only does id's as strings.
18
+ property :id, String, :serial => true
19
+ property :author, String
20
+ property :created_at, DateTime
21
+ property :title, String
22
+ end
23
+
45
24
  @test_schema_hash = {
46
25
  'id' => 'Vanilla',
47
26
  'properties' => {
@@ -50,40 +29,120 @@ describe DataMapper::Adapters::PersevereAdapter do
50
29
  'data' => { 'type' => 'string'}
51
30
  }
52
31
  }
53
- end
54
32
 
55
- it_should_behave_like 'An Adapter'
33
+ @test_schema_hash_alt = {
34
+ 'id' => 'test1/Vanilla',
35
+ 'properties' => {
36
+ 'cid' => {'type' => 'string' },
37
+ 'parent' => { 'type' => 'string'},
38
+ 'data' => { 'type' => 'string'}
39
+ }
40
+ }
41
+ @test_schema_hash_mod = {
42
+ 'id' => 'Vanilla',
43
+ 'properties' => {
44
+ 'cid' => {'type' => 'string' },
45
+ 'newdata' => { 'type' => 'any'}
46
+ }
47
+ }
48
+
49
+ @test_schema_hash_alt_mod = {
50
+ 'id' => 'test1/Vanilla',
51
+ 'properties' => {
52
+ 'cid' => {'type' => 'string' },
53
+ 'newdata' => { 'type' => 'any'}
54
+ }
55
+ }
56
+ end
56
57
 
57
- describe '#get_schema' do
58
- it 'should return all of the schemas (in json) if no name is provided' do
59
- @adapter.get_schema()
60
- end
58
+ describe 'migrations' do
59
+ it 'should create the Bozon storage' do
60
+ Bozon.auto_migrate!
61
+ Bozon.auto_migrate_down!
62
+ end
63
+
64
+ it "should destroy Create then Remove the Bozon Storage" do
65
+ @adapter.get_schema(Bozon.storage_name).should == false
66
+ Bozon.auto_migrate_up!
67
+ @adapter.get_schema(Bozon.storage_name).should_not == false
68
+ Bozon.auto_migrate_down!
69
+ @adapter.get_schema(Bozon.storage_name).should == false
70
+ end
71
+ end
61
72
 
62
- it 'should return the json schema of the class specified' do
63
- @adapter.get_schema("Object")
64
- end
73
+ it_should_behave_like 'An Adapter Foo'
65
74
 
66
- it 'should return all of the schemas (in json) for a project if no name is provided' do
67
- @adapter.get_schema(nil, "Class")
68
- end
75
+ describe '#put_schema' do
76
+ it 'should create the json schema for the hash' do
77
+ @adapter.put_schema(@test_schema_hash).should_not == false
78
+ end
79
+
80
+ it 'should create the json schema for the hash under the specified project' do
81
+ @adapter.put_schema(@test_schema_hash, "test").should_not == false
82
+ end
83
+
84
+ it 'should create the json schema for the hash under the specified project' do
85
+ @adapter.put_schema(@test_schema_hash_alt).should_not == false
86
+ end
87
+ end
69
88
 
70
- it 'should return all of the schemas (in json) if no name is provided' do
71
- @adapter.get_schema("Object", "Class")
72
- end
89
+ describe '#get_schema' do
90
+ it 'should return all of the schemas (in json) if no name is provided' do
91
+ result = @adapter.get_schema()
92
+ result.should_not == false
93
+ JSON.parse(result).class.should == Array
94
+ end
95
+
96
+ it 'should return the json schema of the class specified' do
97
+ result = @adapter.get_schema("Object")
98
+ result.should_not == false
99
+ JSON.parse(result)["id"].should == "Object"
73
100
  end
101
+
102
+ # I don't think we need these tests.
103
+ # it 'should return all of the schemas (in json) for a project if no name is provided' do
104
+ # result = @adapter.get_schema(nil, "Class")
105
+ # debugger
106
+ # result
107
+ # end
108
+ #
109
+ # it 'should return all of the schemas (in json) if no name is provided' do
110
+ # @adapter.get_schema("Object", "Class")
111
+ # end
112
+ end
74
113
 
75
- describe '#put_schema' do
76
- it 'should create the json schema for the hash' do
77
- @adapter.put_schema(@test_schema_hash)
78
- end
114
+ describe '#update_schema' do
115
+ it 'should update a previously existing schema' do
116
+ result = @adapter.update_schema(@test_schema_hash_mod)
117
+ result.should_not == false
79
118
 
80
- it 'should create the json schema for the hash under the specified project' do
81
- @adapter.put_schema(@test_schema_hash, "test")
82
- end
119
+ @test_schema_hash_mod['id'].should match(JSON.parse(result)['id'])
120
+ end
121
+
122
+ it 'should update a previously created schema under the specified project' do
123
+ result = @adapter.update_schema(@test_schema_hash_mod, "test")
124
+ result.should_not == false
125
+ @test_schema_hash_mod['id'].should match(JSON.parse(result)['id'])
126
+ end
127
+
128
+ it 'should update a previously created schema under the specified project' do
129
+ result = @adapter.update_schema(@test_schema_hash_alt_mod)
130
+ result.should_not == false
131
+ @test_schema_hash_alt_mod['id'].should match(JSON.parse(result)['id'])
132
+ end
133
+ end
83
134
 
84
- it 'should create the json schema for the hash under the specified project' do
85
- @test_schema_hash['id'] = 'test1/Vanilla'
86
- @adapter.put_schema(@test_schema_hash)
87
- end
135
+ describe '#delete_schema' do
136
+ it 'should delete the specified schema' do
137
+ @adapter.delete_schema(@test_schema_hash).should == true
138
+ end
139
+
140
+ it 'should delete the specified schema in the specified project' do
141
+ @adapter.delete_schema(@test_schema_hash, "test").should == true
142
+ end
143
+
144
+ it 'should delete the specified schema in the specified project' do
145
+ @adapter.delete_schema(@test_schema_hash_alt).should == true
88
146
  end
89
147
  end
148
+ end
@@ -57,7 +57,6 @@ describe Persevere do
57
57
  result = @p.create('/Class/', @blobObj)
58
58
  result.code.should == "201"
59
59
  JSON.parse(result.body).should == @blobObj
60
- # result.body.should == "\"Can not modify queries\""
61
60
  # This shouldn't be a 201, it should say something mean.
62
61
  end
63
62
  end
@@ -73,7 +72,7 @@ describe Persevere do
73
72
  end
74
73
 
75
74
  it 'should 404 on a non-existent object' do
76
- result = @p.retrieve('/Class/NotThere')
75
+ result = @p.retrieve('/Class/GetNotThere')
77
76
  result.code.should == "404"
78
77
  result.message.should == "Not Found"
79
78
  end
@@ -91,9 +90,10 @@ describe Persevere do
91
90
  end
92
91
 
93
92
  it 'should fail to modify a non-existent item' do
94
- result = @p.update('/Class/NotThere', @blobObj)
93
+ result = @p.update('/Class/NonExistent', @blobObj)
95
94
  result.code.should == "500"
96
95
  result.body.should == "\"id does not match location\""
96
+ @p.delete('/Class/NonExistent') # A bug(?) in Persevere makes a broken NonExistent class.
97
97
  # This should be a 404 and not throw a persevere server exception
98
98
  end
99
99
  end
@@ -110,10 +110,9 @@ describe Persevere do
110
110
 
111
111
  it 'should fail to delete a non-existent item' do
112
112
  result = @p.delete('/Class/NotThere')
113
- result.code.should == "204"
114
- result.message.should == "No Content"
115
- result.body.should be_nil
116
- # This should be a 404 and not fail silently with a 204
113
+ result.code.should == "404"
114
+ result.message.should == "Not Found"
115
+ result.body.should == "\"Class/NotThere not found\""
117
116
  end
118
117
  end
119
118
  end
@@ -1,14 +1,52 @@
1
- # require 'pathname'
2
- # require 'rubygems'
3
- #require 'spec'
4
-
5
- # DataMapper.setup(:default, {
6
- # :adapter => 'persevere',
7
- # :host => 'localhost',
8
- # :port => '8080',
9
- # :uri => 'http://localhost:8080'
10
- # })
11
-
12
- #
13
- # I need to make the Book class for Books to relate to
14
- #
1
+ require 'pathname'
2
+ require 'rubygems'
3
+
4
+ require 'addressable/uri'
5
+ require 'spec'
6
+
7
+ require 'ruby-debug'
8
+
9
+ require 'dm-core'
10
+
11
+ require 'adapter_shared_spec'
12
+
13
+ SPEC_ROOT = Pathname(__FILE__).dirname.expand_path
14
+ # $LOAD_PATH.unshift(SPEC_ROOT.parent + 'lib')
15
+
16
+ Pathname.glob((SPEC_ROOT + '{lib,*/shared}/**/*.rb').to_s).each { |file| require file }
17
+
18
+ ENV['ADAPTERS'] ||= 'all'
19
+
20
+ ADAPTERS = []
21
+
22
+ PRIMARY = {
23
+ 'persevere' => {:adapter => 'persevere', :host => 'localhost', :port => '8080'}
24
+ }
25
+
26
+ adapters = ENV['ADAPTERS'].split(' ').map { |adapter_name| adapter_name.strip.downcase }.uniq
27
+ adapters = PRIMARY.keys if adapters.include?('all')
28
+
29
+ PRIMARY.only(*adapters).each do |name, default|
30
+ connection_string = ENV["#{name.upcase}_SPEC_URI"] || default
31
+ begin
32
+ adapter = DataMapper.setup(name.to_sym, connection_string)
33
+
34
+ # test the connection if possible
35
+ if adapter.respond_to?(:query)
36
+ name == 'oracle' ? adapter.select('SELECT 1 FROM dual') : adapter.select('SELECT 1')
37
+ end
38
+
39
+ ADAPTERS << name
40
+ PRIMARY[name] = connection_string # ensure *_SPEC_URI is saved
41
+ rescue Exception => exception
42
+ puts "Could not connect to the database using #{connection_string.inspect} because: #{exception.inspect}"
43
+ end
44
+ end
45
+
46
+ logger = DataMapper::Logger.new(DataMapper.root / 'log' / 'dm.log', :debug)
47
+ logger.auto_flush = true
48
+
49
+ Spec::Runner.configure do |config|
50
+ config.extend(DataMapper::Spec::AdapterHelpers)
51
+ # config.include(DataMapper::Spec::PendingHelpers)
52
+ end
@@ -2,6 +2,19 @@ $LOAD_PATH << File.dirname(__FILE__)
2
2
 
3
3
  require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
4
4
 
5
+ #
6
+ # I need to make the Book class for Books to relate to
7
+ #
8
+ class Book
9
+ include DataMapper::Resource
10
+
11
+ # Persevere only does id's as strings.
12
+ property :id, String, :serial => true
13
+ property :author, String
14
+ property :created_at, DateTime
15
+ property :title, String
16
+ end
17
+
5
18
  describe 'A Persevere adapter' do
6
19
 
7
20
  before do
metadata CHANGED
@@ -1,92 +1,95 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dm-persevere-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.0
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
- - Ivan R. Judson
8
- - The Yogo Data Management Development Team
7
+ - Ivan R. Judson
8
+ - The Yogo Data Management Development Team
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2010-01-11 00:00:00 -07:00
13
+ date: 2010-01-13 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
- - !ruby/object:Gem::Dependency
17
- name: dm-core
18
- type: :runtime
19
- version_requirement:
20
- version_requirements: !ruby/object:Gem::Requirement
21
- requirements:
22
- - - ">="
23
- - !ruby/object:Gem::Version
24
- version: 0.10.1
25
- version:
26
- - !ruby/object:Gem::Dependency
27
- name: extlib
28
- type: :runtime
29
- version_requirement:
30
- version_requirements: !ruby/object:Gem::Requirement
31
- requirements:
32
- - - ">="
33
- - !ruby/object:Gem::Version
34
- version: "0"
35
- version:
16
+ - !ruby/object:Gem::Dependency
17
+ name: dm-core
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 0.10.1
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: extlib
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ version:
36
36
  description: A DataMapper Adapter for persevere
37
37
  email:
38
- - irjudson [a] gmail [d] com
38
+ - irjudson [a] gmail [d] com
39
39
  executables: []
40
40
 
41
41
  extensions: []
42
42
 
43
43
  extra_rdoc_files:
44
- - LICENSE.txt
45
- - README.txt
44
+ - LICENSE.txt
45
+ - README.txt
46
46
  files:
47
- - .gitignore
48
- - History.txt
49
- - LICENSE.txt
50
- - Manifest.txt
51
- - README.txt
52
- - Rakefile
53
- - VERSION
54
- - lib/persevere.rb
55
- - lib/persevere_adapter.rb
56
- - persevere/History.txt
57
- - persevere/LICENSE.txt
58
- - persevere/Manifest.txt
59
- - persevere/README.txt
60
- - spec/persevere_adapter_spec.rb
61
- - spec/persevere_spec.rb
62
- - spec/spec.opts
63
- - spec/spec_helper.rb
64
- - spec/unit/create_spec.rb
65
- - spec/unit/delete_spec.rb
66
- - spec/unit/read_spec.rb
67
- - spec/unit/update_spec.rb
68
- - tasks/spec.rb
47
+ - .gitignore
48
+ - History.txt
49
+ - LICENSE.txt
50
+ - Manifest.txt
51
+ - README.txt
52
+ - Rakefile
53
+ - VERSION
54
+ - lib/model_json_support.rb
55
+ - lib/persevere.rb
56
+ - lib/persevere_adapter.rb
57
+ - persevere/History.txt
58
+ - persevere/LICENSE.txt
59
+ - persevere/Manifest.txt
60
+ - persevere/README.txt
61
+ - spec/adapter_shared_spec.rb
62
+ - spec/lib/adapter_helpers.rb
63
+ - spec/persevere_adapter_spec.rb
64
+ - spec/persevere_spec.rb
65
+ - spec/spec.opts
66
+ - spec/spec_helper.rb
67
+ - spec/unit/create_spec.rb
68
+ - spec/unit/delete_spec.rb
69
+ - spec/unit/read_spec.rb
70
+ - spec/unit/update_spec.rb
71
+ - tasks/spec.rb
69
72
  has_rdoc: true
70
73
  homepage: http://github.com/yogo/dm-persevere-adapter
71
74
  licenses: []
72
75
 
73
76
  post_install_message:
74
77
  rdoc_options:
75
- - --main
76
- - README.txt
78
+ - --main
79
+ - README.txt
77
80
  require_paths:
78
- - lib
81
+ - lib
79
82
  required_ruby_version: !ruby/object:Gem::Requirement
80
83
  requirements:
81
- - - ">="
82
- - !ruby/object:Gem::Version
83
- version: "0"
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: "0"
84
87
  version:
85
88
  required_rubygems_version: !ruby/object:Gem::Requirement
86
89
  requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: "0"
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: "0"
90
93
  version:
91
94
  requirements: []
92
95
 
@@ -96,10 +99,12 @@ signing_key:
96
99
  specification_version: 3
97
100
  summary: A DataMapper Adapter for persevere
98
101
  test_files:
99
- - spec/persevere_adapter_spec.rb
100
- - spec/persevere_spec.rb
101
- - spec/spec_helper.rb
102
- - spec/unit/create_spec.rb
103
- - spec/unit/delete_spec.rb
104
- - spec/unit/read_spec.rb
105
- - spec/unit/update_spec.rb
102
+ - spec/adapter_shared_spec.rb
103
+ - spec/lib/adapter_helpers.rb
104
+ - spec/persevere_adapter_spec.rb
105
+ - spec/persevere_spec.rb
106
+ - spec/spec_helper.rb
107
+ - spec/unit/create_spec.rb
108
+ - spec/unit/delete_spec.rb
109
+ - spec/unit/read_spec.rb
110
+ - spec/unit/update_spec.rb