parse-ruby-client 0.1.14 → 0.1.15

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.
Files changed (67) hide show
  1. data/.travis.yml +3 -2
  2. data/Gemfile +12 -12
  3. data/Gemfile.lock +26 -12
  4. data/OLD_README.md +255 -0
  5. data/README.md +1038 -144
  6. data/Rakefile +2 -10
  7. data/VERSION +1 -1
  8. data/features.md +11 -11
  9. data/fixtures/vcr_cassettes/test_acls_arent_objects.yml +180 -0
  10. data/fixtures/vcr_cassettes/test_array_add.yml +20 -20
  11. data/fixtures/vcr_cassettes/test_array_add_pointerizing.yml +239 -0
  12. data/fixtures/vcr_cassettes/test_array_add_unique.yml +180 -0
  13. data/fixtures/vcr_cassettes/test_batch_create_object.yml +53 -80
  14. data/fixtures/vcr_cassettes/test_batch_delete_object.yml +303 -428
  15. data/fixtures/vcr_cassettes/test_batch_run.yml +53 -74
  16. data/fixtures/vcr_cassettes/test_batch_update_object.yml +303 -432
  17. data/fixtures/vcr_cassettes/test_circular_save.yml +121 -0
  18. data/fixtures/vcr_cassettes/test_created_at.yml +53 -74
  19. data/fixtures/vcr_cassettes/test_decrement.yml +121 -0
  20. data/fixtures/vcr_cassettes/test_deep_parse.yml +154 -218
  21. data/fixtures/vcr_cassettes/test_destroy.yml +104 -144
  22. data/fixtures/vcr_cassettes/test_eq_pointerize.yml +239 -0
  23. data/fixtures/vcr_cassettes/test_equality.yml +180 -0
  24. data/fixtures/vcr_cassettes/test_get.yml +104 -146
  25. data/fixtures/vcr_cassettes/test_get_missing.yml +60 -0
  26. data/fixtures/vcr_cassettes/test_include.yml +27 -27
  27. data/fixtures/vcr_cassettes/test_new_model.yml +53 -146
  28. data/fixtures/vcr_cassettes/test_new_object.yml +53 -74
  29. data/fixtures/vcr_cassettes/test_nils_delete_keys.yml +155 -216
  30. data/fixtures/vcr_cassettes/test_parse_delete.yml +204 -284
  31. data/fixtures/vcr_cassettes/test_pointer.yml +53 -74
  32. data/fixtures/vcr_cassettes/test_save_with_sub_objects.yml +298 -0
  33. data/fixtures/vcr_cassettes/test_saving_boolean_values.yml +121 -0
  34. data/fixtures/vcr_cassettes/test_server_update.yml +257 -358
  35. data/fixtures/vcr_cassettes/test_simple_save.yml +53 -74
  36. data/fixtures/vcr_cassettes/test_text_file_save.yml +53 -161
  37. data/fixtures/vcr_cassettes/test_update.yml +104 -144
  38. data/fixtures/vcr_cassettes/test_updated_at.yml +104 -144
  39. data/fixtures/vcr_cassettes/test_user_save.yml +10 -10
  40. data/lib/parse/client.rb +43 -6
  41. data/lib/parse/datatypes.rb +14 -35
  42. data/lib/parse/error.rb +8 -0
  43. data/lib/parse/object.rb +25 -20
  44. data/lib/parse/protocol.rb +3 -4
  45. data/lib/parse/query.rb +10 -9
  46. data/lib/parse/util.rb +36 -2
  47. data/parse-ruby-client.gemspec +22 -18
  48. data/test/helper.rb +33 -5
  49. data/test/test_batch.rb +1 -4
  50. data/test/test_client.rb +59 -7
  51. data/test/test_cloud.rb +3 -7
  52. data/test/test_datatypes.rb +6 -7
  53. data/test/test_file.rb +9 -10
  54. data/test/test_model.rb +1 -4
  55. data/test/test_object.rb +148 -6
  56. data/test/test_push.rb +1 -5
  57. data/test/test_query.rb +13 -3
  58. data/test/test_throttle.rb +1 -3
  59. data/test/test_user.rb +1 -5
  60. metadata +23 -19
  61. data/fixtures/vcr_cassettes/test_array_add_relation.yml +0 -321
  62. data/fixtures/vcr_cassettes/test_cloud_function.yml +0 -81
  63. data/fixtures/vcr_cassettes/test_file_save.yml +0 -87
  64. data/fixtures/vcr_cassettes/test_image_file_associate_with_object.yml +0 -2034
  65. data/fixtures/vcr_cassettes/test_image_file_save.yml +0 -1957
  66. data/fixtures/vcr_cassettes/test_object_id.yml +0 -83
  67. data/fixtures/vcr_cassettes/test_request_batch.yml +0 -62
