dm-persevere-adapter 0.47.1 → 0.48.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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.47.1
1
+ 0.48.0
@@ -23,13 +23,27 @@ module DataMapper
23
23
  class Property
24
24
  def to_json_schema_hash(repo)
25
25
  tm = repository(repo).adapter.type_map
26
- json_hash = { "type" => tm[type][:primitive] }
27
- json_hash.merge!( tm[type].reject{ |key,value| key == :primitive } )
28
- json_hash.merge!({ "optional" => true }) unless required?
29
- json_hash.merge!({ "unique" => true}) if unique?
30
- json_hash.merge!({"position" => @position }) unless @position.nil?
31
- json_hash.merge!({"prefix" => @prefix }) unless @prefix.nil?
32
- json_hash.merge!({"separator" => @separator }) unless @separator.nil?
26
+ json_hash = {}
27
+
28
+ if type.eql?(DataMapper::Types::JsonReference)
29
+ json_hash = { "type" => {"$ref" => "../#{@reference_class.storage_name}"}, "optional" => true }
30
+ elsif type.eql?(DataMapper::Types::JsonReferenceCollection)
31
+ json_hash = { "type" => "array",
32
+ "optional" => true,
33
+ "items" => {"$ref" => "../#{@reference_class.storage_name}"}
34
+ }
35
+ # "maxItems" => # For 0..3
36
+ # "minItems" =>
37
+ else
38
+ json_hash = { "type" => tm[type][:primitive] }
39
+ json_hash.merge!( tm[type].reject{ |key,value| key == :primitive } )
40
+ json_hash.merge!({ "optional" => true }) unless required?
41
+ json_hash.merge!({ "unique" => true}) if unique?
42
+ json_hash.merge!({"position" => @position }) unless @position.nil?
43
+ json_hash.merge!({"prefix" => @prefix }) unless @prefix.nil?
44
+ json_hash.merge!({"separator" => @separator }) unless @separator.nil?
45
+ end
46
+
33
47
  # MIN
34
48
  # MAX
35
49
  json_hash
@@ -9,6 +9,9 @@ require 'bigdecimal'
9
9
  require 'model_json_support'
10
10
  require 'persevere'
11
11
 
12
+ require 'types/json_reference'
13
+ require 'types/json_reference_collection'
14
+
12
15
  class BigDecimal
13
16
  alias to_json_old to_json
14
17
 
@@ -600,17 +603,25 @@ module DataMapper
600
603
  def make_json_compatible_hash(resource)
601
604
  json_rsrc = Hash.new
602
605
  resource.attributes(:property).each do |property, value|
603
- next if value.nil?
604
- json_rsrc[property.field] = case value
605
- when DateTime then value.new_offset(0).strftime("%Y-%m-%dT%H:%M:%SZ")
606
- when Date then value.to_s
607
- when Time then value.strftime("%H:%M:%S")
608
- when Float then value.to_f
609
- when BigDecimal then value.to_f
610
- when Integer then value.to_i
611
- else resource[property.name]
606
+
607
+ next if value.nil? || (value.is_a?(Array) && value.empty?)
608
+
609
+ if property.type == DataMapper::Types::JsonReference ||
610
+ property.type == DataMapper::Types::JsonReferenceCollection
611
+ json_rsrc[property.field] = property.value(value)
612
+ else
613
+ json_rsrc[property.field] = case value
614
+ when DateTime then value.new_offset(0).strftime("%Y-%m-%dT%H:%M:%SZ")
615
+ when Date then value.to_s
616
+ when Time then value.strftime("%H:%M:%S")
617
+ when Float then value.to_f
618
+ when BigDecimal then value.to_f
619
+ when Integer then value.to_i
620
+ else resource[property.name]
621
+ end
612
622
  end
613
- end
623
+ end
624
+
614
625
  json_rsrc
615
626
  end
616
627
 
