parse-ruby-client 0.2.0 → 0.3.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.
- checksums.yaml +15 -0
- data/.travis.yml +2 -1
- data/Gemfile +4 -6
- data/Gemfile.lock +18 -18
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/example.rb +2 -1
- data/fixtures/vcr_cassettes/test_batch_update_nils_delete_keys.yml +57 -0
- data/fixtures/vcr_cassettes/test_empty_response.yml +72 -0
- data/fixtures/vcr_cassettes/test_get_missing.yml +95 -38
- data/fixtures/vcr_cassettes/test_image_file_associate_with_object.yml +2089 -0
- data/fixtures/vcr_cassettes/test_image_file_save.yml +1928 -0
- data/fixtures/vcr_cassettes/test_object_id.yml +56 -0
- data/fixtures/vcr_cassettes/test_reset_password.yml +109 -0
- data/fixtures/vcr_cassettes/test_retries.yml +357 -0
- data/fixtures/vcr_cassettes/test_retries_404.yml +72 -0
- data/fixtures/vcr_cassettes/test_retries_404_correct.yml +72 -0
- data/fixtures/vcr_cassettes/test_retries_json_error.yml +357 -0
- data/fixtures/vcr_cassettes/test_retries_server_error.yml +357 -0
- data/fixtures/vcr_cassettes/test_server_update.yml +248 -191
- data/fixtures/vcr_cassettes/test_user_login.yml +276 -0
- data/fixtures/vcr_cassettes/test_xget.yml +280 -0
- data/lib/faraday/better_retry.rb +94 -0
- data/lib/faraday/extended_parse_json.rb +39 -0
- data/lib/faraday/get_method_override.rb +32 -0
- data/lib/parse-ruby-client.rb +9 -9
- data/lib/parse/batch.rb +2 -3
- data/lib/parse/client.rb +72 -161
- data/lib/parse/cloud.rb +2 -1
- data/lib/parse/datatypes.rb +6 -1
- data/lib/parse/error.rb +7 -3
- data/lib/parse/installation.rb +18 -0
- data/lib/parse/model.rb +2 -1
- data/lib/parse/object.rb +7 -1
- data/lib/parse/protocol.rb +10 -0
- data/lib/parse/push.rb +3 -0
- data/lib/parse/query.rb +5 -2
- data/lib/parse/user.rb +1 -0
- data/lib/parse/util.rb +2 -0
- data/parse-ruby-client.gemspec +35 -15
- data/test/helper.rb +55 -1
- data/test/middleware/better_retry_test.rb +57 -0
- data/test/middleware/extend_parse_json_test.rb +55 -0
- data/test/test_client.rb +78 -28
- data/test/test_datatypes.rb +14 -0
- data/test/test_object.rb +16 -0
- metadata +39 -34
- data/lib/parse/http_client.rb +0 -84
@@ -0,0 +1,94 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'ostruct'
|
3
|
+
module Faraday
|
4
|
+
# Catches exceptions and retries each request a limited number of times.
|
5
|
+
#
|
6
|
+
# By default, it retries 2 times and handles only timeout exceptions. It can
|
7
|
+
# be configured with an arbitrary number of retries, a list of exceptions to
|
8
|
+
# handle an a retry interval.
|
9
|
+
#
|
10
|
+
# Examples
|
11
|
+
#
|
12
|
+
# Faraday.new do |conn|
|
13
|
+
# conn.request :retry, max: 2, interval: 0.05,
|
14
|
+
# exceptions: [CustomException, 'Timeout::Error']
|
15
|
+
# conn.adapter ...
|
16
|
+
# end
|
17
|
+
class BetterRetry < Faraday::Middleware
|
18
|
+
class Options < OpenStruct
|
19
|
+
|
20
|
+
def max
|
21
|
+
(self[:max] ||= 2).to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
def interval
|
25
|
+
(self[:interval] ||= 0).to_f
|
26
|
+
end
|
27
|
+
|
28
|
+
def exceptions
|
29
|
+
Array(self[:exceptions] ||= [Errno::ETIMEDOUT, 'Timeout::Error', Error::TimeoutError])
|
30
|
+
end
|
31
|
+
|
32
|
+
# define for ruby less than 2.0
|
33
|
+
def [](name)
|
34
|
+
@table[name.to_sym]
|
35
|
+
end
|
36
|
+
|
37
|
+
def []=(name, value)
|
38
|
+
modifiable[new_ostruct_member(name)] = value
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
# Public: Initialize middleware
|
44
|
+
#
|
45
|
+
# Options:
|
46
|
+
# max - Maximum number of retries (default: 2).
|
47
|
+
# interval - Pause in seconds between retries (default: 0).
|
48
|
+
# exceptions - The list of exceptions to handle. Exceptions can be
|
49
|
+
# given as Class, Module, or String. (default:
|
50
|
+
# [Errno::ETIMEDOUT, Timeout::Error, Error::TimeoutError])
|
51
|
+
def initialize(app, options = {})
|
52
|
+
super(app)
|
53
|
+
@options = Options.new(options)
|
54
|
+
@errmatch = build_exception_matcher(@options.exceptions)
|
55
|
+
@logger = options[:logger]
|
56
|
+
end
|
57
|
+
|
58
|
+
def call(env)
|
59
|
+
env[:retries] = retries = @options.max
|
60
|
+
begin
|
61
|
+
@app.call(env)
|
62
|
+
rescue @errmatch => e
|
63
|
+
if retries > 0
|
64
|
+
if @logger
|
65
|
+
@logger.warn("Retrying Parse Error #{e.inspect} on request #{env[:url].to_s} #{env[:body].inspect} response #{env[:response].inspect}")
|
66
|
+
end
|
67
|
+
retries -= 1
|
68
|
+
env[:retries] = retries
|
69
|
+
sleep @options.interval if @options.interval > 0
|
70
|
+
retry
|
71
|
+
end
|
72
|
+
raise
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Private: construct an exception matcher object.
|
77
|
+
#
|
78
|
+
# An exception matcher for the rescue clause can usually be any object that
|
79
|
+
# responds to `===`, but for Ruby 1.8 it has to be a Class or Module.
|
80
|
+
def build_exception_matcher(exceptions)
|
81
|
+
matcher = Module.new
|
82
|
+
(class << matcher; self; end).class_eval do
|
83
|
+
define_method(:===) do |error|
|
84
|
+
exceptions.any? do |ex|
|
85
|
+
if ex.is_a? Module then error.is_a? ex
|
86
|
+
else error.class.to_s == ex.to_s
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
matcher
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Faraday
|
3
|
+
|
4
|
+
class ExtendedParseJson < FaradayMiddleware::ParseJson
|
5
|
+
|
6
|
+
def process_response(env)
|
7
|
+
env[:raw_body] = env[:body] if preserve_raw?(env)
|
8
|
+
|
9
|
+
|
10
|
+
if env[:status] >= 400
|
11
|
+
data = parse(env[:body]) || {} rescue {}
|
12
|
+
|
13
|
+
array_codes = [
|
14
|
+
Parse::Protocol::ERROR_INTERNAL,
|
15
|
+
Parse::Protocol::ERROR_TIMEOUT,
|
16
|
+
Parse::Protocol::ERROR_EXCEEDED_BURST_LIMIT
|
17
|
+
]
|
18
|
+
error_hash = { "error" => "HTTP Status #{env[:status]} Body #{env[:body]}" }.merge(data)
|
19
|
+
if data['code'] && array_codes.include?(data['code'])
|
20
|
+
sleep 60 if data['code'] == Parse::Protocol::ERROR_EXCEEDED_BURST_LIMIT
|
21
|
+
raise exception(env).new(error_hash.merge(data))
|
22
|
+
elsif env[:status] >= 500
|
23
|
+
raise exception(env).new(error_hash.merge(data))
|
24
|
+
end
|
25
|
+
raise Parse::ParseProtocolError.new(error_hash)
|
26
|
+
else
|
27
|
+
data = parse(env[:body]) || {}
|
28
|
+
|
29
|
+
env[:body] = data
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def exception env
|
34
|
+
# decide to retry or not
|
35
|
+
(env[:retries].to_i.zero? ? Parse::ParseProtocolError : Parse::ParseProtocolRetry)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
|
5
|
+
module Faraday
|
6
|
+
# Public: Writes the original HTTP method to "X-Http-Method-Override" header
|
7
|
+
# and sends the request as POST for GET requests that are too long.
|
8
|
+
class GetMethodOverride < Faraday::Middleware
|
9
|
+
|
10
|
+
HEADER = "X-Http-Method-Override".freeze
|
11
|
+
|
12
|
+
# Public: Initialize the middleware.
|
13
|
+
#
|
14
|
+
# app - the Faraday app to wrap
|
15
|
+
def initialize(app, options = nil)
|
16
|
+
super(app)
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(env)
|
20
|
+
if env[:method] == :get && env[:url].to_s.size > 2000
|
21
|
+
env[:request_headers][HEADER] = 'GET'
|
22
|
+
env[:request_headers]['Content-Type'] =
|
23
|
+
'application/x-www-form-urlencoded'
|
24
|
+
env[:body] = env[:url].query
|
25
|
+
env[:url].query = nil
|
26
|
+
env[:method] = :post
|
27
|
+
end
|
28
|
+
|
29
|
+
@app.call(env)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/parse-ruby-client.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
## ----------------------------------------------------------------------
|
2
3
|
##
|
3
4
|
## Ruby client for parse.com
|
@@ -5,18 +6,16 @@
|
|
5
6
|
## See https://parse.com/docs/rest for full documentation on the API.
|
6
7
|
##
|
7
8
|
## ----------------------------------------------------------------------
|
8
|
-
require
|
9
|
-
require
|
9
|
+
require 'rubygems'
|
10
|
+
require 'bundler/setup'
|
10
11
|
|
11
|
-
require '
|
12
|
+
require 'faraday'
|
13
|
+
require 'faraday_middleware'
|
14
|
+
require 'faraday/better_retry'
|
15
|
+
require 'faraday/extended_parse_json'
|
16
|
+
require 'faraday/get_method_override'
|
12
17
|
require 'date'
|
13
18
|
require 'cgi'
|
14
|
-
if defined?(JRUBY_VERSION)
|
15
|
-
require 'net/http'
|
16
|
-
require 'net/https'
|
17
|
-
else
|
18
|
-
require 'patron'
|
19
|
-
end
|
20
19
|
|
21
20
|
cwd = Pathname(__FILE__).dirname
|
22
21
|
$:.unshift(cwd.to_s) unless $:.include?(cwd.to_s) || $:.include?(cwd.expand_path.to_s)
|
@@ -27,6 +26,7 @@ require 'parse/datatypes'
|
|
27
26
|
require 'parse/util'
|
28
27
|
require 'parse/protocol'
|
29
28
|
require 'parse/user'
|
29
|
+
require "parse/installation"
|
30
30
|
require 'parse/push'
|
31
31
|
require 'parse/cloud'
|
32
32
|
require 'parse/model'
|
data/lib/parse/batch.rb
CHANGED
data/lib/parse/client.rb
CHANGED
@@ -1,12 +1,9 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
require 'parse/protocol'
|
2
3
|
require 'parse/error'
|
3
4
|
require 'parse/util'
|
4
|
-
require 'parse/http_client'
|
5
5
|
|
6
6
|
require 'logger'
|
7
|
-
|
8
|
-
require 'iron_mq'
|
9
|
-
|
10
7
|
module Parse
|
11
8
|
|
12
9
|
# A class which encapsulates the HTTPS communication with the Parse
|
@@ -21,7 +18,7 @@ module Parse
|
|
21
18
|
attr_accessor :max_retries
|
22
19
|
attr_accessor :logger
|
23
20
|
|
24
|
-
def initialize(data = {})
|
21
|
+
def initialize(data = {}, &blk)
|
25
22
|
@host = data[:host] || Protocol::HOST
|
26
23
|
@application_id = data[:application_id]
|
27
24
|
@api_key = data[:api_key]
|
@@ -29,27 +26,26 @@ module Parse
|
|
29
26
|
@session_token = data[:session_token]
|
30
27
|
@max_retries = data[:max_retries] || 3
|
31
28
|
@logger = data[:logger] || Logger.new(STDERR).tap{|l| l.level = Logger::INFO}
|
32
|
-
@session = data[:http_client] || Parse::DEFAULT_HTTP_CLIENT.new
|
33
29
|
|
34
|
-
|
30
|
+
options = {:request => {:timeout => 30, :open_timeout => 30}}
|
35
31
|
|
36
|
-
|
37
|
-
|
38
|
-
else
|
39
|
-
@max_concurrent_requests = 50
|
40
|
-
end
|
32
|
+
@session = Faraday.new("https://#{host}", options) do |c|
|
33
|
+
c.request :json
|
41
34
|
|
42
|
-
|
43
|
-
:project_id => data[:ironio_project_id],
|
44
|
-
:token => data[:ironio_token]
|
45
|
-
}).queue("concurrent_parse_requests")
|
35
|
+
c.use Faraday::GetMethodOverride
|
46
36
|
|
47
|
-
|
37
|
+
c.use Faraday::BetterRetry,
|
38
|
+
max: @max_retries,
|
39
|
+
logger: @logger,
|
40
|
+
interval: 0.5,
|
41
|
+
exceptions: ['Faraday::Error::TimeoutError', 'Faraday::Error::ParsingError', 'Parse::ParseProtocolRetry']
|
42
|
+
c.use Faraday::ExtendedParseJson
|
43
|
+
|
44
|
+
c.response :logger, @logger
|
45
|
+
c.adapter Faraday.default_adapter
|
48
46
|
|
49
|
-
|
50
|
-
|
51
|
-
@session.headers["Accept"] = "application/json"
|
52
|
-
@session.headers["User-Agent"] = "Parse for Ruby, 0.0"
|
47
|
+
yield(c) if block_given?
|
48
|
+
end
|
53
49
|
end
|
54
50
|
|
55
51
|
# Perform an HTTP request for the given uri and method
|
@@ -57,95 +53,20 @@ module Parse
|
|
57
53
|
# ParseProtocolError if the response has an error status code,
|
58
54
|
# and will return the parsed JSON body on success, if there is one.
|
59
55
|
def request(uri, method = :get, body = nil, query = nil, content_type = nil)
|
60
|
-
options = {}
|
61
56
|
headers = {}
|
62
57
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
options[:query] = @session.build_query(query)
|
73
|
-
|
74
|
-
# Avoid 502 or 414 when sending a large querystring. See https://parse.com/questions/502-error-when-query-with-huge-contains
|
75
|
-
if options[:query].size > 2000 && method == :get && !body && !content_type
|
76
|
-
options[:data] = options[:query]
|
77
|
-
options[:query] = nil
|
78
|
-
method = :post
|
79
|
-
headers['X-HTTP-Method-Override'] = 'GET'
|
80
|
-
content_type = 'application/x-www-form-urlencoded'
|
81
|
-
end
|
58
|
+
{
|
59
|
+
"Content-Type" => content_type || 'application/json',
|
60
|
+
"User-Agent" => 'Parse for Ruby, 0.0',
|
61
|
+
Protocol::HEADER_MASTER_KEY => @master_key,
|
62
|
+
Protocol::HEADER_APP_ID => @application_id,
|
63
|
+
Protocol::HEADER_API_KEY => @api_key,
|
64
|
+
Protocol::HEADER_SESSION_TOKEN => @session_token,
|
65
|
+
}.each do |key, value|
|
66
|
+
headers[key] = value if value
|
82
67
|
end
|
83
68
|
|
84
|
-
|
85
|
-
headers["Content-Type"] = content_type
|
86
|
-
end
|
87
|
-
|
88
|
-
num_tries = 0
|
89
|
-
begin
|
90
|
-
num_tries += 1
|
91
|
-
|
92
|
-
if @queue
|
93
|
-
|
94
|
-
#while true
|
95
|
-
# if @queue.reload.size >= @max_concurrent_requests
|
96
|
-
# sleep 1
|
97
|
-
# else
|
98
|
-
# add to queue before request
|
99
|
-
@queue.post("1")
|
100
|
-
response = @session.request(method, uri, headers, options)
|
101
|
-
# delete from queue after request
|
102
|
-
msg = @queue.get()
|
103
|
-
msg.delete
|
104
|
-
# end
|
105
|
-
#end
|
106
|
-
else
|
107
|
-
response = @session.request(method, uri, headers, options)
|
108
|
-
end
|
109
|
-
|
110
|
-
parsed = JSON.parse(response.body)
|
111
|
-
|
112
|
-
if response.status >= 400
|
113
|
-
parsed ||= {}
|
114
|
-
raise ParseProtocolError.new({"error" => "HTTP Status #{response.status} Body #{response.body}"}.merge(parsed))
|
115
|
-
end
|
116
|
-
|
117
|
-
if content_type
|
118
|
-
@session.headers["Content-Type"] = "application/json"
|
119
|
-
end
|
120
|
-
|
121
|
-
return parsed
|
122
|
-
rescue JSON::ParserError => e
|
123
|
-
if num_tries <= max_retries && response.status >= 500
|
124
|
-
log_retry(e, uri, query, body, response)
|
125
|
-
retry
|
126
|
-
end
|
127
|
-
raise
|
128
|
-
rescue HttpClient::TimeoutError => e
|
129
|
-
if num_tries <= max_retries
|
130
|
-
log_retry(e, uri, query, body, response)
|
131
|
-
retry
|
132
|
-
end
|
133
|
-
raise
|
134
|
-
rescue ParseProtocolError => e
|
135
|
-
if num_tries <= max_retries
|
136
|
-
if e.code
|
137
|
-
sleep 60 if e.code == Protocol::ERROR_EXCEEDED_BURST_LIMIT
|
138
|
-
if [Protocol::ERROR_INTERNAL, Protocol::ERROR_TIMEOUT, Protocol::ERROR_EXCEEDED_BURST_LIMIT].include?(e.code)
|
139
|
-
log_retry(e, uri, query, body, response)
|
140
|
-
retry
|
141
|
-
end
|
142
|
-
elsif response.status >= 500
|
143
|
-
log_retry(e, uri, query, body, response)
|
144
|
-
retry
|
145
|
-
end
|
146
|
-
end
|
147
|
-
raise
|
148
|
-
end
|
69
|
+
@session.send(method, uri, query || body || {}, headers).body
|
149
70
|
end
|
150
71
|
|
151
72
|
def get(uri)
|
@@ -164,72 +85,62 @@ module Parse
|
|
164
85
|
request(uri, :delete)
|
165
86
|
end
|
166
87
|
|
167
|
-
protected
|
168
|
-
|
169
|
-
def log_retry(e, uri, query, body, response)
|
170
|
-
logger.warn{"Retrying Parse Error #{e.inspect} on request #{uri} #{CGI.unescape(query.inspect)} #{body.inspect} response #{response.inspect}"}
|
171
|
-
end
|
172
88
|
end
|
173
89
|
|
174
90
|
|
175
91
|
# Module methods
|
176
92
|
# ------------------------------------------------------------
|
93
|
+
class << self
|
94
|
+
# A singleton client for use by methods in Object.
|
95
|
+
# Always use Parse.client to retrieve the client object.
|
96
|
+
@client = nil
|
97
|
+
|
98
|
+
# Initialize the singleton instance of Client which is used
|
99
|
+
# by all API methods. Parse.init must be called before saving
|
100
|
+
# or retrieving any objects.
|
101
|
+
def init(data = {}, &blk)
|
102
|
+
defaults = {:application_id => ENV["PARSE_APPLICATION_ID"], :api_key => ENV["PARSE_REST_API_KEY"]}
|
103
|
+
defaults.merge!(data)
|
104
|
+
|
105
|
+
# use less permissive key if both are specified
|
106
|
+
defaults[:master_key] = ENV["PARSE_MASTER_API_KEY"] unless data[:master_key] || defaults[:api_key]
|
107
|
+
@@client = Client.new(defaults, &blk)
|
108
|
+
end
|
177
109
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
:api_key => ENV["PARSE_REST_API_KEY"]}
|
188
|
-
defaulted.merge!(data)
|
189
|
-
|
190
|
-
# use less permissive key if both are specified
|
191
|
-
defaulted[:master_key] = ENV["PARSE_MASTER_API_KEY"] unless data[:master_key] || defaulted[:api_key]
|
192
|
-
|
193
|
-
|
194
|
-
@@client = Client.new(defaulted)
|
195
|
-
end
|
196
|
-
|
197
|
-
# A convenience method for using global.json
|
198
|
-
def Parse.init_from_cloud_code(path="../config/global.json")
|
199
|
-
global = JSON.parse(Object::File.open(path).read) # warning: toplevel constant File referenced by Parse::Object::File
|
200
|
-
application_name = global["applications"]["_default"]["link"]
|
201
|
-
application_id = global["applications"][application_name]["applicationId"]
|
202
|
-
master_key = global["applications"][application_name]["masterKey"]
|
203
|
-
Parse.init :application_id => application_id,
|
204
|
-
:master_key => master_key
|
205
|
-
end
|
206
|
-
|
207
|
-
# Used mostly for testing. Lets you delete the api key global vars.
|
208
|
-
def Parse.destroy
|
209
|
-
@@client = nil
|
210
|
-
self
|
211
|
-
end
|
110
|
+
# A convenience method for using global.json
|
111
|
+
def init_from_cloud_code(path = "../config/global.json")
|
112
|
+
# warning: toplevel constant File referenced by Parse::Object::File
|
113
|
+
global = JSON.parse(Object::File.open(path).read)
|
114
|
+
application_name = global["applications"]["_default"]["link"]
|
115
|
+
application_id = global["applications"][application_name]["applicationId"]
|
116
|
+
master_key = global["applications"][application_name]["masterKey"]
|
117
|
+
self.init(:application_id => application_id, :master_key => master_key)
|
118
|
+
end
|
212
119
|
|
213
|
-
|
214
|
-
|
215
|
-
|
120
|
+
# Used mostly for testing. Lets you delete the api key global vars.
|
121
|
+
def destroy
|
122
|
+
@@client = nil
|
123
|
+
self
|
216
124
|
end
|
217
|
-
@@client
|
218
|
-
end
|
219
125
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
# given class will be retrieved and returned in an Array.
|
224
|
-
def Parse.get(class_name, object_id = nil)
|
225
|
-
data = Parse.client.get( Protocol.class_uri(class_name, object_id) )
|
226
|
-
Parse.parse_json class_name, data
|
227
|
-
rescue ParseProtocolError => e
|
228
|
-
if e.code == Protocol::ERROR_OBJECT_NOT_FOUND_FOR_GET
|
229
|
-
e.message += ": #{class_name}:#{object_id}"
|
126
|
+
def client
|
127
|
+
raise ParseError, "API not initialized" if !@@client
|
128
|
+
@@client
|
230
129
|
end
|
231
130
|
|
232
|
-
|
131
|
+
# Perform a simple retrieval of a simple object, or all objects of a
|
132
|
+
# given class. If object_id is supplied, a single object will be
|
133
|
+
# retrieved. If object_id is not supplied, then all objects of the
|
134
|
+
# given class will be retrieved and returned in an Array.
|
135
|
+
def get(class_name, object_id = nil)
|
136
|
+
data = self.client.get( Protocol.class_uri(class_name, object_id) )
|
137
|
+
self.parse_json class_name, data
|
138
|
+
rescue ParseProtocolError => e
|
139
|
+
if e.code == Protocol::ERROR_OBJECT_NOT_FOUND_FOR_GET
|
140
|
+
e.message += ": #{class_name}:#{object_id}"
|
141
|
+
end
|
142
|
+
raise
|
143
|
+
end
|
233
144
|
end
|
234
145
|
|
235
146
|
end
|