persevere 0.17.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/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009-2010 Montana State University
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.txt ADDED
@@ -0,0 +1,85 @@
1
+ = dm-persevere-adapter
2
+
3
+ A DataMapper adapter for Persevere (http://www.persvr.org/)
4
+
5
+ This requires the persevere gem (http://github.com/irjudson/persevere) which provides a ruby interface to Persevere.
6
+
7
+ == Usage
8
+
9
+ DM Persevere Adapter is very simple and very similar to the REST
10
+ Adapter, however it has two differences: 1) instead of XML it uses
11
+ JSON, and 2) Persevere supports typing using JSON Schema. These
12
+ differences make it valuable to have a separate DM adapter
13
+ specifically for Persevere so it can leverage richer aspects of
14
+ persevere.
15
+
16
+ The setup and resource mapping is identical to standard datamapper
17
+ objects, as can be seen below.
18
+
19
+ DataMapper.setup(:default, {
20
+ :adapter => 'persevere',
21
+ :host => 'localhost',
22
+ :port => '8080'
23
+ })
24
+
25
+ class MyUser
26
+ include DataMapper::Resource
27
+
28
+ property :id, Serial
29
+ property :uuid, String
30
+ property :name, String
31
+ property :first_name, String
32
+ property :last_name, String
33
+ property :groupid, Integer
34
+ property :userid, Integer
35
+ property :username, String
36
+ property :homedirectory, String
37
+
38
+ end
39
+
40
+ To use with Rails, you can put this in your environment.rb:
41
+ config.gem "dm-core"
42
+ config.gem "data_objects"
43
+ config.gem "dm-persevere-adapter", :lib => 'persevere_adapter'
44
+
45
+ With a database.yml:
46
+
47
+ development: &defaults
48
+ :adapter: persevere
49
+ :host: localhost
50
+ :port: 8080
51
+
52
+ test:
53
+ <<: *defaults
54
+
55
+ production:
56
+ <<: *defaults
57
+
58
+ == Code
59
+
60
+ # Create
61
+ user = MyUser.new(:username => "dmtest", :uuid => UUID.random_create().to_s,
62
+ :name => "DataMapper Test", :homedirectory => "/home/dmtest",
63
+ :first_name => "DataMapperTest", :last_name => "User",
64
+ :userid => 3, :groupid => 500)
65
+ user.save
66
+
67
+ # Retrieve
68
+ user = MyUser.first(:netid => 'dmtest')
69
+ puts user
70
+
71
+ # Modify
72
+ if user.update_attributes(:name => 'DM Test')
73
+ puts user
74
+ else
75
+ puts "Failed to update attributes."
76
+ end
77
+
78
+ # Delete
79
+ result = user.destroy
80
+ puts "Result: #{result}"
81
+
82
+ == To Do:
83
+
84
+ - Make a do-adapter for persevere.
85
+ - Cleanup Documentation
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ require 'rubygems'
2
+ require 'pathname'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gemspec|
7
+ gemspec.name = %q{dm-persevere-adapter}
8
+ gemspec.summary = %q{A DataMapper Adapter for persevere}
9
+ gemspec.description = %q{A DataMapper Adapter for persevere}
10
+ gemspec.email = ["irjudson [a] gmail [d] com"]
11
+ gemspec.homepage = %q{http://github.com/yogo/dm-persevere-adapter}
12
+ gemspec.authors = ["Ivan R. Judson", "The Yogo Data Management Development Team" ]
13
+ gemspec.rdoc_options = ["--main", "README.txt"]
14
+ gemspec.add_dependency(%q<dm-core>, [">= 0.10.1"])
15
+ gemspec.add_dependency(%q<extlib>)
16
+ end
17
+ Jeweler::Tasks.new do |gemspec|
18
+ gemspec.name = %q{persevere}
19
+ gemspec.summary = %q{A ruby wrapper for persevere}
20
+ gemspec.description = %q{A ruby wrapper for persevere}
21
+ gemspec.email = ["irjudson [a] gmail [d] com"]
22
+ gemspec.homepage = %q{http://github.com/yogo/persevere}
23
+ gemspec.authors = ["Ivan R. Judson", "The Yogo Data Management Development Team" ]
24
+ gemspec.rdoc_options = ["--main", "persevere/README.txt"]
25
+ gemspec.files = ["LICENSE.txt", "persevere/History.txt", "persevere/README.txt", "Rakefile", "lib/persevere.rb"]
26
+ gemspec.test_files = ["spec/persevere_spec.rb", "spec/spec.opts", "spec/spec_helper.rb"]
27
+ end
28
+ Jeweler::GemcutterTasks.new
29
+ rescue LoadError
30
+ puts "Jeweler not available. Install it with: gem install jeweler"
31
+ end
32
+
33
+ ROOT = Pathname(__FILE__).dirname.expand_path
34
+ JRUBY = RUBY_PLATFORM =~ /java/
35
+ WINDOWS = Gem.win_platform?
36
+ SUDO = (WINDOWS || JRUBY) ? '' : ('sudo' unless ENV['SUDOLESS'])
37
+
38
+ Pathname.glob(ROOT.join('tasks/**/*.rb').to_s).each { |f| require f }
data/lib/persevere.rb ADDED
@@ -0,0 +1,106 @@
1
+ #
2
+ # Yogo Data Management Toolkit : Persevere Wrapper
3
+ # (c) 2008-2009 Montana State University
4
+ # Ivan R. Judson
5
+ #
6
+ # This provides a relatively simple interface to access the Persevere
7
+ # JSON data store. More information about Persevere can be found here:
8
+ # http://www.persvr.org/
9
+ #
10
+ require 'net/http'
11
+ require 'uri'
12
+
13
+ require 'rubygems'
14
+ require 'json'
15
+
16
+ class PersevereResult
17
+ attr_reader :location, :code, :message, :body
18
+
19
+ def PersevereResult.make(response)
20
+ return PersevereResult.new(response["Location"], response.code,
21
+ response.msg, response.body)
22
+ end
23
+
24
+ def initialize(location, code, message, body)
25
+ @location = location
26
+ @code = code
27
+ @message = message
28
+ @body = body
29
+ end
30
+
31
+ def to_s
32
+ super + " < Location: #{ @location } Code: #{ @code } Message: #{ @message } >"
33
+ end
34
+ end
35
+
36
+ class Persevere
37
+ VERSION = '1.1'
38
+ HEADERS = { 'Accept' => 'application/json',
39
+ 'Content-Type' => 'application/json'
40
+ }
41
+
42
+ attr_accessor :server_url, :pservr
43
+
44
+
45
+ def initialize(url)
46
+ @server_url = url
47
+ server = URI.parse(@server_url)
48
+ @persevere = Net::HTTP.new(server.host, server.port)
49
+ end
50
+
51
+ # Pass in a resource hash
52
+ def create(path, resource)
53
+ json_blob = resource.to_json
54
+ response = nil
55
+ while response.nil?
56
+ begin
57
+ response = @persevere.send_request('POST', path, json_blob, HEADERS)
58
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
59
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
60
+ puts "Persevere Create Failed: #{e}, Trying again."
61
+ end
62
+ end
63
+ return PersevereResult.make(response)
64
+ end
65
+
66
+ def retrieve(path)
67
+ response = nil
68
+ while response.nil?
69
+ begin
70
+ response = @persevere.send_request('GET', path, nil, HEADERS)
71
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
72
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
73
+ puts "Persevere Create Failed: #{e}, Trying again."
74
+ end
75
+ end
76
+ return PersevereResult.make(response)
77
+ end
78
+
79
+ def update(path, resource)
80
+ json_blob = resource.to_json
81
+ # puts "JSON to PERSEVERE: #{json_blob}"
82
+ response = nil
83
+ while response.nil?
84
+ begin
85
+ response = @persevere.send_request('PUT', path, json_blob, HEADERS)
86
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
87
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
88
+ puts "Persevere Create Failed: #{e}, Trying again."
89
+ end
90
+ end
91
+ return PersevereResult.make(response)
92
+ end
93
+
94
+ def delete(path)
95
+ response = nil
96
+ while response.nil?
97
+ begin
98
+ response = @persevere.send_request('DELETE', path, nil, HEADERS)
99
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
100
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
101
+ puts "Persevere Create Failed: #{e}, Trying again."
102
+ end
103
+ end
104
+ return PersevereResult.make(response)
105
+ end
106
+ end # class Persevere
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2009-02-19
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
@@ -0,0 +1,90 @@
1
+ = ruby persevere client
2
+
3
+ * http://github.com/irjudson/persevere
4
+
5
+ == DESCRIPTION:
6
+
7
+ This gem provides a simple ruby wrapper around the persevere JSON document data store available from http://www.persvr.org.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ Currently this provides a very simple RESTful interface to persevere. Data to be stored in persevere should be sent as hashes. To make this more robust it should provide some schema/table support, plus validate data against the schema/table. This exists in persevere, but is not exposed by this wrapper.
12
+
13
+ == SYNOPSIS:
14
+
15
+ #!/usr/bin/env ruby
16
+ #
17
+ require 'persevere'
18
+
19
+ #
20
+ # Create an object to interact with Persevere
21
+ #
22
+ p = Persevere.new('http://localhost:8080')
23
+
24
+ #
25
+ # Test POST to create a new class
26
+ #
27
+ print "\nTesting POST..."
28
+ tstObj = { 'id' => 'tstObj', 'extends' => { '$ref' => 'Object' } }
29
+ result = p.create('/Class/', tstObj)
30
+ print "Response:\n"
31
+ puts result
32
+
33
+ #
34
+ # Test GET to retrieve the list of classes from Persvr
35
+ #
36
+ print "\nTesting GET..."
37
+ result = p.retrieve('/Class')
38
+ print "Response:\n"
39
+ puts result
40
+
41
+ #
42
+ # Test PUT to modify an existing class
43
+ #
44
+ print "\nTesting PUT..."
45
+ tstObj['tstAttribute'] = 42
46
+ result = p.update('/Class/tstObj', tstObj)
47
+ print "Response:\n"
48
+ puts result
49
+
50
+ #
51
+ # Test DELETE to remove the previously created and modified class
52
+ #
53
+ print "\nTesting DELETE..."
54
+ result = p.delete('/Class/tstObj')
55
+ print "Response:\n"
56
+ puts result
57
+
58
+ == REQUIREMENTS:
59
+
60
+ * Persevere installed somewhere
61
+ * JSON gem
62
+
63
+ == INSTALL:
64
+
65
+ sudo gem install persevere
66
+
67
+ == LICENSE:
68
+
69
+ (The MIT License)
70
+
71
+ Copyright (c) 2009 Montana State University
72
+
73
+ Permission is hereby granted, free of charge, to any person obtaining
74
+ a copy of this software and associated documentation files (the
75
+ 'Software'), to deal in the Software without restriction, including
76
+ without limitation the rights to use, copy, modify, merge, publish,
77
+ distribute, sublicense, and/or sell copies of the Software, and to
78
+ permit persons to whom the Software is furnished to do so, subject to
79
+ the following conditions:
80
+
81
+ The above copyright notice and this permission notice shall be
82
+ included in all copies or substantial portions of the Software.
83
+
84
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
85
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
86
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
87
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
88
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
89
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
90
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,119 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require Pathname(__FILE__).dirname.expand_path.parent + 'lib/persevere'
3
+
4
+ describe Persevere do
5
+ #
6
+ # Create an object to interact with Persevere
7
+ #
8
+ before :all do
9
+ @p = Persevere.new('http://localhost:8080')
10
+
11
+ @blobObj = {
12
+ 'id' => 'Yogo',
13
+ 'properties' => {
14
+ 'cid' => {'type' => 'string' },
15
+ 'parent' => { 'type' => 'string'},
16
+ 'data' => { 'type' => 'string'}
17
+ }
18
+ }
19
+
20
+ @corruptObj = {
21
+ 'id' => 'Corrupt',
22
+ 'properties' => {
23
+ 'id' => 1234,
24
+ 'parent' => { 'type' => 'string'},
25
+ 'data' => { 'type' => 'string'}
26
+ }
27
+ }
28
+
29
+ @mockObj = {
30
+ 'id' => 'Yogo',
31
+ 'properties' => {
32
+ 'cid' => {'type' => 'string' },
33
+ 'parent' => { 'type' => 'string'},
34
+ 'data' => { 'type' => 'string'}
35
+ },
36
+ 'prototype' => {}
37
+ }
38
+ end
39
+
40
+ #
41
+ # Test POST to create a new class
42
+ #
43
+ describe '#post' do
44
+ it 'should create a new object in persevere' do
45
+ result = @p.create('/Class/', @blobObj)
46
+ result.code.should == "201"
47
+ JSON.parse(result.body).should == @mockObj
48
+ end
49
+
50
+ it 'should not allow posting with a bad object' do
51
+ result = @p.create('/Class/', @corruptObj)
52
+ result.code.should == "500"
53
+ result.body.should == "\"Can not modify queries\""
54
+ end
55
+
56
+ it 'should not allow posting to an existing object/id/path' do
57
+ result = @p.create('/Class/', @blobObj)
58
+ result.code.should == "201"
59
+ JSON.parse(result.body).should == @blobObj
60
+ # result.body.should == "\"Can not modify queries\""
61
+ # This shouldn't be a 201, it should say something mean.
62
+ end
63
+ end
64
+
65
+ #
66
+ # Test GET to retrieve the list of classes from Persvr
67
+ #
68
+ describe '#get' do
69
+ it 'should retrieve the previously created object from persevere' do
70
+ result = @p.retrieve('/Class/Yogo')
71
+ result.code.should == "200"
72
+ JSON.parse(result.body).should == @blobObj
73
+ end
74
+
75
+ it 'should 404 on a non-existent object' do
76
+ result = @p.retrieve('/Class/NotThere')
77
+ result.code.should == "404"
78
+ result.message.should == "Not Found"
79
+ end
80
+ end
81
+
82
+ #
83
+ # Test PUT to modify an existing class
84
+ #
85
+ describe '#put' do
86
+ it 'should modify the previously created object in persevere' do
87
+ @blobObj['properties']['tstAttribute'] = { 'type' => 'string' }
88
+ result = @p.update('/Class/Yogo', @blobObj)
89
+ result.code.should == "200"
90
+ JSON.parse(result.body).should == @blobObj
91
+ end
92
+
93
+ it 'should fail to modify a non-existent item' do
94
+ result = @p.update('/Class/NotThere', @blobObj)
95
+ result.code.should == "500"
96
+ result.body.should == "\"id does not match location\""
97
+ # This should be a 404 and not throw a persevere server exception
98
+ end
99
+ end
100
+
101
+ #
102
+ # Test DELETE to remove the previously created and modified class
103
+ #
104
+ describe '#delete' do
105
+ it 'should remove the previously created and modified object from persevere' do
106
+ result = @p.delete('/Class/Yogo')
107
+ result.code.should == "204"
108
+ @p.retrieve('/Class/Yogo').code.should == "404"
109
+ end
110
+
111
+ it 'should fail to delete a non-existent item' do
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
117
+ end
118
+ end
119
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,14 @@
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
+ #
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: persevere
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.17.0
5
+ platform: ruby
6
+ authors:
7
+ - Ivan R. Judson
8
+ - The Yogo Data Management Development Team
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2010-01-11 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: A ruby wrapper for persevere
18
+ email:
19
+ - irjudson [a] gmail [d] com
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files:
25
+ - LICENSE.txt
26
+ - README.txt
27
+ files:
28
+ - LICENSE.txt
29
+ - Rakefile
30
+ - lib/persevere.rb
31
+ - persevere/History.txt
32
+ - persevere/README.txt
33
+ - README.txt
34
+ has_rdoc: true
35
+ homepage: http://github.com/yogo/persevere
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --main
41
+ - persevere/README.txt
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.3.5
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: A ruby wrapper for persevere
63
+ test_files:
64
+ - spec/persevere_spec.rb
65
+ - spec/spec.opts
66
+ - spec/spec_helper.rb