@@ -0,0 +1,65 @@
1
+ module DataMapper
2
+ module Types
3
+ class JsonReference < Type
4
+ primitive String
5
+ length 50
6
+ lazy true
7
+
8
+ # Return the Ruby hash (to be turned into JSON) for insertion into the database
9
+ # @api semipublic
10
+ def self.dump(value, property)
11
+ value.save! unless value.saved?
12
+ return nil if value.nil?
13
+ ref_path = "../#{property.reference_class.storage_name}/#{value[:id]}"
14
+ result = { "$ref" => ref_path }
15
+
16
+ return result
17
+ end
18
+
19
+ # @api semipublic
20
+ def self.load(value, property)
21
+ return value if value.class.eql?(property.reference_class)
22
+ return nil if value.nil?
23
+
24
+ id = value.has_key?("$ref") ? value["$ref"] : value["id"]
25
+ id = id.split("/")[-1]
26
+ property.reference_class.get(id)
27
+ end
28
+
29
+ # Should return the public value we are looking for.
30
+ # @api semipublic
31
+ def self.typecast(value, property)
32
+ return value if value.class.eql?(property.reference_class)
33
+ return nil if value.nil?
34
+
35
+ id = value.has_key?("$ref") ? value["$ref"] : value["id"]
36
+ id = id.split("/")[-1]
37
+ property.reference_class.get(id)
38
+ end
39
+
40
+ # @api private
41
+ def self.bind(property)
42
+ property.instance_eval <<-RUBY, __FILE__, __LINE__ + 1
43
+ def primitive?(value)
44
+ puts "This is my primitive!"
45
+
46
+ value.kind_of?(Array)
47
+ end
48
+ RUBY
49
+ end
50
+
51
+ end
52
+ end
53
+
54
+ class Property
55
+ attr_accessor :reference_class
56
+
57
+ alias initialize_without_reference_class initialize
58
+ def initialize_with_reference_class(model, name, type, options = {})
59
+ @reference_class = options.delete(:reference)
60
+
61
+ initialize_without_reference_class(model, name, type, options)
62
+ end
63
+ alias initialize initialize_with_reference_class
64
+ end
65
+ end
@@ -0,0 +1,92 @@
1
+ require 'ruby-debug'
2
+ module DataMapper
3
+ module Types
4
+ class JsonReferenceCollection < Type
5
+ primitive String
6
+ length 5000
7
+ lazy true
8
+
9
+ def self.dump(value, property)
10
+ return nil unless value.class.eql?(Array) || value.blank?
11
+ value.map{|v| v.save! unless v.saved? }
12
+ results = value.map{|v| { "$ref" => "../#{property.reference_class.storage_name}/#{v[:id]}" }}
13
+
14
+ return results
15
+ end
16
+
17
+ def self.load(value, property)
18
+ return [] if value.nil?
19
+
20
+ value.map do |v|
21
+ if v.class.eql?(property.reference_class)
22
+ v
23
+ elsif v.class.eql?(Hash)
24
+ id = v.has_key?("$ref") ? v["$ref"] : v["id"]
25
+ id = id.split("/")[-1]
26
+ property.reference_class.get(id)
27
+ else
28
+ nil
29
+ end
30
+ end
31
+ end
32
+
33
+ # Should return the public value we are looking for.
34
+ def self.typecast(value, property)
35
+ return [] if value.nil?
36
+
37
+ value.map do |v|
38
+ if v.class.eql?(property.reference_class)
39
+ v
40
+ elsif v.class.eql?(Hash)
41
+ id = v.has_key?("$ref") ? v["$ref"] : v["id"]
42
+ id = id.split("/")[-1]
43
+ property.reference_class.get(id)
44
+ else
45
+ nil
46
+ end
47
+ end
48
+ end
49
+
50
+ # @api private
51
+ def self.bind(property)
52
+ model = property.model
53
+ name = property.name.to_s
54
+ instance_variable_name = property.instance_variable_name
55
+
56
+ property.instance_eval <<-RUBY, __FILE__, __LINE__ + 1
57
+ # Primitive error checking. Get it?
58
+ def primitive?(value)
59
+ value.kind_of?(Array)
60
+ end
61
+
62
+
63
+ RUBY
64
+
65
+ # This is hack`n slash that should be reworked.
66
+ model.class_eval <<-RUBY, __FILE__, __LINE__ +1
67
+ def #{name}
68
+ original_attributes[properties[#{name.inspect}]] = []
69
+ return #{instance_variable_name} if defined?(#{instance_variable_name})
70
+ #{instance_variable_name} = properties[#{name.inspect}].get(self)
71
+ end
72
+ RUBY
73
+
74
+ model.send(:resource_methods).add(name)
75
+
76
+ end
77
+
78
+ end
79
+ end
80
+
81
+ # Setup in json_reference.rb
82
+ # class Property
83
+ # attr_accessor :reference_class
84
+ #
85
+ # alias original_initialize initialize
86
+ # def initialize(model, name, type, options = {})
87
+ # @reference_class = options.delete(:reference)
88
+ #
89
+ # original_initialize(model, name, type, options)
90
+ # end
91
+ # end
92
+ end
@@ -89,7 +89,7 @@ describe DataMapper::Adapters::PersevereAdapter do
89
89
  end
90
90
 
91
91
  after :all do
92
- DataMapper::Model.descendants.each{|cur_model| cur_model.auto_migrate_down! }
92
+ DataMapper::Model.descendants.each{|cur_model| cur_model.auto_migrate_down! }
93
93
  end
94
94
 
95
95
  it_should_behave_like 'An Adapter'
@@ -120,7 +120,7 @@ describe DataMapper::Adapters::PersevereAdapter do
120
120
  it 'should create the json schema for the hash under the specified project' do
121
121
  @adapter.put_schema(@test_schema_hash_alt).should_not == false
122
122
  end
123
- end
123
+ end
124
124
 
125
125
  describe '#get_schema' do
126
126
  it 'should return all of the schemas (in json) if no name is provided' do
@@ -306,4 +306,84 @@ describe DataMapper::Adapters::PersevereAdapter do
306
306
  end
307
307
  end
308
308
 
309
+ describe 'associations' do
310
+ before(:all) do
311
+ class ::BlogPost
312
+ include DataMapper::Resource
313
+ property :id, Serial
314
+ property :title, String
315
+ property :body, Text
316
+
317
+ # property :comment, JsonReference, :reference => ::Comment
318
+ end
319
+
320
+ class ::Comment
321
+ include DataMapper::Resource
322
+ property :id, Serial
323
+ property :contents, Text
324
+ property :rating, Integer
325
+
326
+ property :blog_post, JsonReference, :reference => BlogPost
327
+ end
328
+
329
+ class ::Author
330
+ include DataMapper::Resource
331
+ property :id, Serial
332
+ property :name, String
333
+ end
334
+
335
+ class ::Address
336
+ include DataMapper::Resource
337
+ property :id, Serial
338
+ property :addr, String
339
+ end
340
+ end
341
+
342
+ before(:each) do
343
+ BlogPost.auto_migrate!
344
+ Author.auto_migrate!
345
+ Comment.auto_migrate!
346
+ Address.auto_migrate!
347
+ BlogPost.send(:property, :comments, DataMapper::Types::JsonReferenceCollection, :reference => Comment)
348
+ BlogPost.auto_migrate!
349
+ end
350
+
351
+ it "should create associations between models" do
352
+
353
+ # Create the instances
354
+ bpost = BlogPost.create(:title => "Test Post", :body => "This is the body of the test post.")
355
+ comment = Comment.new(:contents => "I think the post is great!", :rating => 4)
356
+ comment.blog_post = bpost
357
+ # bpost.comment = comment
358
+ # bpost.save
359
+ comment.save
360
+
361
+ Comment.first.blog_post.should be_kind_of(BlogPost)
362
+ Comment.first.blog_post.id.should eql(1)
363
+
364
+ # confirm it actually works with tests
365
+ # bpost.comments.length.should eql 2
366
+ end
367
+
368
+ it "should be able to handle collections of relationships" do
369
+ bpost = BlogPost.new(:title => "A new post", :body => "This one will have many comments")
370
+
371
+ bpost.comments = [Comment.new(:contents => "This is the best", :rating => 5)]
372
+ bpost.save
373
+ BlogPost.first.comments.should be_kind_of(Array)
374
+ BlogPost.first.comments.length.should eql(1)
375
+ BlogPost.first.comments.first.should be_kind_of(Comment)
376
+
377
+ bpost.comments << Comment.new(:contents => "No, this is the best!", :rating => 3)
378
+ bpost.save
379
+ BlogPost.first.comments.length.should eql(2)
380
+ end
381
+
382
+ after(:all) do
383
+ BlogPost.auto_migrate_down!
384
+ Author.auto_migrate_down!
385
+ Address.auto_migrate_down!
386
+ Comment.auto_migrate_down!
387
+ end
388
+ end
309
389
  end
@@ -66,7 +66,7 @@ describe Persevere do
66
66
  JSON.parse(result.body).should == @blobObj
67
67
  # This shouldn't be a 201, it should say something mean.
68
68
  end
69
- end
69
+ end
70
70
 
71
71
  #
72
72
  # Test GET to retrieve the list of classes from Persvr
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dm-persevere-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.47.1
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 48
8
+ - 0
9
+ version: 0.48.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - Ivan R. Judson
@@ -10,29 +15,35 @@ autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2010-03-23 00:00:00 -06:00
18
+ date: 2010-04-16 00:00:00 -06:00
14
19
  default_executable:
15
20
  dependencies:
16
21
  - !ruby/object:Gem::Dependency
17
22
  name: dm-core
18
- type: :runtime
19
- version_requirement:
20
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
21
25
  requirements:
22
26
  - - ">="
23
27
  - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ - 10
31
+ - 1
24
32
  version: 0.10.1
25
- version:
33
+ type: :runtime
34
+ version_requirements: *id001
26
35
  - !ruby/object:Gem::Dependency
27
36
  name: extlib
28
- type: :runtime
29
- version_requirement:
30
- version_requirements: !ruby/object:Gem::Requirement
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
31
39
  requirements:
32
40
  - - ">="
33
41
  - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
34
44
  version: "0"
35
- version:
45
+ type: :runtime
46
+ version_requirements: *id002
36
47
  description: A DataMapper Adapter for persevere
37
48
  email:
38
49
  - irjudson [a] gmail [d] com
@@ -54,6 +65,8 @@ files:
54
65
  - lib/model_json_support.rb
55
66
  - lib/persevere.rb
56
67
  - lib/persevere_adapter.rb
68
+ - lib/types/json_reference.rb
69
+ - lib/types/json_reference_collection.rb
57
70
  - persevere/History.txt
58
71
  - persevere/LICENSE.txt
59
72
  - persevere/Manifest.txt
@@ -77,18 +90,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
77
90
  requirements:
78
91
  - - ">="
79
92
  - !ruby/object:Gem::Version
93
+ segments:
94
+ - 0
80
95
  version: "0"
81
- version:
82
96
  required_rubygems_version: !ruby/object:Gem::Requirement
83
97
  requirements:
84
98
  - - ">="
85
99
  - !ruby/object:Gem::Version
100
+ segments:
101
+ - 0
86
102
  version: "0"
87
- version:
88
103
  requirements: []
89
104
 
90
105
  rubyforge_project:
91
- rubygems_version: 1.3.5
106
+ rubygems_version: 1.3.6
92
107
  signing_key:
93
108
  specification_version: 3
94
109
  summary: A DataMapper Adapter for persevere