@@ -1,161 +1,121 @@
1
- ---
2
- http_interactions:
3
- - request:
1
+ ---
2
+ http_interactions:
3
+ - request:
4
4
  method: post
5
5
  uri: https://api.parse.com/1/classes/Post
6
- body:
6
+ body:
7
7
  encoding: UTF-8
8
- string: ! '{"title":"hello"}'
9
- headers:
10
- Content-Type:
8
+ string: "{\"title\":\"hello\"}"
9
+ headers:
10
+ Content-Type:
11
11
  - application/json
12
- Accept:
12
+ Accept:
13
13
  - application/json
14
- User-Agent:
14
+ User-Agent:
15
15
  - Parse for Ruby, 0.0
16
- X-Parse-Master-Key:
17
- - ''
18
- X-Parse-Rest-Api-Key:
19
- - D3Y8jNCQk6kpkKhpRGnWLYTrFGQ7j8dtDVnWZRnZ
20
- X-Parse-Application-Id:
21
- - PPVk6L5M9R1R8GVk8Ye9jT8f5SQNBIeoJUDJLmkT
22
- X-Parse-Session-Token:
23
- - ''
24
- Expect:
25
- - ''
26
- response:
27
- status:
16
+ X-Parse-Master-Key:
17
+ - ""
18
+ X-Parse-Rest-Api-Key:
19
+ - <X-Parse-REST-API-Key>
20
+ X-Parse-Application-Id:
21
+ - <X-Parse-Application-Id>
22
+ X-Parse-Session-Token:
23
+ - ""
24
+ Expect:
25
+ - ""
26
+ response:
27
+ status:
28
28
  code: 201
29
- message: !binary |-
30
- Q3JlYXRlZA==
31
- headers:
32
- !binary "QWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2lu":
33
- - !binary |-
34
- Kg==
35
- !binary "QWNjZXNzLUNvbnRyb2wtUmVxdWVzdC1NZXRob2Q=":
36
- - !binary |-
37
- Kg==
38
- !binary "Q2FjaGUtQ29udHJvbA==":
39
- - !binary |-
40
- bm8tY2FjaGU=
41
- !binary "Q29udGVudC1UeXBl":
42
- - !binary |-
43
- YXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOA==
44
- !binary "RGF0ZQ==":
45
- - !binary |-
46
- VHVlLCAwOSBPY3QgMjAxMiAyMTo0NTozMiBHTVQ=
47
- !binary "TG9jYXRpb24=":
48
- - !binary |-
49
- aHR0cHM6Ly9hcGkucGFyc2UuY29tLzEvY2xhc3Nlcy9Qb3N0LzNiODJoeWI2
50
- UUY=
51
- !binary "U2VydmVy":
52
- - !binary |-
53
- bmdpbngvMS4yLjI=
54
- !binary "U2V0LUNvb2tpZQ==":
55
- - !binary |-
56
- X3BhcnNlX3Nlc3Npb249QkFoN0Jra2lEM05sYzNOcGIyNWZhV1FHT2daRlJp
57
- SWxPR1ZrTVdWbFpqWmpZbU5qWVdNell6Tm1NMk5rTmpoa09UTTFZV1pqTjJZ
58
- JTNELS05N2M1NmUwNDBmMWUyMGQ3MmZlNzA0MGRhOGViZjFlYWM1ZjYwMGNm
59
- OyBkb21haW49LnBhcnNlLmNvbTsgcGF0aD0vOyBleHBpcmVzPVN1biwgMDkt
60
- T2N0LTIwMjIgMjE6NDU6MzIgR01UOyBzZWN1cmU7IEh0dHBPbmx5
61
- !binary "U3RhdHVz":
62
- - !binary |-
63
- MjAxIENyZWF0ZWQ=
64
- !binary "WC1SdW50aW1l":
65
- - !binary |-
66
- MC4wMTg5OTc=
67
- !binary "WC1VYS1Db21wYXRpYmxl":
68
- - !binary |-
69
- SUU9RWRnZSxjaHJvbWU9MQ==
70
- !binary "Q29udGVudC1MZW5ndGg=":
71
- - !binary |-
72
- NjQ=
73
- !binary "Q29ubmVjdGlvbg==":
74
- - !binary |-
75
- a2VlcC1hbGl2ZQ==
76
- body:
29
+ message: Created
30
+ headers:
31
+ Access-Control-Allow-Origin:
32
+ - "*"
33
+ Access-Control-Request-Method:
34
+ - "*"
35
+ Cache-Control:
36
+ - no-cache
37
+ Content-Type:
38
+ - application/json; charset=utf-8
39
+ Date:
40
+ - Mon, 22 Apr 2013 16:03:23 GMT
41
+ Location:
42
+ - https://api.parse.com/1/classes/Post/UzS4Cr4U3J
43
+ Server:
44
+ - nginx/1.2.2
45
+ Set-Cookie:
46
+ - <COOKIE-KEY>
47
+ Status:
48
+ - 201 Created
49
+ X-Runtime:
50
+ - "0.025069"
51
+ X-Ua-Compatible:
52
+ - IE=Edge,chrome=1
53
+ Content-Length:
54
+ - "64"
55
+ Connection:
56
+ - keep-alive
57
+ body:
77
58
  encoding: ASCII-8BIT
