parse-stack 1.5.1 → 1.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changes.md +15 -1
- data/Gemfile.lock +10 -10
- data/README.md +23 -9
- data/bin/console +3 -0
- data/lib/parse/api/analytics.rb +1 -1
- data/lib/parse/api/objects.rb +1 -1
- data/lib/parse/api/users.rb +1 -1
- data/lib/parse/client.rb +77 -40
- data/lib/parse/client/caching.rb +9 -5
- data/lib/parse/client/protocol.rb +47 -0
- data/lib/parse/client/request.rb +66 -37
- data/lib/parse/client/response.rb +39 -21
- data/lib/parse/model/acl.rb +4 -9
- data/lib/parse/model/associations/belongs_to.rb +97 -9
- data/lib/parse/model/associations/collection_proxy.rb +89 -29
- data/lib/parse/model/associations/has_many.rb +301 -28
- data/lib/parse/model/associations/has_one.rb +98 -4
- data/lib/parse/model/associations/pointer_collection_proxy.rb +48 -16
- data/lib/parse/model/associations/relation_collection_proxy.rb +61 -36
- data/lib/parse/model/bytes.rb +11 -5
- data/lib/parse/model/classes/installation.rb +50 -3
- data/lib/parse/model/classes/role.rb +7 -2
- data/lib/parse/model/classes/session.rb +21 -4
- data/lib/parse/model/classes/user.rb +122 -22
- data/lib/parse/model/core/actions.rb +7 -3
- data/lib/parse/model/core/properties.rb +14 -13
- data/lib/parse/model/core/querying.rb +16 -10
- data/lib/parse/model/core/schema.rb +2 -3
- data/lib/parse/model/date.rb +18 -12
- data/lib/parse/model/file.rb +77 -19
- data/lib/parse/model/geopoint.rb +70 -12
- data/lib/parse/model/model.rb +84 -8
- data/lib/parse/model/object.rb +225 -94
- data/lib/parse/model/pointer.rb +94 -13
- data/lib/parse/model/push.rb +76 -4
- data/lib/parse/query.rb +356 -41
- data/lib/parse/query/constraints.rb +399 -29
- data/lib/parse/query/ordering.rb +21 -8
- data/lib/parse/stack.rb +1 -0
- data/lib/parse/stack/version.rb +2 -1
- data/lib/parse/webhooks.rb +0 -24
- data/lib/parse/webhooks/payload.rb +54 -1
- data/lib/parse/webhooks/registration.rb +13 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4da68d2d9e3ed4e2607a9fadaae3cd833755492d
|
4
|
+
data.tar.gz: a0ebd3622b1daedde1396993ad5f777522c3ecb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ecf353df19d8b5c24acf57d472d9e1a166e055e1f8648f596b2d9b78e8755855fc623e4347ff656891a6ba64ad137a3e61bdb1be9435e9719ac4f833eb53d689
|
7
|
+
data.tar.gz: 06ba25aaa84702d56dc87a030aec5c99ea4858686b38ff9bfe261bc2128ca50dc6969652632033e5153e8eb6c906d8ccd9dc3023282fc4972af7206eaac86a92
|
data/Changes.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
## Parse-Stack Changelog
|
2
2
|
|
3
|
+
### 1.5.2
|
4
|
+
- FIXES #16: Constraints to `count` were not properly handled.
|
5
|
+
- FIXES #15: Incorrect call to `request_password_reset`.
|
6
|
+
- FIXES #14: Typos
|
7
|
+
- FIXES: Issues when passing a block to chaining scope.
|
8
|
+
- FIXES: Enums properly handle default values.
|
9
|
+
- FIXES: Enums macro methods now are dirty tracked.
|
10
|
+
- FIXES: #17: overloads inspect to show objects in a has_many scope.
|
11
|
+
- `reload!` and session methods support client request options.
|
12
|
+
- Proactively deletes possible matching cache keys on non GET requests.
|
13
|
+
- Parse::File now has a `force_ssl` option that makes sure all urls returned are `https`.
|
14
|
+
- Documentation
|
15
|
+
- ParseConstraintError is now Parse::ConstraintError.
|
16
|
+
|
3
17
|
### 1.5.1
|
4
18
|
- BREAKING CHANGE: The default `has_many` implementation is `:query` instead of `:array`.
|
5
19
|
- NEW: Support for `has_one` type of associations.
|
@@ -52,7 +66,7 @@
|
|
52
66
|
- Added new `ServiceUnavailableError` exception for Parse error code 2 and HTTP 503 errors.
|
53
67
|
- Upon a `ServiceUnavailableError`, we will retry the request one more time after 2 seconds.
|
54
68
|
- `:not_in` and `:contains_all` queries will format scalar values into an array.
|
55
|
-
- `:exists` and `:null` will raise `
|
69
|
+
- `:exists` and `:null` will raise `ConstraintError` if non-boolean values are passed.
|
56
70
|
- NEW: `:id` constraint to allow passing an objectId to a query where we will infer the class.
|
57
71
|
|
58
72
|
### 1.3.7
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
parse-stack (1.5.
|
4
|
+
parse-stack (1.5.2)
|
5
5
|
active_model_serializers (>= 0.9, < 1)
|
6
6
|
activemodel (>= 4.2.1, < 6)
|
7
7
|
activesupport (>= 4.2.1, < 6)
|
@@ -42,7 +42,7 @@ GEM
|
|
42
42
|
binding_of_caller (0.7.2)
|
43
43
|
debug_inspector (>= 0.0.1)
|
44
44
|
builder (3.2.2)
|
45
|
-
byebug (9.0.
|
45
|
+
byebug (9.0.6)
|
46
46
|
coderay (1.1.1)
|
47
47
|
concurrent-ruby (1.0.2)
|
48
48
|
debug_inspector (0.0.2)
|
@@ -53,21 +53,21 @@ GEM
|
|
53
53
|
faraday_middleware (0.10.0)
|
54
54
|
faraday (>= 0.7.4, < 0.10)
|
55
55
|
i18n (0.7.0)
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
jsonapi (0.1.1.beta6)
|
57
|
+
jsonapi-parser (= 0.1.1.beta3)
|
58
|
+
jsonapi-renderer (= 0.1.1.beta1)
|
59
|
+
jsonapi-parser (0.1.1.beta3)
|
60
|
+
jsonapi-renderer (0.1.1.beta1)
|
59
61
|
loofah (2.0.3)
|
60
62
|
nokogiri (>= 1.5.9)
|
61
63
|
method_source (0.8.2)
|
62
64
|
mini_portile2 (2.1.0)
|
63
|
-
minitest (5.9.
|
65
|
+
minitest (5.9.1)
|
64
66
|
moneta (0.8.0)
|
65
67
|
multipart-post (2.0.0)
|
66
|
-
nokogiri (1.6.8)
|
68
|
+
nokogiri (1.6.8.1)
|
67
69
|
mini_portile2 (~> 2.1.0)
|
68
|
-
pkg-config (~> 1.1.7)
|
69
70
|
parallel (1.9.0)
|
70
|
-
pkg-config (1.1.7)
|
71
71
|
pry (0.10.4)
|
72
72
|
coderay (~> 1.1.0)
|
73
73
|
method_source (~> 0.8.1)
|
@@ -112,4 +112,4 @@ DEPENDENCIES
|
|
112
112
|
rake
|
113
113
|
|
114
114
|
BUNDLED WITH
|
115
|
-
1.
|
115
|
+
1.13.3
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Parse-Stack -
|
1
|
+
# Parse-Stack - The Parse Server Ruby Client and ORM
|
2
2
|
Parse-Stack is a [Parse Server](https://github.com/ParsePlatform/parse-server) REST API Client and ORM framework for ruby. It provides a client adapter, a query engine, an object relational mapper (ORM) and a Cloud Code Webhooks rack application.
|
3
3
|
|
4
4
|
### Code Status
|
@@ -226,7 +226,7 @@ The architecture of `Parse::Stack` is broken into four main components.
|
|
226
226
|
This class is the core and low level API for the Parse SDK REST interface that is used by the other components. It can manage multiple sessions, which means you can have multiple client instances pointing to different Parse Applications at the same time. It handles sending raw requests as well as providing Request/Response objects for all API handlers. The connection engine is Faraday, which means it is open to add any additional middleware for features you'd like to implement.
|
227
227
|
|
228
228
|
### Parse::Query
|
229
|
-
This class implements the [Parse REST Querying](
|
229
|
+
This class implements the [Parse REST Querying](http://parseplatform.github.io/docs/rest/guide/#queries) interface in the [DataMapper finder syntax style](http://datamapper.org/docs/find.html). It compiles a set of query constraints and utilizes `Parse::Client` to send the request and provide the raw results. This class can be used without the need to define models.
|
230
230
|
|
231
231
|
### Parse::Object
|
232
232
|
This component is main class for all object relational mapping subclasses for your application. It provides features in order to map your remote Parse records to a local ruby object. It implements the Active::Model interface to provide a lot of additional features, CRUD operations, querying, including dirty tracking, JSON serialization, save/destroy callbacks and others. While we are overlooking some functionality, for simplicity, you will mainly be working with Parse::Object as your superclass. While not required, it is highly recommended that you define a model (Parse::Object subclass) for all the Parse classes in your application.
|
@@ -286,7 +286,7 @@ Calling `setup` will create the default `Parse::Client` session object that will
|
|
286
286
|
There are additional connection options that you may pass the setup method when creating a `Parse::Client`.
|
287
287
|
|
288
288
|
#### `:server_url`
|
289
|
-
The server url of your Parse
|
289
|
+
The server url of your Parse Server if you are not using the hosted Parse.com service. By default it will use `PARSE_SERVER_URL` environment variable available or fall back to `https://api.parse.com/1/` if not specified.
|
290
290
|
|
291
291
|
#### `:app_id`
|
292
292
|
The Parse application id. By default it will use `PARSE_APP_ID` environment variable if not specified.
|
@@ -313,7 +313,7 @@ Sets the default cache expiration time (in seconds) for successful non-empty `GE
|
|
313
313
|
You may pass a hash of options that will be passed to the `Faraday` constructor.
|
314
314
|
|
315
315
|
## Parse Config
|
316
|
-
Getting your configuration variables once you have a default client setup can be done with `Parse.config`. The first time this method is called, Parse-Stack will get the configuration from Parse
|
316
|
+
Getting your configuration variables once you have a default client setup can be done with `Parse.config`. The first time this method is called, Parse-Stack will get the configuration from Parse Server, and cache it. To force a reload of the config, use `config!`. You
|
317
317
|
|
318
318
|
```ruby
|
319
319
|
Parse.setup( ... )
|
@@ -412,6 +412,19 @@ The default MIME type for all files is `image/jpeg`. This can be default can be
|
|
412
412
|
file = Parse::File.new parse_file
|
413
413
|
```
|
414
414
|
|
415
|
+
If you are using displaying these files on a secure site and want to make sure that urls returned by a call to `url` are `https`, you can set `Parse::File.force_ssl` to true.
|
416
|
+
|
417
|
+
```ruby
|
418
|
+
# Assume file is a Parse::File
|
419
|
+
|
420
|
+
file.url # => http://www.example.com/file.png
|
421
|
+
|
422
|
+
Parse::File.force_ssl = true # make all urls be https
|
423
|
+
|
424
|
+
file.url # => https://www.example.com/file.png
|
425
|
+
|
426
|
+
```
|
427
|
+
|
415
428
|
### Parse::Date
|
416
429
|
This class manages dates in the special JSON format it requires for properties of type `:date`. `Parse::Date` subclasses `DateTime`, which allows you to use any features or methods available to `DateTime` with `Parse::Date`. While the conversion between `Time` and `DateTime` objects to a `Parse::Date` object is done implicitly for you, you can use the added special methods, `DateTime#parse_date` and `Time#parse_date`, for special occasions.
|
417
430
|
|
@@ -1016,7 +1029,8 @@ user.band_by_status(false)
|
|
1016
1029
|
#### Has Many
|
1017
1030
|
Parse has many ways to implement one-to-many and many-to-many associations: `Array`, `Parse Relation` or through a `Query`. How you decide to implement your associations, will affect how `has_many` works in Parse-Stack. Parse natively supports one-to-many and many-to-many relationships using `Array` and `Relations`, as described in [Relational Data](https://parseplatform.github.io/docs/js/guide/#relational-data). Both of these methods require you define a specific column type in your Parse table that will be used to store information about the association.
|
1018
1031
|
|
1019
|
-
In addition to `Array` and `Relation`, Parse-Stack also implements the standard `has_many` behavior prevalent in other frameworks through a query where the associated class contains a foreign pointer to the local class, usually the inverse of a `belongs_to`. This requires that the associated class
|
1032
|
+
In addition to `Array` and `Relation`, Parse-Stack also implements the standard `has_many` behavior prevalent in other frameworks through a query where the associated class contains a foreign pointer to the local class, usually the inverse of a `belongs_to`. This requires that the associated class has a defined column
|
1033
|
+
that contains a pointer the refers to the defining class.
|
1020
1034
|
|
1021
1035
|
##### Query
|
1022
1036
|
In this implementation, a `has_many` association for a Parse class requires that another Parse class will have a foreign pointer that refers to instances of this class. This is the standard way that `has_many` relationships work in most databases systems. This is usually the case when you have a class that has a `belongs_to` relationship to instances of the local class.
|
@@ -1134,7 +1148,7 @@ Other than the use of arrays, Parse supports native one-to-many and many-to-many
|
|
1134
1148
|
2. Querying the relation is actually performed against the implicit join table, not the local one.
|
1135
1149
|
3. Applying query constraints for a set of records within a relation is performed against the foreign table class, not the class having the relational column.
|
1136
1150
|
|
1137
|
-
The Parse documentation provides more details on associations, see [Parse Relations Guide](
|
1151
|
+
The Parse documentation provides more details on associations, see [Parse Relations Guide](http://parseplatform.github.io/docs/ios/guide/#relations). Parse-Stack will handle the work for (2) and (3) automatically.
|
1138
1152
|
|
1139
1153
|
In the example below, a `Band` can have thousands of `Fans`. We setup a `Relation<Fan>` column in the `Band` class that references the `Fan` class. Parse-Stack provides methods to manage the relationship under the [Parse::RelationCollectionProxy](https://github.com/modernistik/parse-stack/blob/master/lib/parse/model/associations/relation_collection_proxy.rb) class.
|
1140
1154
|
|
@@ -1321,7 +1335,7 @@ To commit a new record or changes to an existing record to Parse, use the `#save
|
|
1321
1335
|
songs.save # save the rest of the items
|
1322
1336
|
```
|
1323
1337
|
|
1324
|
-
The save operation can handle both creating and updating existing objects. If you do not want to update the association data of a changed object, you may use the `#update` method to only save the changed property values. In the case where you want to force update an object even though it has not changed, to possibly trigger your `before_save` hooks, you can use the `#update!` method.
|
1338
|
+
The save operation can handle both creating and updating existing objects. If you do not want to update the association data of a changed object, you may use the `#update` method to only save the changed property values. In the case where you want to force update an object even though it has not changed, to possibly trigger your `before_save` hooks, you can use the `#update!` method. In addition, just like with other ActiveModel objects, you may call `reload!` to fetch the current record again from the data store.
|
1325
1339
|
|
1326
1340
|
#### Raising an exception when save fails
|
1327
1341
|
By default, we return `true` or `false` for save and destroy operations. If you prefer to have `Parse::Object` raise an exception instead, you can tell to do so either globally or on a per-model basis. When a save fails, it will raise a `Parse::SaveFailureError`.
|
@@ -1568,7 +1582,7 @@ When a query API is made, the results are cached in the query object in case you
|
|
1568
1582
|
```
|
1569
1583
|
|
1570
1584
|
### Counting
|
1571
|
-
If you only need to know the result count for a query, provide count a non-zero value. However, if you need to perform a count query, use `count()` method instead.
|
1585
|
+
If you only need to know the result count for a query, provide count a non-zero value. However, if you need to perform a count query, use `count()` method instead.
|
1572
1586
|
|
1573
1587
|
```ruby
|
1574
1588
|
# get number of songs with a play_count > 10
|
@@ -1659,7 +1673,7 @@ Song.all limit: 3, use_master_key: false
|
|
1659
1673
|
```
|
1660
1674
|
|
1661
1675
|
#### :session_token
|
1662
|
-
A Parse session token string. If you would like to perform a query as a particular user, you may pass their session token in the query. This will make sure that the query is performed on behalf (and with the
|
1676
|
+
A Parse session token string. If you would like to perform a query as a particular user, you may pass their session token in the query. This will make sure that the query is performed on behalf (and with the privileges) of that user which will cause record ACLs to be enforced. If a session token is provided, caching will be disabled for this request.
|
1663
1677
|
|
1664
1678
|
```ruby
|
1665
1679
|
# disable sending the master key in the request if configured
|
data/bin/console
CHANGED
@@ -8,6 +8,9 @@ Dotenv.load
|
|
8
8
|
|
9
9
|
Parse.setup
|
10
10
|
|
11
|
+
puts "[ParseServerURL] #{Parse.client.server_url}"
|
12
|
+
puts "[ParseAppID] #{Parse.client.app_id}"
|
13
|
+
|
11
14
|
# You can add fixtures and/or initialization code here to make experimenting
|
12
15
|
# with your gem easier. You can also use a different console, if you like.
|
13
16
|
|
data/lib/parse/api/analytics.rb
CHANGED
data/lib/parse/api/objects.rb
CHANGED
data/lib/parse/api/users.rb
CHANGED
@@ -78,7 +78,7 @@ module Parse
|
|
78
78
|
request :post, LOGOUT_PATH, headers: headers, opts: opts
|
79
79
|
end
|
80
80
|
|
81
|
-
#
|
81
|
+
# Signup a user given a username, password and, optionally, their email.
|
82
82
|
def signup(username, password, email = nil, body: {}, **opts)
|
83
83
|
body = body.merge({ username: username, password: password })
|
84
84
|
body[:email] = email || body[:email]
|
data/lib/parse/client.rb
CHANGED
@@ -18,7 +18,6 @@ require_relative "api/all"
|
|
18
18
|
|
19
19
|
module Parse
|
20
20
|
|
21
|
-
# This is an exception that is thrown if there is a client connectivity issue
|
22
21
|
class ConnectionError < StandardError; end;
|
23
22
|
class TimeoutError < StandardError; end;
|
24
23
|
class ProtocolError < StandardError; end;
|
@@ -28,31 +27,54 @@ module Parse
|
|
28
27
|
class RequestLimitExceededError < StandardError; end;
|
29
28
|
class InvalidSessionTokenError < StandardError; end;
|
30
29
|
|
31
|
-
#
|
32
|
-
|
33
|
-
|
30
|
+
# Retrieve the App specific Parse configuration parameters. The configuration
|
31
|
+
# for a connection is cached after the first request. Use the bang version to
|
32
|
+
# force update from the Parse backend.
|
33
|
+
# @see Parse.config!
|
34
|
+
# @param conn [Symbol] the name of the client connection to use.
|
35
|
+
# @return [Hash] the Parse config hash for the session.
|
36
|
+
def self.config(conn = :default)
|
37
|
+
Parse::Client.client(conn).config
|
34
38
|
end
|
35
39
|
|
36
|
-
|
37
|
-
|
40
|
+
# Set a parameter in the Parse configuration for an application.
|
41
|
+
# @param field [String] the name configuration variable.
|
42
|
+
# @param value [Object] the value configuration variable. Only Parse types are supported.
|
43
|
+
# @param conn [Symbol] the name of the client connection to use.
|
44
|
+
# @return [Hash] the Parse config hash for the session.
|
45
|
+
def self.set_config(field, value, conn = :default)
|
46
|
+
Parse::Client.client(conn).update_config({ field => value })
|
38
47
|
end
|
39
48
|
|
40
|
-
|
41
|
-
|
49
|
+
# Set a key value pairs in the Parse configuration for an application.
|
50
|
+
# @param params [Hash] a set of key value pairs to set in the Parse configuration.
|
51
|
+
# @param conn [Symbol] the name of the client connection to use.
|
52
|
+
# @return [Hash] the Parse config hash for the session.
|
53
|
+
def self.update_config(params, conn = :default)
|
54
|
+
Parse::Client.client(conn).update_config(params)
|
42
55
|
end
|
43
56
|
|
44
|
-
|
45
|
-
|
57
|
+
# Force fetch updated Parse configuration
|
58
|
+
# @param conn [Symbol] the name of the client connection to use.
|
59
|
+
# @return [Hash] the Parse configuration
|
60
|
+
def self.config!(conn = :default)
|
61
|
+
Parse::Client.client(conn).config!
|
46
62
|
end
|
47
63
|
|
64
|
+
# Helper method to get the default Parse client.
|
65
|
+
# @param conn [Symbol] the name of the client connection to use.
|
66
|
+
# @return [Parse::Client] a client object for the connection name.
|
48
67
|
def self.client(conn = :default)
|
49
68
|
Parse::Client.client(conn)
|
50
69
|
end
|
51
70
|
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
71
|
+
# This class is the core and low level API for the Parse SDK REST interface that
|
72
|
+
# is used by the other components. It can manage multiple sessions, which means
|
73
|
+
# you can have multiple client instances pointing to different Parse Applications
|
74
|
+
# at the same time. It handles sending raw requests as well as providing
|
75
|
+
# Request/Response objects for all API handlers. The connection engine is
|
76
|
+
# Faraday, which means it is open to add any additional middleware for
|
77
|
+
# features you'd like to implement.
|
56
78
|
class Client
|
57
79
|
include Parse::API::Objects
|
58
80
|
include Parse::API::Config
|
@@ -68,39 +90,56 @@ module Parse
|
|
68
90
|
RETRY_COUNT = 2
|
69
91
|
RETRY_DELAY = 2 #seconds
|
70
92
|
|
71
|
-
|
93
|
+
# @!attribute cache
|
94
|
+
# The underlying cache store for caching API requests.
|
95
|
+
# @return [Moneta::Transformer]
|
96
|
+
# @!attribute [r] application_id
|
97
|
+
# The Parse application identifier to be sent in every API request.
|
98
|
+
# @return [String]
|
99
|
+
# @!attribute [r] api_key
|
100
|
+
# The Parse API key to be sent in every API request.
|
101
|
+
# @return [String]
|
102
|
+
# @!attribute [r] master_key
|
103
|
+
# The Parse master key for this application, which when set, will be sent
|
104
|
+
# in every API request. (There is a way to prevent this on a per request basis.)
|
105
|
+
# @return [String]
|
106
|
+
# @!attribute [r] server_url
|
107
|
+
# The Parse server url that will be receiving these API requests. By default
|
108
|
+
# this will be {Parse::Protocol::SERVER_URL}.
|
109
|
+
# @return [String]
|
110
|
+
attr_accessor :cache
|
72
111
|
attr_reader :application_id, :api_key, :master_key, :server_url
|
112
|
+
alias_method :app_id, :application_id
|
73
113
|
# The client can support multiple sessions. The first session created, will be placed
|
74
114
|
# under the default session tag. The :default session will be the default client to be used
|
75
115
|
# by the other classes including Parse::Query and Parse::Objects
|
76
116
|
@clients = { default: nil }
|
77
117
|
class << self
|
118
|
+
# @!attribute [r] clients
|
119
|
+
# A hash of Parse::Client instances.
|
120
|
+
# @return [Hash<Parse::Client>]
|
78
121
|
attr_reader :clients
|
79
|
-
def session?(v = :default)
|
80
|
-
puts '[Warning] Parse::Client#session is DEPRECATED. Please use Parse::Client#client instead.'
|
81
|
-
self.client? v
|
82
|
-
end
|
83
|
-
|
84
|
-
# DEPRECATED
|
85
|
-
# get a session for a given tag. This will also create a new one for the tag if not specified.
|
86
|
-
def session(connection = :default)
|
87
|
-
puts '[Warning] Parse::Client#session is DEPRECATED. Please use Parse::Client#client instead.'
|
88
|
-
self.client(connection)
|
89
|
-
end
|
90
122
|
|
91
|
-
|
92
|
-
|
123
|
+
# @param conn [Symbol] the name of the connection.
|
124
|
+
# @return [Boolean] true if a Parse::Client has been configured.
|
125
|
+
def client?(conn = :default)
|
126
|
+
@clients[conn].present?
|
93
127
|
end
|
94
128
|
|
95
|
-
|
96
|
-
|
129
|
+
# Returns or create a new Parse::Client connection for the given connection
|
130
|
+
# name.
|
131
|
+
# @param conn [Symbol] the name of the connection.
|
132
|
+
# @return [Parse::Client]
|
133
|
+
def client(conn = :default)
|
134
|
+
@clients[conn] ||= self.new
|
97
135
|
end
|
98
136
|
|
137
|
+
# Setup the Parse-Stack framework with the appropriate Parse app keys and middleware.
|
138
|
+
# @yield a block for additional configuration
|
139
|
+
# @param opts [Hash] the set of options to configure the :default Parse::Client connection.
|
140
|
+
# @return [Parse::Client]
|
141
|
+
# @see Parse::Client#initialize
|
99
142
|
def setup(opts = {})
|
100
|
-
# If Proc.new is called from inside a method without any arguments of
|
101
|
-
# its own, it will return a new Proc containing the block given to
|
102
|
-
# its surrounding method.
|
103
|
-
# http://mudge.name/2011/01/26/passing-blocks-in-ruby-without-block.html
|
104
143
|
@clients[:default] = self.new(opts, &Proc.new)
|
105
144
|
end
|
106
145
|
|
@@ -128,7 +167,7 @@ module Parse
|
|
128
167
|
opts[:adapter] ||= Faraday.default_adapter
|
129
168
|
opts[:expires] ||= 3
|
130
169
|
if @application_id.nil? || ( @api_key.nil? && @master_key.nil? )
|
131
|
-
raise "Please call Parse.setup(application_id:, api_key:) to setup a
|
170
|
+
raise "Please call Parse.setup(application_id:, api_key:) to setup a client"
|
132
171
|
end
|
133
172
|
@server_url += '/' unless @server_url.ends_with?('/')
|
134
173
|
#Configure Faraday
|
@@ -175,14 +214,12 @@ module Parse
|
|
175
214
|
self
|
176
215
|
end
|
177
216
|
|
178
|
-
|
179
|
-
@application_id
|
180
|
-
end
|
181
|
-
|
217
|
+
# @return [String] the url prefix of the Parse Server url.
|
182
218
|
def url_prefix
|
183
219
|
@conn.url_prefix
|
184
220
|
end
|
185
221
|
|
222
|
+
# Clear the client cache
|
186
223
|
def clear_cache!
|
187
224
|
self.cache.clear if self.cache.present?
|
188
225
|
end
|
@@ -318,7 +355,7 @@ module Parse
|
|
318
355
|
request :put, uri, body: body, headers: headers
|
319
356
|
end
|
320
357
|
|
321
|
-
# shorthand for request(:delete, uri, body: {})
|
358
|
+
# shorthand for request(:delete, uri, body: {}, headers: {})
|
322
359
|
def delete(uri, body = nil, headers = {})
|
323
360
|
request :delete, uri, body: body, headers: headers
|
324
361
|
end
|
data/lib/parse/client/caching.rb
CHANGED
@@ -22,6 +22,8 @@ module Parse
|
|
22
22
|
# * 410 - 'Gone' - removed
|
23
23
|
CACHEABLE_HTTP_CODES = [200, 203, 300, 301, 302]
|
24
24
|
CACHE_CONTROL = 'Cache-Control'
|
25
|
+
CONTENT_LENGTH_KEY = "content-length"
|
26
|
+
CACHE_RESPONSE_HEADER = "X-Cache-Response"
|
25
27
|
CACHE_EXPIRES_DURATION = 'X-Parse-Stack-Cache-Expires'
|
26
28
|
|
27
29
|
class << self
|
@@ -85,8 +87,8 @@ module Parse
|
|
85
87
|
@cache_key = url.to_s
|
86
88
|
|
87
89
|
if @request_headers.key?(SESSION_TOKEN)
|
88
|
-
session_token = @request_headers[SESSION_TOKEN]
|
89
|
-
@cache_key = "#{session_token}
|
90
|
+
@session_token = @request_headers[SESSION_TOKEN]
|
91
|
+
@cache_key = "#{@session_token}:#{@cache_key}" # prefix tokens
|
90
92
|
elsif @request_headers.key?(MASTER_KEY)
|
91
93
|
@cache_key = "mk:#{@cache_key}" # prefix for master key requests
|
92
94
|
end
|
@@ -98,7 +100,7 @@ module Parse
|
|
98
100
|
res_env = @store[@cache_key] # previous cached response
|
99
101
|
body = res_env.respond_to?(:body) ? res_env.body : nil
|
100
102
|
if body.present?
|
101
|
-
response.finish({status: 200, response_headers: {
|
103
|
+
response.finish({status: 200, response_headers: { CACHE_RESPONSE_HEADER => true }, body: body })
|
102
104
|
return response
|
103
105
|
else
|
104
106
|
@store.delete @cache_key
|
@@ -107,7 +109,9 @@ module Parse
|
|
107
109
|
#non GET requets should clear the cache for that same resource path.
|
108
110
|
#ex. a POST to /1/classes/Artist/<objectId> should delete the cache for a GET
|
109
111
|
# request for the same '/1/classes/Artist/<objectId>' where objectId are equivalent
|
110
|
-
@store.delete
|
112
|
+
@store.delete url.to_s # regular
|
113
|
+
@store.delete "mk:#{url.to_s}" # master key cache-key
|
114
|
+
@store.delete @cache_key # final key
|
111
115
|
end
|
112
116
|
rescue Errno::EINVAL, Redis::CannotConnectError => e
|
113
117
|
# if the cache store fails to connect, catch the exception but proceed
|
@@ -122,7 +126,7 @@ module Parse
|
|
122
126
|
# Only cache GET requests with valid HTTP status codes whose content-length
|
123
127
|
# is greater than 20. Otherwise they could be errors, successes and empty result sets.
|
124
128
|
if @enabled && method == :get && CACHEABLE_HTTP_CODES.include?(response_env.status) &&
|
125
|
-
response_env.present? && response_env.response_headers[
|
129
|
+
response_env.present? && response_env.response_headers[CONTENT_LENGTH_KEY].to_i > 20
|
126
130
|
@store.store(@cache_key, response_env, expires: @expires) # ||= response_env.body
|
127
131
|
end # if
|
128
132
|
# do something with the response
|