dm-persevere-adapter 0.47.1 → 0.48.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.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