78
- string: !binary |-
79
- eyJjcmVhdGVkQXQiOiIyMDEyLTEwLTA5VDIxOjQ1OjMyLjQ4OFoiLCJvYmpl
80
- Y3RJZCI6IjNiODJoeWI2UUYifQ==
59
+ string: "{\"createdAt\":\"2013-04-22T16:03:23.371Z\",\"objectId\":\"UzS4Cr4U3J\"}"
81
60
  http_version:
82
- recorded_at: Tue, 09 Oct 2012 21:45:32 GMT
83
- - request:
61
+ recorded_at: Mon, 22 Apr 2013 16:03:23 GMT
62
+ - request:
84
63
  method: put
85
- uri: https://api.parse.com/1/classes/Post/3b82hyb6QF
86
- body:
64
+ uri: https://api.parse.com/1/classes/Post/UzS4Cr4U3J
65
+ body:
87
66
  encoding: UTF-8
88
- string: ! '{"title":"hello 2"}'
89
- headers:
90
- Content-Type:
67
+ string: "{\"title\":\"hello 2\"}"
68
+ headers:
69
+ Content-Type:
91
70
  - application/json
92
- Accept:
71
+ Accept:
93
72
  - application/json
94
- User-Agent:
73
+ User-Agent:
95
74
  - Parse for Ruby, 0.0
96
- X-Parse-Master-Key:
97
- - ''
98
- X-Parse-Rest-Api-Key:
99
- - D3Y8jNCQk6kpkKhpRGnWLYTrFGQ7j8dtDVnWZRnZ
100
- X-Parse-Application-Id:
101
- - PPVk6L5M9R1R8GVk8Ye9jT8f5SQNBIeoJUDJLmkT
102
- X-Parse-Session-Token:
103
- - ''
104
- Expect:
105
- - ''
106
- response:
107
- status:
75
+ X-Parse-Master-Key:
76
+ - ""
77
+ X-Parse-Rest-Api-Key:
78
+ - <X-Parse-REST-API-Key>
79
+ X-Parse-Application-Id:
80
+ - <X-Parse-Application-Id>
81
+ X-Parse-Session-Token:
82
+ - ""
83
+ Expect:
84
+ - ""
85
+ response:
86
+ status:
108
87
  code: 200
