persevere 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
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