leancloud-ruby-client 0.1.1 → 0.2.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 +4 -4
- data/Gemfile +1 -0
- data/README.md +144 -116
- data/VERSION +1 -1
- data/example.rb +7 -7
- data/leancloud-ruby-client.gemspec +1 -3
- data/lib/faraday/extended_parse_json.rb +6 -6
- data/lib/leancloud-ruby-client.rb +15 -15
- data/lib/leancloud/application.rb +2 -2
- data/lib/leancloud/batch.rb +6 -6
- data/lib/leancloud/client.rb +39 -14
- data/lib/leancloud/cloud.rb +4 -4
- data/lib/leancloud/datatypes.rb +7 -7
- data/lib/leancloud/error.rb +6 -6
- data/lib/leancloud/installation.rb +5 -5
- data/lib/leancloud/model.rb +3 -3
- data/lib/leancloud/object.rb +15 -15
- data/lib/leancloud/protocol.rb +10 -5
- data/lib/leancloud/push.rb +2 -2
- data/lib/leancloud/query.rb +22 -22
- data/lib/leancloud/user.rb +12 -6
- data/lib/leancloud/util.rb +18 -18
- data/test/helper.rb +5 -7
- data/test/test_batch.rb +18 -18
- data/test/test_client.rb +17 -17
- data/test/test_cloud.rb +7 -7
- data/test/test_datatypes.rb +23 -23
- data/test/test_file.rb +5 -5
- data/test/test_init.rb +4 -4
- data/test/test_init_from_cloud_code.rb +2 -2
- data/test/test_installation.rb +6 -6
- data/test/test_model.rb +4 -4
- data/test/test_object.rb +45 -45
- data/test/test_push.rb +7 -7
- data/test/test_query.rb +39 -39
- data/test/test_throttle.rb +1 -1
- data/test/test_user.rb +9 -9
- metadata +23 -24
- data/Gemfile.lock +0 -86
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ecf19276ad700a328278cfaa848c670478e9ebfa
|
4
|
+
data.tar.gz: 72b08d7370936b73520defe8dce0c3598ccdbd93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 920eff12917ac82e3e5b74eaf08edacdb33683b0833df22d4a6b6695138f0eb50ff0722bbd0d695a97651f157bae3410f7df6e1d246d8fc56c5500fffb884f2b
|
7
|
+
data.tar.gz: 81e4c8b39f9bca5f17d3ef7329454c1d4773d2dc9b61d0ad3814d3901eb5ab7116d78759217223010f46d6b565bf2f6a69d57f40c6d3843eac8c0f4e2c66c353
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,10 +4,16 @@ leancloud-ruby-client 从 [parse-ruby-client](https://github.com/adelevie/parse-
|
|
4
4
|
|
5
5
|
除了简单的重命名和调用地址改动之外,还做了下列事情:
|
6
6
|
|
7
|
-
* 增加短信 API `
|
8
|
-
* 增加 CQL 调用 `
|
7
|
+
* 增加短信 API `LC::Cloud.request_sms(params)` 和 `LC::Cloud.verify_sms_code(phone, code)`
|
8
|
+
* 增加 CQL 调用 `LC::Query.do_cloud_query(cql, pvalues)`
|
9
9
|
* 其他兼容性改进和测试,特别是文件
|
10
10
|
* 推送增加可以指定 iOS 生产或者测试证书功能 `production` 属性,值为 `true/false`。
|
11
|
+
* 增加用户 API `LC::User.became(token)`
|
12
|
+
|
13
|
+
## Contributors
|
14
|
+
|
15
|
+
* [oranzhang](https://github.com/oranzhang)
|
16
|
+
* [lostpupil](https://github.com/lostpupil)
|
11
17
|
|
12
18
|
### Quick Reference
|
13
19
|
|
@@ -20,9 +26,9 @@ leancloud-ruby-client 从 [parse-ruby-client](https://github.com/adelevie/parse-
|
|
20
26
|
```ruby
|
21
27
|
require 'leancloud-ruby-client'
|
22
28
|
|
23
|
-
|
29
|
+
LC.init :application_id => "<your_app_id>",
|
24
30
|
:api_key => "<your_api_key>",
|
25
|
-
:quiet => true | false
|
31
|
+
:quiet => true | false
|
26
32
|
```
|
27
33
|
|
28
34
|
[](http://badge.fury.io/rb/parse-ruby-client)
|
@@ -104,7 +110,7 @@ The design philosophy behind parse-ruby-client is to stay out of the way as much
|
|
104
110
|
### Creating Objects
|
105
111
|
|
106
112
|
```ruby
|
107
|
-
game_score =
|
113
|
+
game_score = LC::Object.new("GameScore")
|
108
114
|
game_score["score"] = 1337
|
109
115
|
game_score["playerName"] = "Sean Plott"
|
110
116
|
game_score["cheatMode"] = false
|
@@ -124,10 +130,10 @@ This will return:
|
|
124
130
|
|
125
131
|
### Retrieving Objects
|
126
132
|
|
127
|
-
The easiest way to retrieve Objects is with `
|
133
|
+
The easiest way to retrieve Objects is with `LC::Query`:
|
128
134
|
|
129
135
|
```ruby
|
130
|
-
game_score_query =
|
136
|
+
game_score_query = LC::Query.new("GameScore")
|
131
137
|
game_score_query.eq("objectId", "GeqPWJdNqp")
|
132
138
|
game_score = game_score_query.get
|
133
139
|
puts game_score
|
@@ -148,7 +154,7 @@ Notice that this is an `Array` of results. For more information on queries, see
|
|
148
154
|
When retrieving objects that have pointers to children, you can fetch child objects by setting the `include` attribute. For instance, to fetch the object pointed to by the "game" key:
|
149
155
|
|
150
156
|
```ruby
|
151
|
-
game_score_query =
|
157
|
+
game_score_query = LC::Query.new("GameScore")
|
152
158
|
game_score_query.eq("objectId", "GeqPWJdNqp")
|
153
159
|
game_score_query.include = "game"
|
154
160
|
game_score = game_score_query.get
|
@@ -162,10 +168,10 @@ game_score_query.include = "game,genre"
|
|
162
168
|
|
163
169
|
### Updating Objects
|
164
170
|
|
165
|
-
To change the data on an object that already exists, just call `
|
171
|
+
To change the data on an object that already exists, just call `LC::Object#save` on it. Any keys you don't specify will remain unchanged, so you can update just a subset of the object's data. For example, if we wanted to change the score field of our object:
|
166
172
|
|
167
173
|
```ruby
|
168
|
-
game_score =
|
174
|
+
game_score = LC::Query.new("GameScore").eq("objectId", "GeqPWJdNqp").get.first
|
169
175
|
game_score["score"] = 73453
|
170
176
|
result = game_score.save
|
171
177
|
puts result
|
@@ -186,8 +192,8 @@ This will return:
|
|
186
192
|
To help with storing counter-type data, Parse provides the ability to atomically increment (or decrement) any number field. So, we can increment the score field like so:
|
187
193
|
|
188
194
|
```ruby
|
189
|
-
game_score =
|
190
|
-
game_score["score"] =
|
195
|
+
game_score = LC::Query.new("GameScore").eq("objectId", "GeqPWJdNqp").get.first
|
196
|
+
game_score["score"] = LC::Increment.new(1)
|
191
197
|
game_score.save
|
192
198
|
```
|
193
199
|
|
@@ -197,14 +203,14 @@ You can also use a negative amount to decrement.
|
|
197
203
|
|
198
204
|
To help with storing array data, there are three operations that can be used to atomically change an array field:
|
199
205
|
|
200
|
-
1. `
|
201
|
-
2. `
|
202
|
-
3. `
|
206
|
+
1. `LC::Object#array_add(field, value)` appends the given array of objects to the end of an array field.
|
207
|
+
2. `LC::Object#array_add_unique(field, value)` adds only the given objects which aren't already contained in an array field to that field. The position of the insert is not guaranteed.
|
208
|
+
3. `LC::Object#array_remove(field, value)` removes all instances of each given object from an array field.
|
203
209
|
|
204
210
|
Each method takes an array of objects to add or remove in the "objects" key. For example, we can add items to the set-like "skills" field like so:
|
205
211
|
|
206
212
|
```ruby
|
207
|
-
game_score =
|
213
|
+
game_score = LC::Query.new("GameScore").eq("objectId", "5iEEIxM4MW").get.first
|
208
214
|
game_score.array_add_unique("skills", ["flying", "kungfu"])
|
209
215
|
game_score.save
|
210
216
|
puts game_score["skills"]
|
@@ -221,11 +227,11 @@ This will return:
|
|
221
227
|
In order to update Relation types, Parse provides special operators to atomically add and remove objects to a relation. So, we can add an object to a relation like so:
|
222
228
|
|
223
229
|
```ruby
|
224
|
-
game_score =
|
225
|
-
player =
|
230
|
+
game_score = LC::Query.new("GameScore").eq("objectId", "5iEEIxM4MW").get.first
|
231
|
+
player = LC::Query.new("Player").eq("objectId", "GLtvtEaGKa").get.first
|
226
232
|
game_score.array_add_relation("opponents", player.pointer)
|
227
233
|
game_score.save
|
228
|
-
game_score["opponents"] #=> #<
|
234
|
+
game_score["opponents"] #=> #<LC::ArrayOp:0x007fbe98931508 @operation="AddRelation", @objects=[Player:GLtvtEaGKa]>
|
229
235
|
game_score["opponents"].objects.first #=> Player:GLtvtEaGKa
|
230
236
|
```
|
231
237
|
|
@@ -237,15 +243,15 @@ To remove an object from a relation, you can do:
|
|
237
243
|
|
238
244
|
### Deleting Objects
|
239
245
|
|
240
|
-
To delete an object from the Parse Cloud, call `
|
246
|
+
To delete an object from the Parse Cloud, call `LC::Object#parse_delete`. For example:
|
241
247
|
|
242
248
|
```ruby
|
243
|
-
game_score =
|
249
|
+
game_score = LC::Query.new("GameScore").eq("objectId", "5iEEIxM4MW").get.first
|
244
250
|
game_score.parse_delete
|
245
|
-
|
251
|
+
LC::Query.new("GameScore").eq("objectId", "5iEEIxM4MW").get.length #=> 0
|
246
252
|
```
|
247
253
|
|
248
|
-
You can delete a single field from an object by using the `
|
254
|
+
You can delete a single field from an object by using the `LC::Object#delete_field` operation:
|
249
255
|
|
250
256
|
```ruby
|
251
257
|
# TODO: This method is not yet implemented.
|
@@ -255,10 +261,10 @@ You can delete a single field from an object by using the `AV::Object#delete_fie
|
|
255
261
|
|
256
262
|
To reduce the amount of time spent on network round trips, you can create, update, or delete several objects in one call, using the batch endpoint.
|
257
263
|
|
258
|
-
parse-ruby-client provides a "manual" way to construct Batch Operations, as well as some convenience methods. The commands are run in the order they are given. For example, to create a couple of GameScore objects using the "manual" style, use `
|
264
|
+
parse-ruby-client provides a "manual" way to construct Batch Operations, as well as some convenience methods. The commands are run in the order they are given. For example, to create a couple of GameScore objects using the "manual" style, use `LC::Batch#add_request`. `#add_request` takes a `Hash` with `"method"`, `"path"`, and `"body"` keys that specify the HTTP command that would normally be used for that command.
|
259
265
|
|
260
266
|
```ruby
|
261
|
-
batch =
|
267
|
+
batch = LC::Batch.new
|
262
268
|
batch.add_request({
|
263
269
|
"method" => "POST",
|
264
270
|
"path" => "/1/classes/GameScore"
|
@@ -278,13 +284,13 @@ batch.add_request({
|
|
278
284
|
batch.run!
|
279
285
|
```
|
280
286
|
|
281
|
-
Because manually constructing `"path"` values is repetitive, you can use `
|
287
|
+
Because manually constructing `"path"` values is repetitive, you can use `LC::Batch#create_object`, `LC::Batch#update_object`, and `LC::Batch#delete_object`. Each of these methods takes an instance of `LC::Object` as the only argument. Then you just call `LC::Batch#run!`. For example:
|
282
288
|
|
283
289
|
```ruby
|
284
|
-
batch =
|
290
|
+
batch = LC::Batch.new
|
285
291
|
# making a few GameScore objects and adding them to the batch operation.
|
286
292
|
[1, 2, 3, 4, 5].each do |i|
|
287
|
-
gs =
|
293
|
+
gs = LC::Object.new("GameScore")
|
288
294
|
gs["score"] = "#{i}"
|
289
295
|
batch.create_object(gs)
|
290
296
|
end
|
@@ -319,32 +325,32 @@ So far we have only used values that can be encoded with standard JSON. The Pars
|
|
319
325
|
|
320
326
|
#### Dates
|
321
327
|
|
322
|
-
Use `
|
328
|
+
Use `LC::Date::new` to create a date object:
|
323
329
|
|
324
330
|
```ruby
|
325
331
|
date_time = DateTime.now
|
326
|
-
parse_date =
|
332
|
+
parse_date = LC::Date.new(date_time)
|
327
333
|
```
|
328
334
|
|
329
335
|
Dates are useful in combination with the built-in createdAt and updatedAt fields. For example, to retrieve objects created since a particular time, just encode a Date in a comparison query:
|
330
336
|
|
331
337
|
```ruby
|
332
|
-
game_score =
|
333
|
-
q.greater_than("createdAt",
|
338
|
+
game_score = LC::Query.new("GameScore").tap do |q|
|
339
|
+
q.greater_than("createdAt", LC::Date.new(DateTime.now)) # query options explained in more detail later in this document
|
334
340
|
end.get.first
|
335
341
|
```
|
336
342
|
|
337
|
-
`
|
343
|
+
`LC::Date::new` can take a `DateTime`, iso `Hash`, or a `String` that can be parsed by `DateTime#parse` as the sole argument.
|
338
344
|
|
339
|
-
The `
|
345
|
+
The `LC::Date` API is not set in stone and will likely change following the suggestions discussed here: https://github.com/adelevie/parse-ruby-client/issues/35. The current methods probably will not go away, but some newer, easier methods will be added.
|
340
346
|
|
341
347
|
#### Bytes
|
342
348
|
|
343
|
-
`
|
349
|
+
`LC::Bytes` contains an attribute, `base64`, which contains a base64 encoding of binary data. The specific base64 encoding is the one used by MIME, and does not contain whitespace.
|
344
350
|
|
345
351
|
```ruby
|
346
352
|
data = "TG9va3MgbGlrZSB5b3UgZm91bmQgYW4gZWFzdGVyIEVnZy4gTWF5YmUgaXQn\ncyB0aW1lIHlvdSB0b29rIGEgTWluZWNyYWZ0IGJyZWFrPw==\n" # base64 encoded data
|
347
|
-
bytes =
|
353
|
+
bytes = LC::Bytes.new(data)
|
348
354
|
```
|
349
355
|
|
350
356
|
#### Pointers
|
@@ -352,12 +358,12 @@ bytes = AV::Bytes.new(data)
|
|
352
358
|
The `Pointer` type is used when mobile code sets a `PFObject` (iOS SDK) or `ParseObject` (Android SDK) as the value of another object. It contains the `className` and `objectId` of the referred-to value.
|
353
359
|
|
354
360
|
```ruby
|
355
|
-
pointer =
|
361
|
+
pointer = LC::Pointer.new({"className" => "gameScore", "objectId" => "GeqPWJdNqp"})
|
356
362
|
```
|
357
363
|
|
358
364
|
Pointers to `user` objects have a `className` of `_User`. Prefixing with an underscore is forbidden for developer-defined classes and signifies the class is a special built-in.
|
359
365
|
|
360
|
-
If you already have a `
|
366
|
+
If you already have a `LC::Object`, you can get its `Pointer` very easily:
|
361
367
|
|
362
368
|
```ruby
|
363
369
|
game_score.pointer
|
@@ -385,7 +391,7 @@ When more data types are added, they will also be represented as hashes with a `
|
|
385
391
|
Queries are created like so:
|
386
392
|
|
387
393
|
```ruby
|
388
|
-
query =
|
394
|
+
query = LC::Query.new("GameScore")
|
389
395
|
```
|
390
396
|
|
391
397
|
|
@@ -398,7 +404,7 @@ You can retrieve multiple objects at once by calling `#get`:
|
|
398
404
|
query.get
|
399
405
|
```
|
400
406
|
|
401
|
-
The return value is an `Array` of `
|
407
|
+
The return value is an `Array` of `LC::Object` instances:
|
402
408
|
|
403
409
|
```ruby
|
404
410
|
[{"score"=>100,
|
@@ -420,53 +426,53 @@ The return value is an `Array` of `AV::Object` instances:
|
|
420
426
|
|
421
427
|
### Query Contraints
|
422
428
|
|
423
|
-
There are several ways to put constraints on the objects found, using various methods of `
|
429
|
+
There are several ways to put constraints on the objects found, using various methods of `LC::Query`. The most basic is `LC::Query#eq`:
|
424
430
|
|
425
431
|
```ruby
|
426
|
-
query =
|
432
|
+
query = LC::Query.new("GameScore").eq("playerName", "Sean Plott")
|
427
433
|
```
|
428
434
|
|
429
435
|
Other constraint methods include:
|
430
436
|
|
431
437
|
<table>
|
432
438
|
<tr>
|
433
|
-
<td>`
|
439
|
+
<td>`LC::Query#less_than(field, value)`</td>
|
434
440
|
<td>Less Than</td>
|
435
441
|
</tr>
|
436
442
|
<tr>
|
437
|
-
<td>`
|
443
|
+
<td>`LC::Query#less_eq(field, value)`</td>
|
438
444
|
<td>Less Than or Equal To</td>
|
439
445
|
</tr>
|
440
446
|
<tr>
|
441
|
-
<td>`
|
447
|
+
<td>`LC::Query#greater_than(field, value)`</td>
|
442
448
|
<td>Greater Than</td>
|
443
449
|
</tr>
|
444
450
|
<tr>
|
445
|
-
<td>`
|
451
|
+
<td>`LC::Query#greater_eq(field, value)`</td>
|
446
452
|
<td>Greater Than Or Equal To</td>
|
447
453
|
</tr>
|
448
454
|
<tr>
|
449
|
-
<td>`
|
455
|
+
<td>`LC::Query#not_eq(field, value)`</td>
|
450
456
|
<td>Not Equal To</td>
|
451
457
|
</tr>
|
452
458
|
<tr>
|
453
|
-
<td>`
|
459
|
+
<td>`LC::Query#value_in(field, values)`</td>
|
454
460
|
<td>Contained In</td>
|
455
461
|
</tr>
|
456
462
|
<tr>
|
457
|
-
<td>`
|
463
|
+
<td>`LC::Query#value_not_in(field, values)`</td>
|
458
464
|
<td>Not Contained in</td>
|
459
465
|
</tr>
|
460
466
|
<tr>
|
461
|
-
<td>`
|
467
|
+
<td>`LC::Query#exists(field, value=true)`</td>
|
462
468
|
<td>A value is set for the key</td>
|
463
469
|
</tr>
|
464
470
|
<tr>
|
465
|
-
<td>`
|
471
|
+
<td>`LC::Query#contains_all(field, values)`</td>
|
466
472
|
<td>Contains all values in the array</td>
|
467
473
|
</tr>
|
468
474
|
<tr>
|
469
|
-
<td>`
|
475
|
+
<td>`LC::Query#select`</td>
|
470
476
|
<td>TODO: `$select` not yet implemented. This matches a value for a key in the result of a different query</td>
|
471
477
|
</tr>
|
472
478
|
</table>
|
@@ -474,7 +480,7 @@ Other constraint methods include:
|
|
474
480
|
For example, to retrieve scores between 1000 and 3000, including the endpoints, we could issue:
|
475
481
|
|
476
482
|
```ruby
|
477
|
-
scores =
|
483
|
+
scores = LC::Query.new("GameScore").tap do |q|
|
478
484
|
q.greater_eq("score", 1000)
|
479
485
|
q.less_eq("score", 3000)
|
480
486
|
end.get
|
@@ -483,7 +489,7 @@ end.get
|
|
483
489
|
To retrieve scores equal to an odd number below 10, we could issue:
|
484
490
|
|
485
491
|
```ruby
|
486
|
-
scores =
|
492
|
+
scores = LC::Query.new("GameScore").tap do |q|
|
487
493
|
q.value_in("score", [1,3,5,7,9])
|
488
494
|
end.get
|
489
495
|
```
|
@@ -491,7 +497,7 @@ end.get
|
|
491
497
|
To retrieve scores not by a given list of players we could issue:
|
492
498
|
|
493
499
|
```ruby
|
494
|
-
scores =
|
500
|
+
scores = LC::Query.new("GameScore").tap do |q|
|
495
501
|
q.value_not_in("playerName", ["Jonathan Walsh","Dario Wunsch","Shawn Simon"])
|
496
502
|
end.get
|
497
503
|
```
|
@@ -499,7 +505,7 @@ end.get
|
|
499
505
|
To retrieve documents with the score set, we could issue:
|
500
506
|
|
501
507
|
```ruby
|
502
|
-
scores =
|
508
|
+
scores = LC::Query.new("GameScore").tap do |q|
|
503
509
|
q.exists("score") # defaults to `true`
|
504
510
|
end.get
|
505
511
|
```
|
@@ -507,7 +513,7 @@ end.get
|
|
507
513
|
To retrieve documents without the score set, we could issue:
|
508
514
|
|
509
515
|
```ruby
|
510
|
-
scores =
|
516
|
+
scores = LC::Query.new("GameScore").tap do |q|
|
511
517
|
q.exists("score", false)
|
512
518
|
end.get
|
513
519
|
```
|
@@ -515,7 +521,7 @@ end.get
|
|
515
521
|
If you have a class containing sports teams and you store a user's hometown in the user class, you can issue one query to find the list of users whose hometown teams have winning records. The query would look like:
|
516
522
|
|
517
523
|
```ruby
|
518
|
-
users =
|
524
|
+
users = LC::Query.new("_User").tap do |users_query|
|
519
525
|
users_query.eq("hometown", {
|
520
526
|
"$select" => {
|
521
527
|
"query" => {
|
@@ -532,10 +538,10 @@ end.get
|
|
532
538
|
|
533
539
|
Currently, there is no convenience method provided for `$select` queries. However, they are still possible. This is a good example of the flexibility of parse-ruby-client. You usually do not need to wait for a feature to be added in order to user it. If you have a good idea on what a convencience method for this should look like, please file an issue, or even better, submit a pull request.
|
534
540
|
|
535
|
-
You can use the `
|
541
|
+
You can use the `LC::Query#order_by` method to specify a field to sort by. By default, everything is ordered ascending. Thus, to retrieve scores in ascending order:
|
536
542
|
|
537
543
|
```ruby
|
538
|
-
scores =
|
544
|
+
scores = LC::Query.new("GameScore").tap do |q|
|
539
545
|
q.order_by = "score"
|
540
546
|
end.get
|
541
547
|
```
|
@@ -543,7 +549,7 @@ end.get
|
|
543
549
|
And to retrieve scores in descending order:
|
544
550
|
|
545
551
|
```ruby
|
546
|
-
scores =
|
552
|
+
scores = LC::Query.new("GameScore").tap do |q|
|
547
553
|
q.order_by = "score"
|
548
554
|
q.order = :descending
|
549
555
|
end.get
|
@@ -552,7 +558,7 @@ end.get
|
|
552
558
|
You can sort by multiple fields by passing order a comma-separated list. Currently, there is no convenience method to accomplish this. However, you can still manually construct an `order` string. To retrieve documents that are ordered by scores in ascending order and the names in descending order:
|
553
559
|
|
554
560
|
```ruby
|
555
|
-
scores =
|
561
|
+
scores = LC::Query.new("GameScore").tap do |q|
|
556
562
|
q.order_by = "score,-name"
|
557
563
|
end.get
|
558
564
|
```
|
@@ -560,7 +566,7 @@ end.get
|
|
560
566
|
You can use the `limit` and `skip` parameters for pagination. `limit` defaults to 100, but anything from 1 to 1000 is a valid limit. Thus, to retrieve 200 objects after skipping the first 400:
|
561
567
|
|
562
568
|
```ruby
|
563
|
-
scores =
|
569
|
+
scores = LC::Query.new("GameScore").tap do |q|
|
564
570
|
q.limit = 200
|
565
571
|
q.skip = 400
|
566
572
|
end.get
|
@@ -573,13 +579,13 @@ All of these parameters can be used in combination with each other.
|
|
573
579
|
For keys with an array type, you can find objects where the key's array value contains 2 by:
|
574
580
|
|
575
581
|
```ruby
|
576
|
-
randos =
|
582
|
+
randos = LC::Query.new("RandomObject").eq("arrayKey", 2).get
|
577
583
|
```
|
578
584
|
|
579
585
|
You can also query that the array contains multiple objects by using contains all, for example you can return objects that have the array values 2 AND 3 by:
|
580
586
|
|
581
587
|
```ruby
|
582
|
-
randos =
|
588
|
+
randos = LC::Query.new("RandomObject").eq("arrayKey", [2, 3]).get
|
583
589
|
```
|
584
590
|
|
585
591
|
### Relational Queries
|
@@ -587,36 +593,36 @@ randos = AV::Query.new("RandomObject").eq("arrayKey", [2, 3]).get
|
|
587
593
|
There are several ways to issue queries for relational data. For example, if each `Comment` has a `Post` object in its `post` field, you can fetch comments for a particular `Post`:
|
588
594
|
|
589
595
|
```ruby
|
590
|
-
comments =
|
591
|
-
q.eq("post",
|
596
|
+
comments = LC::Query.new("Comment").tap do |q|
|
597
|
+
q.eq("post", LC::Pointer.new({
|
592
598
|
"className" => "Post",
|
593
599
|
"objectId" => "8TOXdXf3tz"
|
594
600
|
}))
|
595
601
|
end.get
|
596
602
|
```
|
597
603
|
|
598
|
-
If you want to retrieve objects where a field contains an object that matches another query, you can use the `
|
604
|
+
If you want to retrieve objects where a field contains an object that matches another query, you can use the `LC::Query#in_query(field, query=nil)` method. Note that the default limit of 100 and maximum limit of 1000 apply to the inner query as well, so with large data sets you may need to construct queries carefully to get the desired behavior. For example, imagine you have `Post` class and a `Comment` class, where each `Comment` has a relation to its parent `Post`. You can find comments on posts with images by doing:
|
599
605
|
|
600
606
|
```ruby
|
601
|
-
comments =
|
602
|
-
comments_query.in_query("post",
|
607
|
+
comments = LC::Query.new("Comment").tap do |comments_query|
|
608
|
+
comments_query.in_query("post", LC::Query.new("Post").tap do |posts_query|
|
603
609
|
posts_query.exists("image")
|
604
610
|
end)
|
605
611
|
end.get
|
606
612
|
```
|
607
613
|
|
608
|
-
Note: You must pass an instance of `
|
614
|
+
Note: You must pass an instance of `LC::Query` as the second argument for `LC::Query#query_in`. You cannot manually construct queries for this.
|
609
615
|
|
610
616
|
TODO: Implement this:
|
611
617
|
```
|
612
618
|
If you want to retrieve objects where a field contains an object that does not match another query, you can use the $notInQuery operator. Imagine you have Post class and a Comment class, where each Comment has a relation to its parent Post. You can find comments on posts without images by doing:
|
613
619
|
```
|
614
620
|
|
615
|
-
If you want to retrieve objects that are members of `Relation` field of a parent object, you can use the `
|
621
|
+
If you want to retrieve objects that are members of `Relation` field of a parent object, you can use the `LC::Query#related_to(field, value)` method. Imagine you have a `Post `class and `User` class, where each `Post` can be liked by many users. If the `Users` that liked a Post was stored in a `Relation` on the post under the key likes, you, can the find the users that liked a particular post by:
|
616
622
|
|
617
623
|
```ruby
|
618
|
-
users =
|
619
|
-
q.related_to("likes",
|
624
|
+
users = LC::Query.new("_User").tap do |q|
|
625
|
+
q.related_to("likes", LC::Pointer.new({
|
620
626
|
"className" => "Post",
|
621
627
|
"objectId" => "8TOXdXf3tz"
|
622
628
|
}))
|
@@ -626,7 +632,7 @@ end.get
|
|
626
632
|
In some situations, you want to return multiple types of related objects in one query. You can do this by passing the field to include in the `include` parameter. For example, let's say you are retrieving the last ten comments, and you want to retrieve their related posts at the same time:
|
627
633
|
|
628
634
|
```ruby
|
629
|
-
comments =
|
635
|
+
comments = LC::Query.new("Comment").tap do |q|
|
630
636
|
q.order_by = "createdAt"
|
631
637
|
q.order = :descending
|
632
638
|
q.limit = 10
|
@@ -660,7 +666,7 @@ When the query is issued with an `include` parameter for the key holding this po
|
|
660
666
|
You can also do multi level includes using dot notation. If you wanted to include the post for a comment and the post's author as well you can do:
|
661
667
|
|
662
668
|
```ruby
|
663
|
-
comments =
|
669
|
+
comments = LC::Query.new("Comment").tap do |q|
|
664
670
|
q.order_by = "createdAt"
|
665
671
|
q.order = :descending
|
666
672
|
q.limit = 10
|
@@ -671,7 +677,7 @@ end.get
|
|
671
677
|
You can issue a query with multiple fields included by passing a comma-separated list of keys as the include parameter:
|
672
678
|
|
673
679
|
```ruby
|
674
|
-
comments =
|
680
|
+
comments = LC::Query.new("Comment").tap do |q|
|
675
681
|
q.include("post,author")
|
676
682
|
end.get
|
677
683
|
```
|
@@ -681,7 +687,7 @@ end.get
|
|
681
687
|
If you are limiting your query, or if there are a very large number of results, and you want to know how many total results there are without returning them all, you can use the `count` parameter. For example, if you only care about the number of games played by a particular player:
|
682
688
|
|
683
689
|
```ruby
|
684
|
-
count =
|
690
|
+
count = LC::Query.new("GameScore").tap do |q|
|
685
691
|
q.eq("playerName", "Jonathan Walsh")
|
686
692
|
q.limit = 0
|
687
693
|
q.count
|
@@ -692,13 +698,13 @@ With a nonzero limit, that request would return results as well as the count.
|
|
692
698
|
|
693
699
|
### Compound Queries
|
694
700
|
|
695
|
-
If you want to find objects that match one of several queries, you can use `
|
701
|
+
If you want to find objects that match one of several queries, you can use `LC::Quer#or` method, with an `Array` as its value. For instance, if you want to find players with either have a lot of wins or a few wins, you can do:
|
696
702
|
|
697
703
|
```ruby
|
698
704
|
|
699
|
-
players =
|
705
|
+
players = LC::Query.new("Player").tap do |q|
|
700
706
|
q.greater_than("wins", 150)
|
701
|
-
q.or(
|
707
|
+
q.or(LC::Query.new("Player").tap do |or_query|
|
702
708
|
or_query.less_than("wins, 5")
|
703
709
|
end)
|
704
710
|
end.get
|
@@ -706,7 +712,7 @@ end.get
|
|
706
712
|
|
707
713
|
## Users
|
708
714
|
|
709
|
-
Many apps have a unified login that works across the mobile app and other systems. Accessing user accounts through parse-ruby-client lets you build this functionality on top of
|
715
|
+
Many apps have a unified login that works across the mobile app and other systems. Accessing user accounts through parse-ruby-client lets you build this functionality on top of LC.
|
710
716
|
|
711
717
|
In general, users have the same features as other objects, such as the flexible schema. The differences are that user objects must have a username and password, the password is automatically encrypted and stored securely, and Parse enforces the uniqueness of the `username` and `email` fields.
|
712
718
|
|
@@ -716,10 +722,10 @@ Signing up a new user differs from creating a generic object in that the `userna
|
|
716
722
|
|
717
723
|
You can ask Parse to verify user email addresses in your application settings page. With this setting enabled, all new user registrations with an `email` field will generate an email confirmation at that address. You can check whether the user has verified their `email` with the `emailVerified` field.
|
718
724
|
|
719
|
-
To sign up a new user, create a new `
|
725
|
+
To sign up a new user, create a new `LC::User` object and then call `#save` on it:
|
720
726
|
|
721
727
|
```ruby
|
722
|
-
user =
|
728
|
+
user = LC::User.new({
|
723
729
|
:username => "cooldude6",
|
724
730
|
:password => "p_n7!-e8",
|
725
731
|
:phone => "415-392-0202"
|
@@ -727,7 +733,7 @@ user = AV::User.new({
|
|
727
733
|
user.save
|
728
734
|
```
|
729
735
|
|
730
|
-
The response body is a `
|
736
|
+
The response body is a `LC::User` object containing the `objectId`, the `createdAt` timestamp of the newly-created object, and the `sessionToken` which can be used to authenticate subsequent requests as this user:
|
731
737
|
|
732
738
|
```ruby
|
733
739
|
{"username"=>"cooldude6",
|
@@ -739,13 +745,13 @@ The response body is a `AV::User` object containing the `objectId`, the `created
|
|
739
745
|
|
740
746
|
### Logging In
|
741
747
|
|
742
|
-
After you allow users to sign up, you need to let them log in to their account with a username and password in the future. To do this, call `
|
748
|
+
After you allow users to sign up, you need to let them log in to their account with a username and password in the future. To do this, call `LC::User#authenticate(username, password)`:
|
743
749
|
|
744
750
|
```ruby
|
745
|
-
user =
|
751
|
+
user = LC::User.authenticate("cooldude6", "p_n7!-e8")
|
746
752
|
```
|
747
753
|
|
748
|
-
The response body is a `
|
754
|
+
The response body is a `LC::User` object containing all the user-provided fields except `password`. It also contains the `createdAt`, `updatedAt`, `objectId`, and `sessionToken` fields:
|
749
755
|
|
750
756
|
```ruby
|
751
757
|
{"username"=>"cooldude6",
|
@@ -770,10 +776,10 @@ There are three `emailVerified` states to consider:
|
|
770
776
|
|
771
777
|
### Requesting A Password Reset
|
772
778
|
|
773
|
-
You can initiate password resets for users who have emails associated with their account. To do this, use `
|
779
|
+
You can initiate password resets for users who have emails associated with their account. To do this, use `LC::User::reset_password`:
|
774
780
|
|
775
781
|
```ruby
|
776
|
-
resp =
|
782
|
+
resp = LC::User.reset_password("coolguy@iloveapps.com")
|
777
783
|
puts resp #=> {}
|
778
784
|
```
|
779
785
|
|
@@ -781,13 +787,13 @@ If successful, the response body is an empty `Hash` object.
|
|
781
787
|
|
782
788
|
### Retrieving Users
|
783
789
|
|
784
|
-
You can also retrieve the contents of a user object by using `
|
790
|
+
You can also retrieve the contents of a user object by using `LC::Query`. For example, to retrieve the user created above:
|
785
791
|
|
786
792
|
```ruby
|
787
|
-
user =
|
793
|
+
user = LC::Query.new("_User").eq("objectId", "2bMfWZQ9Ob").get.first
|
788
794
|
```
|
789
795
|
|
790
|
-
The response body is a `
|
796
|
+
The response body is a `LC::User` object containing all the user-provided fields except `password`. It also contains the `createdAt`, `updatedAt`, and `objectId` fields:
|
791
797
|
|
792
798
|
```ruby
|
793
799
|
{"username"=>"cooldude6",
|
@@ -808,7 +814,7 @@ To change the data on a user that already exists, send a PUT request to the user
|
|
808
814
|
For example, if we wanted to change the phone number for cooldude6:
|
809
815
|
|
810
816
|
```ruby
|
811
|
-
user =
|
817
|
+
user = LC::Query.new("_User").eq("objectId", "2bMfWZQ9Ob").get.first
|
812
818
|
user["phone"] = "415-369-6201"
|
813
819
|
user.save
|
814
820
|
```
|
@@ -816,24 +822,24 @@ user.save
|
|
816
822
|
Currently returns the following error:
|
817
823
|
|
818
824
|
```
|
819
|
-
|
825
|
+
LC::LCProtocolError: 206: LC::UserCannotBeAlteredWithoutSessionError
|
820
826
|
```
|
821
827
|
|
822
828
|
### Querying
|
823
829
|
|
824
|
-
You can retrieve multiple users at once by using `
|
830
|
+
You can retrieve multiple users at once by using `LC::Query`:
|
825
831
|
|
826
832
|
```ruby
|
827
|
-
users =
|
833
|
+
users = LC::Query.new("_User").get
|
828
834
|
```
|
829
835
|
|
830
|
-
The return value is an `Array` of `
|
836
|
+
The return value is an `Array` of `LC::User` objects:
|
831
837
|
|
832
838
|
```ruby
|
833
839
|
[{"username"=>"fake_person",
|
834
840
|
"createdAt"=>"2012-04-20T20:07:32.295Z",
|
835
841
|
"updatedAt"=>"2012-04-20T20:07:32.295Z",
|
836
|
-
"objectId"=>"
|
842
|
+
"objectId"=>"ALCwfClOx9"},
|
837
843
|
{"username"=>"fake_person222",
|
838
844
|
"createdAt"=>"2012-04-20T20:07:32.946Z",
|
839
845
|
"updatedAt"=>"2012-04-20T20:07:32.946Z",
|
@@ -907,7 +913,7 @@ Signing a user up with a linked service and logging them in with that service us
|
|
907
913
|
|
908
914
|
```ruby
|
909
915
|
# should look something like this:
|
910
|
-
twitter_user =
|
916
|
+
twitter_user = LC::User::Twitter.new({
|
911
917
|
"id" => "12345678",
|
912
918
|
"screen_name" => "ParseIt",
|
913
919
|
"consumer_key" => "SaMpLeId3X7eLjjLgWEw",
|
@@ -964,7 +970,7 @@ Linking an existing user with a service like Facebook or Twitter uses a PUT requ
|
|
964
970
|
```ruby
|
965
971
|
# should look something like this:
|
966
972
|
|
967
|
-
user =
|
973
|
+
user = LC::Query.new("_User").eq("objectId", "2bMfWZQ9Ob").get.first
|
968
974
|
user.link_to_facebook!({
|
969
975
|
"id" => "123456789",
|
970
976
|
"access_token" => "SaMpLeAAibS7Q55FSzcERWIEmzn6rosftAr7pmDME10008bWgyZAmv7mziwfacNOhWkgxDaBf8a2a2FCc9Hbk9wAsqLYZBLR995wxBvSGNoTrEaL",
|
@@ -988,7 +994,7 @@ Unlinking an existing user with a service also uses a PUT request to clear authD
|
|
988
994
|
```ruby
|
989
995
|
# should look something like this:
|
990
996
|
|
991
|
-
user =
|
997
|
+
user = LC::Query.new("_User").eq("objectId", "2bMfWZQ9Ob").get.first
|
992
998
|
user.unlink_from_facebook!
|
993
999
|
```
|
994
1000
|
|
@@ -1026,10 +1032,10 @@ See https://leancloud.cn/docs/rest_api.html#角色-1
|
|
1026
1032
|
|
1027
1033
|
### Uploading Files
|
1028
1034
|
|
1029
|
-
To upload a file to Parse, use `
|
1035
|
+
To upload a file to Parse, use `LC::File`. You must include the `"Content-Type"` parameter when instantiating. Keep in mind that files are limited to 10 megabytes. Here's a simple example that'll create a file named `hello.txt` containing a string:
|
1030
1036
|
|
1031
1037
|
```ruby
|
1032
|
-
file =
|
1038
|
+
file = LC::File.new({
|
1033
1039
|
:body => "Hello World!",
|
1034
1040
|
:local_filename => "hello.txt",
|
1035
1041
|
:content_type => "text/plain"
|
@@ -1048,7 +1054,7 @@ The response body is a `Hash` object containing the name of the file, which is t
|
|
1048
1054
|
To upload an image, the syntax is a little bit different. Here's an example that will upload the image parsers.jpg from the current directory:
|
1049
1055
|
|
1050
1056
|
```ruby
|
1051
|
-
photo =
|
1057
|
+
photo = LC::File.new({
|
1052
1058
|
:body => IO.read("test/parsers.jpg"),
|
1053
1059
|
:local_filename => "parsers.jpg",
|
1054
1060
|
:content_type => "image/jpeg"
|
@@ -1061,13 +1067,13 @@ photo.save
|
|
1061
1067
|
After files are uploaded, you can associate them with Parse objects:
|
1062
1068
|
|
1063
1069
|
```ruby
|
1064
|
-
photo =
|
1070
|
+
photo = LC::File.new({
|
1065
1071
|
:body => IO.read("test/parsers.jpg"),
|
1066
1072
|
:local_filename => "parsers.jpg",
|
1067
1073
|
:content_type => "image/jpeg"
|
1068
1074
|
})
|
1069
1075
|
photo.save
|
1070
|
-
player_profile =
|
1076
|
+
player_profile = LC::Object.new("PlayerProfile").tap do |p|
|
1071
1077
|
p["name"] = "All the Parsers"
|
1072
1078
|
p["picture"] = photo
|
1073
1079
|
end.save
|
@@ -1090,7 +1096,7 @@ For config/installation: https://leancloud.cn/docs/push_guide.html#使用_REST_A
|
|
1090
1096
|
To send a notification to the "Giants" channel, as given at: https://leancloud.cn/docs/push_guide.html
|
1091
1097
|
```ruby
|
1092
1098
|
data = { :alert => "This is a notification from Parse" }
|
1093
|
-
push =
|
1099
|
+
push = LC::Push.new(data, "Giants")
|
1094
1100
|
push.type = "ios"
|
1095
1101
|
push.save
|
1096
1102
|
```
|
@@ -1102,9 +1108,9 @@ To send a notification to installations where `injuryReports` is `true`, as give
|
|
1102
1108
|
|
1103
1109
|
```ruby
|
1104
1110
|
data = { :alert => "This is a notification from Parse" }
|
1105
|
-
push =
|
1111
|
+
push = LC::Push.new(data)
|
1106
1112
|
push.type = "ios"
|
1107
|
-
query =
|
1113
|
+
query = LC::Query.new(LC::Protocol::CLASS_INSTALLATION).eq('injuryReports', true)
|
1108
1114
|
push.where = query.where
|
1109
1115
|
push.save
|
1110
1116
|
```
|
@@ -1114,16 +1120,16 @@ push.save
|
|
1114
1120
|
#### Retrieving Installations
|
1115
1121
|
|
1116
1122
|
```ruby
|
1117
|
-
installation =
|
1123
|
+
installation = LC::Installation.get "objectId"
|
1118
1124
|
# Same as
|
1119
|
-
installation =
|
1125
|
+
installation = LC::Installation.new "objectId"
|
1120
1126
|
installation.get
|
1121
1127
|
```
|
1122
1128
|
|
1123
1129
|
#### Updating installations
|
1124
1130
|
|
1125
1131
|
```ruby
|
1126
|
-
installation =
|
1132
|
+
installation = LC::Installation.new "objectId"
|
1127
1133
|
installation.channels = ["", "my-channel-name"]
|
1128
1134
|
installation.badge = 5
|
1129
1135
|
installation.save
|
@@ -1138,8 +1144,8 @@ Parse allows you to associate real-world latitude and longitude coordinates with
|
|
1138
1144
|
To associate a point with an object you will need to embed a GeoPoint data type into your object. This is done by using a JSON object with __type set to the string GeoPoint and numeric values being set for the latitude and longitude keys. For example, to create an object containing a point under the "location" key with a latitude of 40.0 degrees and -30.0 degrees longitude:
|
1139
1145
|
|
1140
1146
|
```ruby
|
1141
|
-
place =
|
1142
|
-
p["location"] =
|
1147
|
+
place = LC::Object.new("PlaceObject").tap do |p|
|
1148
|
+
p["location"] = LC::GeoPoint.new({
|
1143
1149
|
"latitude" => 40.0,
|
1144
1150
|
"longitude" => -30.0
|
1145
1151
|
})
|
@@ -1154,7 +1160,7 @@ Now that you have a bunch of objects with spatial coordinates, it would be nice
|
|
1154
1160
|
|
1155
1161
|
```ruby
|
1156
1162
|
# should look something like this:
|
1157
|
-
places =
|
1163
|
+
places = LC::Query.new("PlaceObject").tap do |q|
|
1158
1164
|
q.near("location", {
|
1159
1165
|
"latitude" => 30.0,
|
1160
1166
|
"longitude" => -20.0
|
@@ -1172,6 +1178,28 @@ At the moment there are a couple of things to watch out for:
|
|
1172
1178
|
|
1173
1179
|
2. Points should not equal or exceed the extreme ends of the ranges. Latitude should not be -90.0 or 90.0. Longitude should not be -180.0 or 180.0. Attempting to use GeoPoint's with latitude and/or longitude outside these ranges will cause an error.
|
1174
1180
|
|
1181
|
+
## Cloud Function
|
1182
|
+
|
1183
|
+
You can call cloud function which you have had written in `main.js`.
|
1184
|
+
|
1185
|
+
### How to use
|
1186
|
+
|
1187
|
+
```ruby
|
1188
|
+
# should look something like this:
|
1189
|
+
LC::Cloud::Function.new("hello").call(foo: "bar", ...)
|
1190
|
+
# or call it without params like this:
|
1191
|
+
LC::Cloud::Function.new("hello").call
|
1192
|
+
```
|
1193
|
+
|
1194
|
+
### Request sms code
|
1195
|
+
|
1196
|
+
```ruby
|
1197
|
+
# this should get the sms code
|
1198
|
+
LC::Cloud.request_sms(params)
|
1199
|
+
# this should verify sms code
|
1200
|
+
LC::Cloud.verify_sms_code(phone, code)
|
1201
|
+
```
|
1202
|
+
|
1175
1203
|
# 原始文档
|
1176
1204
|
|
1177
1205
|
[parse-ruby-client](https://github.com/adelevie/parse-ruby-client)
|