109
- message: !binary |-
110
- T0s=
111
- headers:
112
- !binary "QWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2lu":
113
- - !binary |-
114
- Kg==
115
- !binary "QWNjZXNzLUNvbnRyb2wtUmVxdWVzdC1NZXRob2Q=":
116
- - !binary |-
117
- Kg==
118
- !binary "Q2FjaGUtQ29udHJvbA==":
119
- - !binary |-
120
- bWF4LWFnZT0wLCBwcml2YXRlLCBtdXN0LXJldmFsaWRhdGU=
121
- !binary "Q29udGVudC1UeXBl":
122
- - !binary |-
123
- YXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOA==
124
- !binary "RGF0ZQ==":
125
- - !binary |-
126
- VHVlLCAwOSBPY3QgMjAxMiAyMTo0NTozMiBHTVQ=
127
- !binary "RXRhZw==":
128
- - !binary |-
129
- IjhhZTRmMTQzOGY1ZWM3M2Q1NzkyMDdjZTg5MjVmYTFjIg==
130
- !binary "U2VydmVy":
131
- - !binary |-
132
- bmdpbngvMS4yLjI=
133
- !binary "U2V0LUNvb2tpZQ==":
134
- - !binary |-
135
- X3BhcnNlX3Nlc3Npb249QkFoN0Jra2lEM05sYzNOcGIyNWZhV1FHT2daRlJp
136
- SWxZVFJpTlRabFkyRXpaVGMyWWpCaFl6SmhaV1l6TnpsaE1XTTFaakl6WldZ
137
- JTNELS1hYTJkNjdlN2FkNjZhODBlZGRmMTk5OTJjZjg4YmFiYWU1NDJiNzVm
138
- OyBkb21haW49LnBhcnNlLmNvbTsgcGF0aD0vOyBleHBpcmVzPVN1biwgMDkt
139
- T2N0LTIwMjIgMjE6NDU6MzIgR01UOyBzZWN1cmU7IEh0dHBPbmx5
140
- !binary "U3RhdHVz":
141
- - !binary |-
142
- MjAwIE9L
143
- !binary "WC1SdW50aW1l":
144
- - !binary |-
145
- MC4wMzUwODU=
146
- !binary "WC1VYS1Db21wYXRpYmxl":
147
- - !binary |-
148
- SUU9RWRnZSxjaHJvbWU9MQ==
149
- !binary "Q29udGVudC1MZW5ndGg=":
150
- - !binary |-
151
- NDA=
152
- !binary "Q29ubmVjdGlvbg==":
153
- - !binary |-
154
- a2VlcC1hbGl2ZQ==
155
- body:
88
+ message: OK
89
+ headers:
90
+ Access-Control-Allow-Origin:
91
+ - "*"
92
+ Access-Control-Request-Method:
93
+ - "*"
94
+ Cache-Control:
95
+ - max-age=0, private, must-revalidate
96
+ Content-Type:
97
+ - application/json; charset=utf-8
98
+ Date:
99
+ - Mon, 22 Apr 2013 16:03:23 GMT
100
+ Etag:
101
+ - "\"713d90a679b7296644271208d96d7d8f\""
102
+ Server:
103
+ - nginx/1.2.2
104
+ Set-Cookie:
105
+ - <COOKIE-KEY>
106
+ Status:
107
+ - 200 OK
108
+ X-Runtime:
109
+ - "0.060774"
110
+ X-Ua-Compatible:
111
+ - IE=Edge,chrome=1
112
+ Content-Length:
113
+ - "40"
114
+ Connection:
115
+ - keep-alive
116
+ body:
156
117
  encoding: ASCII-8BIT
157
- string: !binary |-
158
- eyJ1cGRhdGVkQXQiOiIyMDEyLTEwLTA5VDIxOjQ1OjMyLjU5N1oifQ==
118
+ string: "{\"updatedAt\":\"2013-04-22T16:03:23.498Z\"}"
159
119
  http_version:
160
- recorded_at: Tue, 09 Oct 2012 21:45:32 GMT
161
- recorded_with: VCR 2.0.1
120
+ recorded_at: Mon, 22 Apr 2013 16:03:23 GMT
121
+ recorded_with: VCR 2.4.0
@@ -5,7 +5,7 @@ http_interactions:
5
5
  uri: https://api.parse.com/1/users
6
6
  body:
7
7
  encoding: UTF-8
8
- string: "{\"username\":\"0.40493766445323776\",\"password\":\"topsecret\"}"
8
+ string: "{\"username\":\"0.27216148534966633\",\"password\":\"topsecret\"}"
9
9
  headers:
10
10
  Content-Type:
11
11
  - application/json
@@ -16,9 +16,9 @@ http_interactions:
16
16
  X-Parse-Master-Key:
17
17
  - ""
18
18
  X-Parse-Rest-Api-Key:
19
- - jYdptjS76YHikuIFfJEgHD8UMIjH6cp2rWz4fo2C
19
+ - <X-Parse-REST-API-Key>
20
20
  X-Parse-Application-Id:
21
- - hnJRtntbYPvWfjqcqLZsdFaOKT0F3SfNU7Kc7woN
21
+ - <X-Parse-Application-Id>
22
22
  X-Parse-Session-Token:
23
23
  - ""
24
24
  Expect:
@@ -37,17 +37,17 @@ http_interactions:
37
37
  Content-Type:
38
38
  - application/json; charset=utf-8
39
39
  Date:
