dm-persevere-adapter 0.70.0 → 0.71.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 +1 -1
- data/lib/persevere.rb +25 -11
- data/lib/persevere_adapter.rb +28 -32
- data/spec/persevere_adapter_spec.rb +59 -1
- metadata +13 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.71.0
|
data/lib/persevere.rb
CHANGED
@@ -59,18 +59,24 @@ class Persevere
|
|
59
59
|
def initialize(url)
|
60
60
|
@server_url = url
|
61
61
|
server = URI.parse(@server_url)
|
62
|
-
@
|
62
|
+
@base_uri = server.path || ''
|
63
63
|
@persevere = Net::HTTP.new(server.host, server.port)
|
64
|
+
@client_id = "dm-persevere-adapter-#{(rand*1000)}" # just need a small random string
|
65
|
+
@sequence_id = 0
|
64
66
|
end
|
65
67
|
|
66
68
|
# Pass in a resource hash
|
67
69
|
def create(path, resource, headers = {})
|
68
|
-
path = @
|
69
|
-
|
70
|
+
path = @base_uri + path
|
71
|
+
if headers.has_key?('Content-Type') && headers['Content-Type'] != 'application/json'
|
72
|
+
json_blob = resource
|
73
|
+
else
|
74
|
+
json_blob = resource.delete_if{|key,value| value.nil? }.to_json
|
75
|
+
end
|
70
76
|
response = nil
|
71
77
|
while response.nil?
|
72
78
|
begin
|
73
|
-
response = @persevere.send_request('POST', URI.encode(path), json_blob,
|
79
|
+
response = @persevere.send_request('POST', URI.encode(path), json_blob, default_headers.merge(headers))
|
74
80
|
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
75
81
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
76
82
|
puts "Persevere Create Failed: #{e}, Trying again."
|
@@ -80,11 +86,11 @@ class Persevere
|
|
80
86
|
end
|
81
87
|
|
82
88
|
def retrieve(path, headers = {})
|
83
|
-
path = @
|
89
|
+
path = @base_uri + path
|
84
90
|
response = nil
|
85
91
|
while response.nil?
|
86
92
|
begin
|
87
|
-
response = @persevere.send_request('GET', URI.encode(path), nil,
|
93
|
+
response = @persevere.send_request('GET', URI.encode(path), nil, default_headers.merge(headers))
|
88
94
|
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
89
95
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
90
96
|
puts "Persevere Retrieve Failed: #{e}, Trying again."
|
@@ -94,12 +100,12 @@ class Persevere
|
|
94
100
|
end
|
95
101
|
|
96
102
|
def update(path, resource, headers = {})
|
97
|
-
path = @
|
103
|
+
path = @base_uri + path
|
98
104
|
json_blob = resource.to_json
|
99
105
|
response = nil
|
100
106
|
while response.nil?
|
101
107
|
begin
|
102
|
-
response = @persevere.send_request('PUT', URI.encode(path), json_blob,
|
108
|
+
response = @persevere.send_request('PUT', URI.encode(path), json_blob, default_headers.merge(headers))
|
103
109
|
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
104
110
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
105
111
|
puts "Persevere Create Failed: #{e}, Trying again."
|
@@ -109,11 +115,11 @@ class Persevere
|
|
109
115
|
end
|
110
116
|
|
111
117
|
def delete(path, headers = {})
|
112
|
-
path = @
|
118
|
+
path = @base_uri + path
|
113
119
|
response = nil
|
114
120
|
while response.nil?
|
115
121
|
begin
|
116
|
-
response = @persevere.send_request('DELETE', URI.encode(path), nil,
|
122
|
+
response = @persevere.send_request('DELETE', URI.encode(path), nil, default_headers.merge(headers))
|
117
123
|
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
118
124
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
119
125
|
puts "Persevere Create Failed: #{e}, Trying again."
|
@@ -121,4 +127,12 @@ class Persevere
|
|
121
127
|
end
|
122
128
|
return PersevereResult.make(response)
|
123
129
|
end
|
124
|
-
|
130
|
+
|
131
|
+
private
|
132
|
+
|
133
|
+
def default_headers
|
134
|
+
@sequence_id += 1
|
135
|
+
HEADERS.merge( {'Seq-Id' => @sequence_id.to_s, 'Client-Id' => @client_id } )
|
136
|
+
end
|
137
|
+
|
138
|
+
end # class Persevere
|
data/lib/persevere_adapter.rb
CHANGED
@@ -267,8 +267,7 @@ module DataMapper
|
|
267
267
|
path = "/#{resource.model.storage_name}/"
|
268
268
|
# Invoke to_json_hash with a boolean to indicate this is a create
|
269
269
|
# We might want to make this a post-to_json_hash cleanup instead
|
270
|
-
payload = resource.to_json_hash(false)
|
271
|
-
# scrub_data(payload)
|
270
|
+
payload = resource.to_json_hash(false).delete_if{|key,value| value.nil? }
|
272
271
|
DataMapper.logger.debug("--> PATH/PAYLOAD: #{path} #{payload.inspect}")
|
273
272
|
response = @persevere.create(path, payload)
|
274
273
|
|
@@ -332,7 +331,6 @@ module DataMapper
|
|
332
331
|
tblname = resource.model.storage_name
|
333
332
|
path = "/#{tblname}/#{resource.key.first}"
|
334
333
|
payload = resource.to_json_hash()
|
335
|
-
# scrub_data(payload)
|
336
334
|
DataMapper.logger.debug("--> PATH/PAYLOAD: #{path} #{payload.inspect}")
|
337
335
|
result = @persevere.update(path, payload)
|
338
336
|
|
@@ -381,8 +379,6 @@ module DataMapper
|
|
381
379
|
# @api semipublic
|
382
380
|
def read_many(query)
|
383
381
|
connect if @persevere.nil?
|
384
|
-
|
385
|
-
# check_schemas
|
386
382
|
|
387
383
|
resources = Array.new
|
388
384
|
tblname = query.model.storage_name
|
@@ -411,15 +407,11 @@ module DataMapper
|
|
411
407
|
if value.is_a?(Hash)
|
412
408
|
if value.has_key?("$ref")
|
413
409
|
value = value["$ref"].split("/")[-1]
|
414
|
-
else
|
415
|
-
# value = value["id"].split("/")[-1]
|
416
410
|
end
|
417
411
|
elsif value.is_a?(Array)
|
418
412
|
value = value.map do |v|
|
419
413
|
if v.has_key?("$ref")
|
420
414
|
v = v["$ref"].split("/")[-1]
|
421
|
-
else
|
422
|
-
# v = v["id"].split("/")[-1]
|
423
415
|
end
|
424
416
|
end
|
425
417
|
end
|
@@ -470,8 +462,6 @@ module DataMapper
|
|
470
462
|
connect if @persevere.nil?
|
471
463
|
|
472
464
|
deleted = 0
|
473
|
-
|
474
|
-
# check_schemas
|
475
465
|
|
476
466
|
if ! query.is_a?(DataMapper::Query)
|
477
467
|
resources = [query].flatten
|
@@ -500,8 +490,6 @@ module DataMapper
|
|
500
490
|
def get_schema(name = nil, project = nil)
|
501
491
|
path = nil
|
502
492
|
single = false
|
503
|
-
|
504
|
-
# check_schemas
|
505
493
|
|
506
494
|
if name.nil? & project.nil?
|
507
495
|
path = "/Class/"
|
@@ -520,7 +508,6 @@ module DataMapper
|
|
520
508
|
schema['properties']['id'] = { 'type' => "serial", 'index' => true }
|
521
509
|
end
|
522
510
|
end
|
523
|
-
# save_schemas
|
524
511
|
|
525
512
|
return name.nil? ? schemas : schemas[0..0]
|
526
513
|
else
|
@@ -542,14 +529,11 @@ module DataMapper
|
|
542
529
|
end
|
543
530
|
end
|
544
531
|
|
545
|
-
# check_schemas
|
546
|
-
|
547
532
|
scrub_schema(schema_hash['properties'])
|
548
533
|
schema_hash['extends'] = { "$ref" => "/Class/Versioned" } if @options[:versioned]
|
549
|
-
|
534
|
+
schema_hash.delete_if{|key,value| value.nil? }
|
550
535
|
result = @persevere.create(path, schema_hash)
|
551
536
|
if result.code == '201'
|
552
|
-
# save_schemas
|
553
537
|
|
554
538
|
return JSON.parse(result.body)
|
555
539
|
else
|
@@ -565,8 +549,6 @@ module DataMapper
|
|
565
549
|
scrub_schema(payload['properties'])
|
566
550
|
payload['extends'] = { "$ref" => "/Class/Versioned" } if @options[:versioned]
|
567
551
|
|
568
|
-
# check_schemas
|
569
|
-
|
570
552
|
if project.nil?
|
571
553
|
path = "/Class/#{id}"
|
572
554
|
else
|
@@ -576,7 +558,6 @@ module DataMapper
|
|
576
558
|
result = @persevere.update(path, payload)
|
577
559
|
|
578
560
|
if result.code == '200'
|
579
|
-
# save_schemas
|
580
561
|
return result.body
|
581
562
|
else
|
582
563
|
return false
|
@@ -595,14 +576,11 @@ module DataMapper
|
|
595
576
|
DataMapper.logger.error("You need an id key/value in the hash")
|
596
577
|
end
|
597
578
|
end
|
598
|
-
|
599
|
-
# check_schemas
|
600
|
-
|
579
|
+
|
601
580
|
path = "/Class/#{schema_hash['id']}"
|
602
581
|
result = @persevere.delete(path)
|
603
582
|
|
604
583
|
if result.code == "204"
|
605
|
-
# save_schemas
|
606
584
|
return true
|
607
585
|
else
|
608
586
|
return false
|
@@ -642,7 +620,12 @@ module DataMapper
|
|
642
620
|
@options[:scheme] = @options[:adapter]
|
643
621
|
@options.delete(:scheme)
|
644
622
|
|
645
|
-
@resource_naming_convention = NamingConventions::Resource::Underscored
|
623
|
+
# @resource_naming_convention = NamingConventions::Resource::Underscored
|
624
|
+
@resource_naming_convention = lambda do |value|
|
625
|
+
# value.split('::').map{ |val| Extlib::Inflection.underscore(val) }.join('__')
|
626
|
+
Extlib::Inflection.underscore(value).gsub('/', '__')
|
627
|
+
end
|
628
|
+
|
646
629
|
@identity_maps = {}
|
647
630
|
@persevere = nil
|
648
631
|
@prepped = false
|
@@ -729,7 +712,7 @@ module DataMapper
|
|
729
712
|
# If the user specified a versioned datastore load the versioning REST code
|
730
713
|
#
|
731
714
|
unless get_classes.include?("Versioned") && @options[:versioned]
|
732
|
-
versioned_class
|
715
|
+
versioned_class =<<-EOF
|
733
716
|
{
|
734
717
|
id: "Versioned",
|
735
718
|
prototype: {
|
@@ -775,12 +758,25 @@ module DataMapper
|
|
775
758
|
}
|
776
759
|
}
|
777
760
|
EOF
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
761
|
+
|
762
|
+
response = @persevere.create('/Class/', versioned_class, { 'Content-Type' => 'application/javascript' } )
|
763
|
+
|
764
|
+
# Check the response, this needs to be more robust and raise
|
765
|
+
# exceptions when there's a problem
|
766
|
+
if response.code == "201"# good:
|
767
|
+
DataMapper.logger.info("Created versioned class.")
|
768
|
+
else
|
769
|
+
DataMapper.logger.info("Failed to create versioned class.")
|
783
770
|
end
|
771
|
+
|
772
|
+
# headers = { 'Content-Type' => 'application/javascript', 'Accept' => 'application/json' }
|
773
|
+
# begin
|
774
|
+
# puts "POST #{URI.encode('/Class')}, #{versioned_class}, #{headers.inspect}"
|
775
|
+
# response = @persevere.persevere.send_request('POST', URI.encode('/Class/'), versioned_class, headers )
|
776
|
+
# rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
777
|
+
# Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
778
|
+
# DataMapper.logger.error("Persevere Create Failed: #{e}, Trying again.")
|
779
|
+
# end
|
784
780
|
end
|
785
781
|
end
|
786
782
|
end # class PersevereAdapter
|
@@ -11,7 +11,7 @@ require Pathname(__FILE__).dirname.expand_path.parent + 'lib/persevere_adapter'
|
|
11
11
|
|
12
12
|
describe DataMapper::Adapters::PersevereAdapter do
|
13
13
|
before :all do
|
14
|
-
DataMapper::Logger.new(STDOUT, :debug)
|
14
|
+
# DataMapper::Logger.new(STDOUT, :debug)
|
15
15
|
@adapter = DataMapper.setup(:default, {
|
16
16
|
:adapter => 'persevere',
|
17
17
|
:host => 'localhost',
|
@@ -518,6 +518,64 @@ describe DataMapper::Adapters::PersevereAdapter do
|
|
518
518
|
|
519
519
|
Bozon.first.nugatons.length.should be(1)
|
520
520
|
end
|
521
|
+
|
522
|
+
it "should remove resources from both sides of the relationship when there are many on each side" do
|
523
|
+
|
524
|
+
bozon1 = Bozon.create(:author => 'Jade', :title => "Jade's the author")
|
525
|
+
bozon2 = Bozon.create(:author => 'Ivan', :title => "Blow up the world!")
|
526
|
+
nugat1 = Nugaton.new(:name => "numero uno")
|
527
|
+
nugat2 = Nugaton.new(:name => "numero duo")
|
528
|
+
|
529
|
+
bozon1.nugatons.push(nugat1, nugat2)
|
530
|
+
bozon2.nugatons = [nugat1,nugat2]
|
531
|
+
bozon1.save
|
532
|
+
bozon2.save
|
533
|
+
|
534
|
+
bozon1.nugatons.delete(nugat1)
|
535
|
+
bozon1.save
|
536
|
+
|
537
|
+
# Bozon1 should have only nugaton2
|
538
|
+
Bozon.get(bozon1.id).nugatons.length.should eql 1
|
539
|
+
Bozon.get(bozon1.id).nugatons.should_not include(nugat1)
|
540
|
+
Bozon.get(bozon1.id).nugatons.should include(nugat2)
|
541
|
+
|
542
|
+
# Bozon2 should have both nugatons
|
543
|
+
Bozon.get(bozon2.id).nugatons.length.should eql 2
|
544
|
+
Bozon.get(bozon2.id).nugatons.should include(nugat1)
|
545
|
+
Bozon.get(bozon2.id).nugatons.should include(nugat2)
|
546
|
+
|
547
|
+
# Nugaton1 should have Bozon2
|
548
|
+
Nugaton.get(nugat1.id).bozons.length.should eql 1
|
549
|
+
Nugaton.get(nugat1.id).bozons.should_not include(bozon1)
|
550
|
+
Nugaton.get(nugat1.id).bozons.should include(bozon2)
|
551
|
+
|
552
|
+
# Nugaton2 should have both bozons
|
553
|
+
Nugaton.get(nugat2.id).bozons.length.should eql 2
|
554
|
+
Nugaton.get(nugat2.id).bozons.should include(bozon1)
|
555
|
+
Nugaton.get(nugat2.id).bozons.should include(bozon2)
|
556
|
+
end
|
557
|
+
|
558
|
+
it "should act sanely" do
|
559
|
+
Bozon.has(Infinity, :nugatons, {:through => DataMapper::Resource})
|
560
|
+
Nugaton.has(Infinity, :bozons, {:through => DataMapper::Resource})
|
561
|
+
Bozon.auto_upgrade!
|
562
|
+
Nugaton.auto_upgrade!
|
563
|
+
|
564
|
+
bozon = Bozon.create(:author => 'Jade', :title => "Jade's the author")
|
565
|
+
|
566
|
+
nugat1 = Nugaton.create(:name => "numero uno")
|
567
|
+
nugat2 = Nugaton.create(:name => "numero duo")
|
568
|
+
|
569
|
+
nugat1.bozons << bozon
|
570
|
+
nugat1.save
|
571
|
+
|
572
|
+
n = Nugaton.get(nugat2.id)
|
573
|
+
n.bozons << Bozon.first
|
574
|
+
n.save
|
575
|
+
|
576
|
+
Bozon.get(bozon.id).nugatons.length.should eql 2
|
577
|
+
|
578
|
+
end
|
521
579
|
|
522
580
|
end
|
523
581
|
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-persevere-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 259
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
|
-
-
|
8
|
+
- 71
|
8
9
|
- 0
|
9
|
-
version: 0.
|
10
|
+
version: 0.71.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Ivan R. Judson
|
@@ -15,16 +16,18 @@ autorequire:
|
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2010-
|
19
|
+
date: 2010-07-01 00:00:00 -06:00
|
19
20
|
default_executable:
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
22
23
|
name: dm-core
|
23
24
|
prerelease: false
|
24
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
25
27
|
requirements:
|
26
28
|
- - ">="
|
27
29
|
- !ruby/object:Gem::Version
|
30
|
+
hash: 51
|
28
31
|
segments:
|
29
32
|
- 0
|
30
33
|
- 10
|
@@ -36,9 +39,11 @@ dependencies:
|
|
36
39
|
name: extlib
|
37
40
|
prerelease: false
|
38
41
|
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
39
43
|
requirements:
|
40
44
|
- - ">="
|
41
45
|
- !ruby/object:Gem::Version
|
46
|
+
hash: 3
|
42
47
|
segments:
|
43
48
|
- 0
|
44
49
|
version: "0"
|
@@ -90,23 +95,27 @@ rdoc_options:
|
|
90
95
|
require_paths:
|
91
96
|
- lib
|
92
97
|
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
93
99
|
requirements:
|
94
100
|
- - ">="
|
95
101
|
- !ruby/object:Gem::Version
|
102
|
+
hash: 3
|
96
103
|
segments:
|
97
104
|
- 0
|
98
105
|
version: "0"
|
99
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
100
108
|
requirements:
|
101
109
|
- - ">="
|
102
110
|
- !ruby/object:Gem::Version
|
111
|
+
hash: 3
|
103
112
|
segments:
|
104
113
|
- 0
|
105
114
|
version: "0"
|
106
115
|
requirements: []
|
107
116
|
|
108
117
|
rubyforge_project:
|
109
|
-
rubygems_version: 1.3.
|
118
|
+
rubygems_version: 1.3.7
|
110
119
|
signing_key:
|
111
120
|
specification_version: 3
|
112
121
|
summary: A DataMapper Adapter for persevere
|