40
- - Thu, 10 Jan 2013 17:13:29 GMT
40
+ - Mon, 22 Apr 2013 16:03:27 GMT
41
41
  Location:
42
- - https://api.parse.com/1/users/TjN5LVdT83
42
+ - https://api.parse.com/1/users/j0rFtnWhJy
43
43
  Server:
44
44
  - nginx/1.2.2
45
45
  Set-Cookie:
46
- - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlNDhiYjExOGE4MzY1ZmEzNGVjN2NmYjUxMzk2YjFjNzk%3D--242cb8875ea6f8b5c353b05bf1b9dcc351e5197e; domain=.parse.com; path=/; expires=Tue, 10-Jan-2023 17:13:29 GMT; secure; HttpOnly
46
+ - <COOKIE-KEY>
47
47
  Status:
48
48
  - 201 Created
49
49
  X-Runtime:
50
- - "0.312384"
50
+ - "0.346105"
51
51
  X-Ua-Compatible:
52
52
  - IE=Edge,chrome=1
53
53
  Content-Length:
@@ -56,7 +56,7 @@ http_interactions:
56
56
  - keep-alive
57
57
  body:
58
58
  encoding: ASCII-8BIT
59
- string: "{\"createdAt\":\"2013-01-10T17:13:29.400Z\",\"objectId\":\"TjN5LVdT83\",\"sessionToken\":\"ltj1s0ms3rft92u1avdnys7vn\"}"
59
+ string: "{\"createdAt\":\"2013-04-22T16:03:27.061Z\",\"objectId\":\"j0rFtnWhJy\",\"sessionToken\":\"rmranzh72f4mb3bptat7siph1\"}"
60
60
  http_version:
61
- recorded_at: Thu, 10 Jan 2013 17:13:29 GMT
62
- recorded_with: VCR 2.0.1
61
+ recorded_at: Mon, 22 Apr 2013 16:03:27 GMT
62
+ recorded_with: VCR 2.4.0
@@ -2,6 +2,8 @@ require 'parse/protocol'
2
2
  require 'parse/error'
3
3
  require 'parse/util'
4
4
 
5
+ require 'logger'
6
+
5
7
  require 'iron_mq'
6
8
 
7
9
  module Parse
@@ -17,6 +19,7 @@ module Parse
17
19
  attr_accessor :session_token
18
20
  attr_accessor :session
19
21
  attr_accessor :max_retries
22
+ attr_accessor :logger
20
23
 
21
24
  def initialize(data = {})
22
25
  @host = data[:host] || Protocol::HOST
@@ -25,6 +28,8 @@ module Parse
25
28
  @master_key = data[:master_key]
26
29
  @session_token = data[:session_token]
27
30
  @max_retries = data[:max_retries] || 3
31
+ @logger = data[:logger] || Logger.new(STDERR).tap{|l| l.level = Logger::INFO}
32
+
28
33
  @session = Patron::Session.new
29
34
  @session.timeout = 30
30
35
  @session.connect_timeout = 30
@@ -78,10 +83,10 @@ module Parse
78
83
 
79
84
  if @queue
80
85
 
81
- #while true
86
+ #while true
82
87
  # if @queue.reload.size >= @max_concurrent_requests
83
88
  # sleep 1
84
- # else
89
+ # else
85
90
  # add to queue before request
86
91
  @queue.post("1")
87
92
  response = @session.request(method, uri, {}, options)
@@ -97,7 +102,8 @@ module Parse
97
102
  parsed = JSON.parse(response.body)
98
103
 
99
104
  if response.status >= 400
100
- raise ParseProtocolError.new(parsed)
105
+ parsed ||= {}
106
+ raise ParseProtocolError.new({"error" => "HTTP Status #{response.status} Body #{response.body}"}.merge(parsed))
101
107
  end
102
108
 
103
109
  if content_type
@@ -105,11 +111,31 @@ module Parse
105
111
  end
106
112
 
107
113
  return parsed
108
- rescue Patron::TimeoutError
109
- retry if num_tries <= max_retries
114
+ rescue JSON::ParserError => e
115
+ if num_tries <= max_retries && response.status >= 500
116
+ log_retry(e, uri, query, body, response)
117
+ retry
118
+ end
119
+ raise
120
+ rescue Patron::TimeoutError => e
121
+ if num_tries <= max_retries
122
+ log_retry(e, uri, query, body, response)
123
+ retry
124
+ end
110
125
  raise
111
126
  rescue ParseProtocolError => e
112
- retry if e.code == Protocol::ERROR_TIMEOUT && num_tries <= max_retries
127
+ if num_tries <= max_retries
128
+ if e.code
129
+ sleep 60 if e.code == Protocol::ERROR_EXCEEDED_BURST_LIMIT
130
+ if [Protocol::ERROR_INTERNAL, Protocol::ERROR_TIMEOUT, Protocol::ERROR_EXCEEDED_BURST_LIMIT].include?(e.code)
131
+ log_retry(e, uri, query, body, response)
132
+ retry
133
+ end
134
+ elsif response.status >= 500
135
+ log_retry(e, uri, query, body, response)
136
+ retry
137
+ end
138
+ end
113
139
  raise
114
140
  end
115
141
  end
@@ -130,6 +156,11 @@ module Parse
130
156
  request(uri, :delete)
131
157
  end
132
158
 
159
+ protected
160
+
161
+ def log_retry(e, uri, query, body, response)
162
+ logger.warn{"Retrying Parse Error #{e.inspect} on request #{uri} #{CGI.unescape(query.inspect)} #{body.inspect} response #{response.inspect}"}
163
+ end
133
164
  end
134
165
 
135
166
 
@@ -185,6 +216,12 @@ module Parse
185
216
  def Parse.get(class_name, object_id = nil)
186
217
  data = Parse.client.get( Protocol.class_uri(class_name, object_id) )
187
218
  Parse.parse_json class_name, data
219
+ rescue ParseProtocolError => e
220
+ if e.code == Protocol::ERROR_OBJECT_NOT_FOUND_FOR_GET
221
+ e.message += ": #{class_name}:#{object_id}"
222
+ end
223
+
224
+ raise
188
225
  end
189
226
 
190
227
  end
@@ -10,6 +10,13 @@ module Parse
10
10
  attr_accessor :class_name
11
11
  alias :id :parse_object_id
12
12
 
13
+ def self.make(class_name, object_id)
14
+ Pointer.new(
15
+ Protocol::KEY_CLASS_NAME => class_name,
16
+ Protocol::KEY_OBJECT_ID => object_id
17
+ )
18
+ end
19
+
13
20
  def initialize(data)
14
21
  @class_name = data[Protocol::KEY_CLASS_NAME]
15
22
  @parse_object_id = data[Protocol::KEY_OBJECT_ID]
@@ -21,15 +28,17 @@ module Parse
21
28
  end
22
29
 
23
30
  def eql?(other)
24
- self.class.equal?(other.class) &&
25
- class_name == other.class_name &&
26
- parse_object_id == other.parse_object_id
31
+ Parse.object_pointer_equality?(self, other)
27
32
  end
28
33
 
29
34
  alias == eql?
30
35
 
31
36
  def hash
32
- class_name.hash ^ parse_object_id.hash
37
+ Parse.object_pointer_hash(self)
38
+ end
39
+
40
+ def new?
41
+ false
33
42
  end
34
43
 
35
44
  def as_json(*a)
@@ -193,37 +202,6 @@ module Parse
193
202
  end
194
203
  end
195
204
 
196
- class Decrement
197
- # '{"score": {"__op": "Decrement", "amount": 1 } }'
198
- attr_accessor :amount
199
-
200
- def initialize(amount)
201
- @amount = amount
202
- end
203
-
204
- def eql?(other)
205
- self.class.equal?(other.class) &&
206
- amount == other.amount
207
- end
208
-
209
- alias == eql?
210
-
211
- def hash
212
- amount.hash
213
- end
214
-
215
- def as_json(*a)
216
- {
217
- Protocol::KEY_OP => Protocol::KEY_DECREMENT,
218
- Protocol::KEY_AMOUNT => @amount
219
- }
220
- end
221
-
222
- def to_json(*a)
223
- as_json.to_json(*a)
224
- end
225
- end
226
-
227
205
  class ArrayOp
228
206
  # '{"myArray": {"__op": "Add", "objects": ["something", "something else"] } }'
229
207
  attr_accessor :operation
@@ -319,6 +297,7 @@ module Parse
319
297
  def initialize(data)
320
298
  data = Hash[data.map{ |k, v| [k.to_s, v] }] # convert hash keys to strings
321
299
  @local_filename = data["local_filename"] if data["local_filename"]
300
+ @parse_filename = data["name"] if data["name"]
322
301
  @parse_filename = data["parse_filename"] if data["parse_filename"]
323
302
  @content_type = data["content_type"] if data["content_type"]
324
303
  @url = data["url"] if data["url"]