parse-stack 1.8.0 → 1.8.1
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/.solargraph.yml +23 -0
- data/.travis.yml +0 -1
- data/Gemfile +13 -12
- data/Gemfile.lock +88 -51
- data/README.md +2 -4
- data/Rakefile +14 -14
- data/lib/parse/api/aggregate.rb +4 -7
- data/lib/parse/api/all.rb +1 -1
- data/lib/parse/api/analytics.rb +0 -3
- data/lib/parse/api/batch.rb +3 -5
- data/lib/parse/api/cloud_functions.rb +0 -3
- data/lib/parse/api/config.rb +0 -4
- data/lib/parse/api/files.rb +3 -7
- data/lib/parse/api/hooks.rb +4 -8
- data/lib/parse/api/objects.rb +7 -12
- data/lib/parse/api/push.rb +0 -4
- data/lib/parse/api/schema.rb +2 -6
- data/lib/parse/api/server.rb +4 -7
- data/lib/parse/api/sessions.rb +2 -5
- data/lib/parse/api/users.rb +9 -14
- data/lib/parse/client.rb +54 -50
- data/lib/parse/client/authentication.rb +29 -33
- data/lib/parse/client/batch.rb +8 -11
- data/lib/parse/client/body_builder.rb +19 -20
- data/lib/parse/client/caching.rb +23 -28
- data/lib/parse/client/protocol.rb +11 -12
- data/lib/parse/client/request.rb +4 -6
- data/lib/parse/client/response.rb +5 -7
- data/lib/parse/model/acl.rb +14 -12
- data/lib/parse/model/associations/belongs_to.rb +14 -21
- data/lib/parse/model/associations/collection_proxy.rb +328 -329
- data/lib/parse/model/associations/has_many.rb +18 -25
- data/lib/parse/model/associations/has_one.rb +6 -11
- data/lib/parse/model/associations/pointer_collection_proxy.rb +5 -8
- data/lib/parse/model/associations/relation_collection_proxy.rb +5 -9
- data/lib/parse/model/bytes.rb +8 -10
- data/lib/parse/model/classes/installation.rb +2 -4
- data/lib/parse/model/classes/product.rb +2 -5
- data/lib/parse/model/classes/role.rb +3 -5
- data/lib/parse/model/classes/session.rb +2 -5
- data/lib/parse/model/classes/user.rb +20 -16
- data/lib/parse/model/core/actions.rb +31 -46
- data/lib/parse/model/core/builder.rb +6 -6
- data/lib/parse/model/core/errors.rb +0 -1
- data/lib/parse/model/core/fetching.rb +45 -50
- data/lib/parse/model/core/properties.rb +51 -66
- data/lib/parse/model/core/querying.rb +291 -294
- data/lib/parse/model/core/schema.rb +89 -92
- data/lib/parse/model/date.rb +16 -17
- data/lib/parse/model/file.rb +171 -174
- data/lib/parse/model/geopoint.rb +12 -16
- data/lib/parse/model/model.rb +31 -37
- data/lib/parse/model/object.rb +47 -53
- data/lib/parse/model/pointer.rb +177 -176
- data/lib/parse/model/push.rb +8 -10
- data/lib/parse/model/shortnames.rb +1 -2
- data/lib/parse/model/time_zone.rb +3 -5
- data/lib/parse/query.rb +34 -35
- data/lib/parse/query/constraint.rb +4 -6
- data/lib/parse/query/constraints.rb +21 -29
- data/lib/parse/query/operation.rb +8 -11
- data/lib/parse/query/ordering.rb +45 -49
- data/lib/parse/stack.rb +11 -12
- data/lib/parse/stack/generators/rails.rb +28 -30
- data/lib/parse/stack/generators/templates/model.erb +5 -6
- data/lib/parse/stack/generators/templates/model_installation.rb +0 -1
- data/lib/parse/stack/generators/templates/model_role.rb +0 -1
- data/lib/parse/stack/generators/templates/model_session.rb +0 -1
- data/lib/parse/stack/generators/templates/model_user.rb +0 -1
- data/lib/parse/stack/generators/templates/parse.rb +9 -9
- data/lib/parse/stack/generators/templates/webhooks.rb +1 -2
- data/lib/parse/stack/railtie.rb +2 -4
- data/lib/parse/stack/tasks.rb +70 -86
- data/lib/parse/stack/version.rb +1 -1
- data/lib/parse/webhooks.rb +19 -26
- data/lib/parse/webhooks/payload.rb +26 -28
- data/lib/parse/webhooks/registration.rb +23 -31
- data/parse-stack.gemspec +25 -25
- data/parse-stack.png +0 -0
- metadata +13 -7
- data/.github/parse-ruby-sdk.png +0 -0
data/lib/parse/model/acl.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
4
|
module Parse
|
6
5
|
|
7
6
|
# This class allows you to define custom data types for your model fields. You
|
@@ -33,7 +32,6 @@ module Parse
|
|
33
32
|
def as_json(*args)
|
34
33
|
{}.as_json
|
35
34
|
end
|
36
|
-
|
37
35
|
end
|
38
36
|
|
39
37
|
# An ACL represents the dirty-trackable Parse Permissions object used for
|
@@ -131,6 +129,7 @@ module Parse
|
|
131
129
|
def permissions
|
132
130
|
@permissions ||= {}
|
133
131
|
end
|
132
|
+
|
134
133
|
# The key field value for public permissions.
|
135
134
|
PUBLIC = "*".freeze
|
136
135
|
|
@@ -162,7 +161,7 @@ module Parse
|
|
162
161
|
# @return [ACL::Permission]
|
163
162
|
# @see ACL::Permission
|
164
163
|
def self.permission(read, write = nil)
|
165
|
-
|
164
|
+
ACL::Permission.new(read, write)
|
166
165
|
end
|
167
166
|
# Determines whether two ACLs or a Parse-ACL hash is equivalent to this object.
|
168
167
|
# @example
|
@@ -195,6 +194,7 @@ module Parse
|
|
195
194
|
apply(PUBLIC, read, write)
|
196
195
|
permissions[PUBLIC]
|
197
196
|
end
|
197
|
+
|
198
198
|
alias_method :world, :everyone
|
199
199
|
|
200
200
|
# Calls `acl_will_change!` on the delegate when the permissions have changed.
|
@@ -236,7 +236,7 @@ module Parse
|
|
236
236
|
# @return [Hash] the current set of permissions.
|
237
237
|
# @see #apply_role
|
238
238
|
def apply(id, read = nil, write = nil)
|
239
|
-
return apply_role(id,read,write) if id.is_a?(Parse::Role)
|
239
|
+
return apply_role(id, read, write) if id.is_a?(Parse::Role)
|
240
240
|
id = id.id if id.is_a?(Parse::Pointer)
|
241
241
|
unless id.present?
|
242
242
|
raise ArgumentError, "Invalid argument applying ACLs: must be either objectId, role or :public"
|
@@ -254,7 +254,8 @@ module Parse
|
|
254
254
|
end
|
255
255
|
|
256
256
|
permissions
|
257
|
-
end;
|
257
|
+
end;
|
258
|
+
alias_method :add, :apply
|
258
259
|
|
259
260
|
# Apply a {Parse::Role} to this ACL.
|
260
261
|
# @overload apply_role(role, read = nil, write = nil)
|
@@ -268,7 +269,8 @@ module Parse
|
|
268
269
|
def apply_role(name, read = nil, write = nil)
|
269
270
|
name = name.name if name.is_a?(Parse::Role)
|
270
271
|
apply("role:#{name}", read, write)
|
271
|
-
end;
|
272
|
+
end;
|
273
|
+
alias_method :add_role, :apply_role
|
272
274
|
|
273
275
|
# Used for object conversion when formatting the input/output value in
|
274
276
|
# Parse::Object properties
|
@@ -286,7 +288,7 @@ module Parse
|
|
286
288
|
# all privileges
|
287
289
|
# @return [Hash]
|
288
290
|
def attributes
|
289
|
-
permissions.select {|k,v| v.present? }.as_json
|
291
|
+
permissions.select { |k, v| v.present? }.as_json
|
290
292
|
end
|
291
293
|
|
292
294
|
# @!visibility private
|
@@ -294,8 +296,8 @@ module Parse
|
|
294
296
|
return unless h.is_a?(Hash)
|
295
297
|
will_change!
|
296
298
|
@permissions ||= {}
|
297
|
-
h.each do |k,v|
|
298
|
-
apply(k,v)
|
299
|
+
h.each do |k, v|
|
300
|
+
apply(k, v)
|
299
301
|
end
|
300
302
|
end
|
301
303
|
|
@@ -306,7 +308,7 @@ module Parse
|
|
306
308
|
|
307
309
|
# @return [Hash]
|
308
310
|
def as_json(*args)
|
309
|
-
permissions.select {|k,v| v.present? }.as_json
|
311
|
+
permissions.select { |k, v| v.present? }.as_json
|
310
312
|
end
|
311
313
|
|
312
314
|
# @return [Boolean] true if there are any permissions.
|
@@ -330,7 +332,8 @@ module Parse
|
|
330
332
|
def master_key_only!
|
331
333
|
will_change!
|
332
334
|
@permissions = {}
|
333
|
-
end;
|
335
|
+
end;
|
336
|
+
alias_method :clear!, :master_key_only!
|
334
337
|
|
335
338
|
# Grants read permission on all existing users and roles attached to this object.
|
336
339
|
# @example
|
@@ -530,7 +533,6 @@ module Parse
|
|
530
533
|
def no_write!
|
531
534
|
@write = false
|
532
535
|
end
|
533
|
-
|
534
536
|
end
|
535
537
|
end
|
536
538
|
end
|
@@ -1,11 +1,10 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require_relative
|
5
|
-
require_relative
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
-
|
4
|
+
require_relative "../pointer"
|
5
|
+
require_relative "collection_proxy"
|
6
|
+
require_relative "pointer_collection_proxy"
|
7
|
+
require_relative "relation_collection_proxy"
|
9
8
|
|
10
9
|
module Parse
|
11
10
|
# Defines all the types of Parse object associations.
|
@@ -120,7 +119,7 @@ module Parse
|
|
120
119
|
|
121
120
|
# These items are added as attributes with the special data type of :pointer
|
122
121
|
def belongs_to(key, opts = {})
|
123
|
-
opts = {as: key, field: key.to_s.camelize(:lower), required: false}.merge(opts)
|
122
|
+
opts = { as: key, field: key.to_s.camelize(:lower), required: false }.merge(opts)
|
124
123
|
klassName = opts[:as].to_parse_class
|
125
124
|
parse_field = opts[:field].to_sym
|
126
125
|
|
@@ -138,13 +137,13 @@ module Parse
|
|
138
137
|
end
|
139
138
|
# store this attribute in the attributes hash with the proper remote column name.
|
140
139
|
# we know the type is pointer.
|
141
|
-
self.attributes.merge!(
|
140
|
+
self.attributes.merge!(parse_field => :pointer)
|
142
141
|
# Add them to our list of pointer references
|
143
|
-
self.references.merge!(
|
142
|
+
self.references.merge!(parse_field => klassName)
|
144
143
|
# Add them to the list of fields in our class model
|
145
|
-
self.fields.merge!(
|
144
|
+
self.fields.merge!(key => :pointer, parse_field => :pointer)
|
146
145
|
# Mapping between local attribute name and the remote column name
|
147
|
-
self.field_map.merge!(
|
146
|
+
self.field_map.merge!(key => parse_field)
|
148
147
|
|
149
148
|
# used for dirty tracking
|
150
149
|
define_attribute_methods key
|
@@ -154,7 +153,6 @@ module Parse
|
|
154
153
|
|
155
154
|
# We generate the getter method
|
156
155
|
define_method(key) do
|
157
|
-
|
158
156
|
val = instance_variable_get ivar
|
159
157
|
# We provide autofetch functionality. If the value is nil and the
|
160
158
|
# current Parse::Object is a pointer, then let's auto fetch it
|
@@ -166,8 +164,8 @@ module Parse
|
|
166
164
|
# if for some reason we retrieved either from store or fetching a
|
167
165
|
# hash, lets try to buid a Pointer of that type.
|
168
166
|
|
169
|
-
if val.is_a?(Hash) && (
|
170
|
-
val = Parse::Object.build val, (
|
167
|
+
if val.is_a?(Hash) && (val["__type"] == "Pointer" || val["__type"] == "Object")
|
168
|
+
val = Parse::Object.build val, (val[Parse::Model::KEY_CLASS_NAME] || klassName)
|
171
169
|
instance_variable_set ivar, val
|
172
170
|
end
|
173
171
|
val
|
@@ -190,12 +188,12 @@ module Parse
|
|
190
188
|
define_method(set_attribute_method) do |val, track = true|
|
191
189
|
if val == Parse::Properties::DELETE_OP
|
192
190
|
val = nil
|
193
|
-
elsif val.is_a?(Hash) && (
|
194
|
-
val = Parse::Object.build val, (
|
191
|
+
elsif val.is_a?(Hash) && (val["__type"] == "Pointer" || val["__type"] == "Object")
|
192
|
+
val = Parse::Object.build val, (val[Parse::Model::KEY_CLASS_NAME] || klassName)
|
195
193
|
end
|
196
194
|
|
197
195
|
if track == true
|
198
|
-
send will_change_method unless val == instance_variable_get(
|
196
|
+
send will_change_method unless val == instance_variable_get(ivar)
|
199
197
|
end
|
200
198
|
|
201
199
|
# Never set an object that is not a Parse::Pointer
|
@@ -204,7 +202,6 @@ module Parse
|
|
204
202
|
else
|
205
203
|
warn "[#{self.class}] Invalid value #{val} set for belongs_to field #{key}"
|
206
204
|
end
|
207
|
-
|
208
205
|
end
|
209
206
|
# don't create method aliases if the fields are the same
|
210
207
|
return if parse_field.to_sym == key.to_sym
|
@@ -216,12 +213,8 @@ module Parse
|
|
216
213
|
elsif parse_field.to_sym != :objectId
|
217
214
|
warn "Alias belongs_to method #{self}##{parse_field} already defined."
|
218
215
|
end
|
219
|
-
|
220
216
|
end
|
221
|
-
|
222
217
|
end # ClassMethod
|
223
|
-
|
224
218
|
end #BelongsTo
|
225
219
|
end #Associations
|
226
|
-
|
227
220
|
end
|
@@ -1,379 +1,378 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require_relative
|
9
|
-
|
4
|
+
require "active_model"
|
5
|
+
require "active_support"
|
6
|
+
require "active_support/inflector"
|
7
|
+
require "active_support/core_ext/object"
|
8
|
+
require_relative "../pointer"
|
10
9
|
|
11
10
|
module Parse
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
11
|
+
# We use a delegate pattern to send notifications to the parent whenever the content of the internal array changes.
|
12
|
+
# The main requirement to using the proxy is to provide the list of initial items if any,
|
13
|
+
# the owner to be notified and the name of the attribute 'key'. With that, anytime the array
|
14
|
+
# will change, we will notify the delegate by sending :'key'_will_change! . The proxy can also
|
15
|
+
# be lazy when fetching the contents of the collection. Whenever the collection is accessed and
|
16
|
+
# the list is in a "not loaded" state (empty and loaded == false), we will send :'key_fetch!' to the delegate in order to
|
17
|
+
# populate the collection.
|
18
|
+
|
19
|
+
# A CollectionProxy is a special type of array wrapper that notifies a delegate
|
20
|
+
# object about changes to the array in order to perform dirty tracking. This is
|
21
|
+
# used for all Array properties in Parse::Objects. Subclasses of {CollectionProxy} are
|
22
|
+
# also available for supporting different association types such as an array of Parse pointers
|
23
|
+
# and Parse relations.
|
24
|
+
# @see PointerCollectionProxy
|
25
|
+
# @see RelationCollectionProxy
|
26
|
+
class CollectionProxy
|
27
|
+
include ::ActiveModel::Model
|
28
|
+
include ::ActiveModel::Dirty
|
29
|
+
include ::Enumerable
|
30
|
+
|
31
|
+
# @!attribute [r] delegate
|
32
|
+
# The object to be notified of changes to the collection.
|
33
|
+
# @return [Object]
|
34
|
+
|
35
|
+
# @!attribute [rw] loaded
|
36
|
+
# @return [Boolean] true/false whether the collection has been loaded.
|
37
|
+
|
38
|
+
# @!attribute [r] parse_class
|
39
|
+
# For some subclasses, this helps typecast the items in the collection.
|
40
|
+
# @return [String]
|
41
|
+
|
42
|
+
# @!attribute [r] key
|
43
|
+
# the name of the property key to use when sending notifications for _will_change! and _fetch!
|
44
|
+
# @return [String]
|
45
|
+
|
46
|
+
attr_accessor :collection, :delegate, :loaded, :parse_class
|
47
|
+
attr_reader :delegate, :key
|
48
|
+
|
49
|
+
# This is to use dirty tracking within the proxy
|
50
|
+
define_attribute_methods :collection
|
51
|
+
|
52
|
+
# Create a new CollectionProxy instance.
|
53
|
+
# @param collection [Array] the initial items to add to the collection.
|
54
|
+
# @param delegate [Object] the owner of the object that will receive the notifications.
|
55
|
+
# @param key [Symbol] the name of the key to use when sending notifications for _will_change! and _fetch!
|
56
|
+
# @param parse_class [String] (Optional) the Parse class type are the items of the collection.
|
57
|
+
# This is used to typecast the objects in the array to a particular Parse Object type.
|
25
58
|
# @see PointerCollectionProxy
|
26
59
|
# @see RelationCollectionProxy
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
# @return [Object]
|
35
|
-
|
36
|
-
# @!attribute [rw] loaded
|
37
|
-
# @return [Boolean] true/false whether the collection has been loaded.
|
38
|
-
|
39
|
-
# @!attribute [r] parse_class
|
40
|
-
# For some subclasses, this helps typecast the items in the collection.
|
41
|
-
# @return [String]
|
42
|
-
|
43
|
-
# @!attribute [r] key
|
44
|
-
# the name of the property key to use when sending notifications for _will_change! and _fetch!
|
45
|
-
# @return [String]
|
46
|
-
|
47
|
-
attr_accessor :collection, :delegate, :loaded, :parse_class
|
48
|
-
attr_reader :delegate, :key
|
49
|
-
|
50
|
-
# This is to use dirty tracking within the proxy
|
51
|
-
define_attribute_methods :collection
|
52
|
-
|
53
|
-
# Create a new CollectionProxy instance.
|
54
|
-
# @param collection [Array] the initial items to add to the collection.
|
55
|
-
# @param delegate [Object] the owner of the object that will receive the notifications.
|
56
|
-
# @param key [Symbol] the name of the key to use when sending notifications for _will_change! and _fetch!
|
57
|
-
# @param parse_class [String] (Optional) the Parse class type are the items of the collection.
|
58
|
-
# This is used to typecast the objects in the array to a particular Parse Object type.
|
59
|
-
# @see PointerCollectionProxy
|
60
|
-
# @see RelationCollectionProxy
|
61
|
-
def initialize(collection = nil, delegate: nil, key: nil, parse_class: nil)
|
62
|
-
@delegate = delegate
|
63
|
-
@key = key.to_sym if key.present?
|
64
|
-
@collection = collection.is_a?(Array) ? collection : []
|
65
|
-
@loaded = @collection.count > 0
|
66
|
-
@parse_class = parse_class
|
67
|
-
end
|
68
|
-
|
69
|
-
# true if the collection has been loaded
|
70
|
-
def loaded?
|
71
|
-
@loaded
|
72
|
-
end
|
73
|
-
|
74
|
-
# Forward a method call to the delegate.
|
75
|
-
# @param method [Symbol] the name of the method to forward
|
76
|
-
# @param params [Object] method parameters
|
77
|
-
# @return [Object] the return value from the forwarded method.
|
78
|
-
def forward(method, params = nil)
|
79
|
-
return unless @delegate && @delegate.respond_to?(method)
|
80
|
-
params.nil? ? @delegate.send(method) : @delegate.send(method, params)
|
81
|
-
end
|
82
|
-
|
83
|
-
# Reset the state of the collection.
|
84
|
-
def reset!
|
85
|
-
@loaded = false
|
86
|
-
clear
|
87
|
-
end
|
88
|
-
|
89
|
-
# @return [Boolean] true if two collection proxies have similar items.
|
90
|
-
def ==(other_list)
|
91
|
-
if other_list.is_a?(Array)
|
92
|
-
return @collection == other_list
|
93
|
-
elsif other_list.is_a?(Parse::CollectionProxy)
|
94
|
-
return @collection == other_list.instance_variable_get(:@collection)
|
95
|
-
end
|
96
|
-
end
|
60
|
+
def initialize(collection = nil, delegate: nil, key: nil, parse_class: nil)
|
61
|
+
@delegate = delegate
|
62
|
+
@key = key.to_sym if key.present?
|
63
|
+
@collection = collection.is_a?(Array) ? collection : []
|
64
|
+
@loaded = @collection.count > 0
|
65
|
+
@parse_class = parse_class
|
66
|
+
end
|
97
67
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
68
|
+
# true if the collection has been loaded
|
69
|
+
def loaded?
|
70
|
+
@loaded
|
71
|
+
end
|
103
72
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
73
|
+
# Forward a method call to the delegate.
|
74
|
+
# @param method [Symbol] the name of the method to forward
|
75
|
+
# @param params [Object] method parameters
|
76
|
+
# @return [Object] the return value from the forwarded method.
|
77
|
+
def forward(method, params = nil)
|
78
|
+
return unless @delegate && @delegate.respond_to?(method)
|
79
|
+
params.nil? ? @delegate.send(method) : @delegate.send(method, params)
|
80
|
+
end
|
108
81
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
82
|
+
# Reset the state of the collection.
|
83
|
+
def reset!
|
84
|
+
@loaded = false
|
85
|
+
clear
|
86
|
+
end
|
113
87
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
88
|
+
# @return [Boolean] true if two collection proxies have similar items.
|
89
|
+
def ==(other_list)
|
90
|
+
if other_list.is_a?(Array)
|
91
|
+
return @collection == other_list
|
92
|
+
elsif other_list.is_a?(Parse::CollectionProxy)
|
93
|
+
return @collection == other_list.instance_variable_get(:@collection)
|
119
94
|
end
|
95
|
+
end
|
120
96
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
#
|
125
|
-
|
126
|
-
# @return [Array] contents of the collection.
|
127
|
-
def collection
|
128
|
-
if @collection.empty? && @loaded == false
|
129
|
-
@collection = forward( :"#{@key}_fetch!" ) || @collection || []
|
130
|
-
@loaded = true
|
131
|
-
end
|
132
|
-
|
133
|
-
@collection
|
134
|
-
end
|
97
|
+
# Reload and restore the collection to its original set of items.
|
98
|
+
def reload!
|
99
|
+
reset!
|
100
|
+
collection #force reload
|
101
|
+
end
|
135
102
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
103
|
+
# clear all items in the collection
|
104
|
+
def clear
|
105
|
+
@collection.clear
|
106
|
+
end
|
140
107
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
# @return [Array] the collection.
|
154
|
-
def add_unique(*items)
|
155
|
-
return unless items.count > 0
|
156
|
-
notify_will_change!
|
157
|
-
@collection = collection | items.flatten
|
158
|
-
@collection
|
159
|
-
end; alias_method :push_unique, :add_unique
|
160
|
-
|
161
|
-
# Set Union - Returns a new array by joining two arrays, excluding
|
162
|
-
# any duplicates and preserving the order from the original array.
|
163
|
-
# It compares elements using their hash and eql? methods for efficiency.
|
164
|
-
# See {https://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-hash Array#|}
|
165
|
-
# @example
|
166
|
-
# [ "a", "b", "c" ] | [ "c", "d", "a" ] #=> [ "a", "b", "c", "d" ]
|
167
|
-
# @param items [Array] items to uniquely add
|
168
|
-
# @see #add_unique
|
169
|
-
# @return [Array] array with unique items
|
170
|
-
def |(items)
|
171
|
-
collection | [items].flatten
|
172
|
-
end
|
108
|
+
# @return [Array]
|
109
|
+
def to_a
|
110
|
+
collection.to_a
|
111
|
+
end;
|
112
|
+
alias_method :to_ary, :to_a
|
113
|
+
|
114
|
+
# Set the internal collection of items *without* dirty tracking or
|
115
|
+
# change notifications.
|
116
|
+
# @return [Array] the collection
|
117
|
+
def set_collection!(list)
|
118
|
+
@collection = list
|
119
|
+
end
|
173
120
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
def &(other_ary)
|
185
|
-
collection & [other_ary].flatten
|
121
|
+
# @!attribute [rw] collection
|
122
|
+
# The internal backing store of the collection containing the content. This value is lazily
|
123
|
+
# loaded for some subclasses.
|
124
|
+
# @note If you modify this directly, it is highly recommended that you
|
125
|
+
# call {CollectionProxy#notify_will_change!} to notify the dirty tracking system.
|
126
|
+
# @return [Array] contents of the collection.
|
127
|
+
def collection
|
128
|
+
if @collection.empty? && @loaded == false
|
129
|
+
@collection = forward(:"#{@key}_fetch!") || @collection || []
|
130
|
+
@loaded = true
|
186
131
|
end
|
187
132
|
|
188
|
-
|
189
|
-
|
190
|
-
# items that also appear in other_ary. The order is preserved from the
|
191
|
-
# original array.
|
192
|
-
# @example
|
193
|
-
# [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
|
194
|
-
# @param other_ary [Array]
|
195
|
-
# @return [Array] delta array
|
196
|
-
def -(other_ary)
|
197
|
-
collection - [other_ary].flatten
|
198
|
-
end
|
133
|
+
@collection
|
134
|
+
end
|
199
135
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
# [ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ]
|
205
|
-
# @param other_ary [Array]
|
206
|
-
# @return [Array] concatenated array
|
207
|
-
def +(other_ary)
|
208
|
-
collection + [other_ary].flatten.to_a
|
209
|
-
end
|
136
|
+
def collection=(c)
|
137
|
+
notify_will_change!
|
138
|
+
@collection = c
|
139
|
+
end
|
210
140
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
141
|
+
# Add items to the collection
|
142
|
+
# @param items [Array] items to add
|
143
|
+
def add(*items)
|
144
|
+
notify_will_change! if items.count > 0
|
145
|
+
items.each do |item|
|
146
|
+
collection.push item
|
147
|
+
end
|
148
|
+
@collection
|
149
|
+
end;
|
150
|
+
alias_method :push, :add
|
151
|
+
|
152
|
+
# Add items to the collection if they don't already exist
|
153
|
+
# @param items [Array] items to uniquely add
|
154
|
+
# @return [Array] the collection.
|
155
|
+
def add_unique(*items)
|
156
|
+
return unless items.count > 0
|
157
|
+
notify_will_change!
|
158
|
+
@collection = collection | items.flatten
|
159
|
+
@collection
|
160
|
+
end;
|
161
|
+
alias_method :push_unique, :add_unique
|
162
|
+
|
163
|
+
# Set Union - Returns a new array by joining two arrays, excluding
|
164
|
+
# any duplicates and preserving the order from the original array.
|
165
|
+
# It compares elements using their hash and eql? methods for efficiency.
|
166
|
+
# See {https://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-hash Array#|}
|
167
|
+
# @example
|
168
|
+
# [ "a", "b", "c" ] | [ "c", "d", "a" ] #=> [ "a", "b", "c", "d" ]
|
169
|
+
# @param items [Array] items to uniquely add
|
170
|
+
# @see #add_unique
|
171
|
+
# @return [Array] array with unique items
|
172
|
+
def |(items)
|
173
|
+
collection | [items].flatten
|
174
|
+
end
|
216
175
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
# @see #add_unique!
|
231
|
-
def add!(*items)
|
232
|
-
return false unless @delegate.respond_to?(:op_add!)
|
233
|
-
@delegate.send :op_add!, @key, items.flatten
|
234
|
-
reset!
|
235
|
-
end
|
176
|
+
# Set Intersection - Returns a new array containing unique elements common
|
177
|
+
# to the two arrays. The order is preserved from the original array.
|
178
|
+
#
|
179
|
+
# It compares elements using their hash and eql? methods for efficiency.
|
180
|
+
# See {https://ruby-doc.org/core-2.4.1/Array.html#method-i-26 Array#&}
|
181
|
+
# @example
|
182
|
+
# [ 1, 1, 3, 5 ] & [ 3, 2, 1 ] #=> [ 1, 3 ]
|
183
|
+
# [ 'a', 'b', 'b', 'z' ] & [ 'a', 'b', 'c' ] #=> [ 'a', 'b' ]
|
184
|
+
# @param other_ary [Array]
|
185
|
+
# @return [Array] intersection array
|
186
|
+
def &(other_ary)
|
187
|
+
collection & [other_ary].flatten
|
188
|
+
end
|
236
189
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
190
|
+
# Alias {https://ruby-doc.org/core-2.4.1/Array.html#method-i-2D Array Difference}.
|
191
|
+
# Returns a new array that is a copy of the original array, removing any
|
192
|
+
# items that also appear in other_ary. The order is preserved from the
|
193
|
+
# original array.
|
194
|
+
# @example
|
195
|
+
# [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
|
196
|
+
# @param other_ary [Array]
|
197
|
+
# @return [Array] delta array
|
198
|
+
def -(other_ary)
|
199
|
+
collection - [other_ary].flatten
|
200
|
+
end
|
246
201
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
202
|
+
# Alias {https://ruby-doc.org/core-2.4.1/Array.html#method-i-2B Array Concatenation}.
|
203
|
+
# Returns a new array built by concatenating the two arrays together to
|
204
|
+
# produce a third array.
|
205
|
+
# @example
|
206
|
+
# [ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ]
|
207
|
+
# @param other_ary [Array]
|
208
|
+
# @return [Array] concatenated array
|
209
|
+
def +(other_ary)
|
210
|
+
collection + [other_ary].flatten.to_a
|
211
|
+
end
|
255
212
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
collection_will_change!
|
262
|
-
@collection.clear
|
263
|
-
reset!
|
264
|
-
end
|
213
|
+
# Alias {https://ruby-doc.org/core-2.4.1/Array.html#method-i-flatten Array flattening}.
|
214
|
+
# @return [Array] a flattened one-dimensional array
|
215
|
+
def flatten
|
216
|
+
collection.flatten
|
217
|
+
end
|
265
218
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
219
|
+
# Remove items from the collection
|
220
|
+
# @param items [Array] items to remove
|
221
|
+
def remove(*items)
|
222
|
+
notify_will_change! if items.count > 0
|
223
|
+
items.each do |item|
|
224
|
+
collection.delete item
|
225
|
+
end
|
226
|
+
@collection
|
227
|
+
end;
|
228
|
+
alias_method :delete, :remove
|
229
|
+
|
230
|
+
# Atomically adds all items from the array.
|
231
|
+
# This request is sent directly to the Parse backend.
|
232
|
+
# @param items [Array] items to uniquely add
|
233
|
+
# @see #add_unique!
|
234
|
+
def add!(*items)
|
235
|
+
return false unless @delegate.respond_to?(:op_add!)
|
236
|
+
@delegate.send :op_add!, @key, items.flatten
|
237
|
+
reset!
|
238
|
+
end
|
270
239
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
240
|
+
# Atomically adds all items from the array that are not already part of the collection.
|
241
|
+
# This request is sent directly to the Parse backend.
|
242
|
+
# @param items [Array] items to uniquely add
|
243
|
+
# @see #add!
|
244
|
+
def add_unique!(*items)
|
245
|
+
return false unless @delegate.respond_to?(:op_add_unique!)
|
246
|
+
@delegate.send :op_add_unique!, @key, items.flatten
|
247
|
+
reset!
|
248
|
+
end
|
275
249
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
250
|
+
# Atomically deletes all items from the array. This request is sent
|
251
|
+
# directly to the Parse backend.
|
252
|
+
# @param items [Array] items to remove
|
253
|
+
def remove!(*items)
|
254
|
+
return false unless @delegate.respond_to?(:op_remove!)
|
255
|
+
@delegate.send :op_remove!, @key, items.flatten
|
256
|
+
reset!
|
257
|
+
end
|
280
258
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
259
|
+
# Atomically deletes all items in the array, and marks the field as `undefined` directly
|
260
|
+
# with the Parse server. This request is sent directly to the Parse backend.
|
261
|
+
def destroy!
|
262
|
+
return false unless @delegate.respond_to?(:op_destroy!)
|
263
|
+
@delegate.send :op_destroy!, @key
|
264
|
+
collection_will_change!
|
265
|
+
@collection.clear
|
266
|
+
reset!
|
267
|
+
end
|
286
268
|
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
269
|
+
# Locally restores previous attributes (not from the persistent store)
|
270
|
+
def rollback!
|
271
|
+
restore_attributes
|
272
|
+
end
|
291
273
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
end
|
274
|
+
# clears all dirty tracked information.
|
275
|
+
def clear_changes!
|
276
|
+
clear_changes_information
|
277
|
+
end
|
297
278
|
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
279
|
+
# mark that collection changes where applied, which clears dirty tracking.
|
280
|
+
def changes_applied!
|
281
|
+
changes_applied
|
282
|
+
end
|
302
283
|
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
284
|
+
# @param args [Hash] arguments to pass to Array#first.
|
285
|
+
# @return [Object] the first item in the collection
|
286
|
+
def first(*args)
|
287
|
+
collection.first(*args)
|
288
|
+
end
|
307
289
|
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
290
|
+
# @return [Object] the second item in the collection
|
291
|
+
def second
|
292
|
+
collection.second
|
293
|
+
end
|
312
294
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
end
|
319
|
-
end
|
295
|
+
# @param args [Hash] arguments to pass to Array#last.
|
296
|
+
# @return [Object] the last item in the collection
|
297
|
+
def last(*args)
|
298
|
+
collection.last(*args)
|
299
|
+
end
|
320
300
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
end
|
301
|
+
# @return [Integer] number of items in the collection.
|
302
|
+
def count
|
303
|
+
collection.count
|
304
|
+
end
|
326
305
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
end
|
306
|
+
# @return [Hash] a JSON representation
|
307
|
+
def as_json(opts = nil)
|
308
|
+
collection.as_json(opts)
|
309
|
+
end
|
332
310
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
end
|
311
|
+
# true if the collection is empty.
|
312
|
+
def empty?
|
313
|
+
collection.empty?
|
314
|
+
end
|
338
315
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
316
|
+
# Append items to the collection
|
317
|
+
def <<(*list)
|
318
|
+
if list.count > 0
|
319
|
+
notify_will_change!
|
320
|
+
list.flatten.each { |e| collection.push(e) }
|
343
321
|
end
|
322
|
+
end
|
344
323
|
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
324
|
+
# Notifies the delegate that the collection changed.
|
325
|
+
def notify_will_change!
|
326
|
+
collection_will_change!
|
327
|
+
forward "#{@key}_will_change!"
|
328
|
+
end
|
350
329
|
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
end
|
330
|
+
# Alias for Array#each
|
331
|
+
def each
|
332
|
+
return collection.enum_for(:each) unless block_given?
|
333
|
+
collection.each &Proc.new
|
334
|
+
end
|
357
335
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
336
|
+
# Alias for Array#map
|
337
|
+
def map
|
338
|
+
return collection.enum_for(:map) unless block_given?
|
339
|
+
collection.map &Proc.new
|
340
|
+
end
|
362
341
|
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
342
|
+
# Alias for Array#select
|
343
|
+
def select
|
344
|
+
return collection.enum_for(:select) unless block_given?
|
345
|
+
collection.select &Proc.new
|
346
|
+
end
|
368
347
|
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
348
|
+
# Alias for Array#uniq
|
349
|
+
def uniq
|
350
|
+
return collection.uniq(&Proc.new) if block_given?
|
351
|
+
return collection.uniq
|
352
|
+
end
|
374
353
|
|
354
|
+
# Alias for Array#uniq!
|
355
|
+
def uniq!
|
356
|
+
notify_will_change!
|
357
|
+
return collection.uniq!(&Proc.new) if block_given?
|
358
|
+
return collection.uniq!
|
375
359
|
end
|
376
360
|
|
361
|
+
# @!visibility private
|
362
|
+
def inspect
|
363
|
+
"#<#{self.class} changed?=#{changed?} @collection=#{@collection.inspect} >"
|
364
|
+
end
|
377
365
|
|
366
|
+
# Alias to `to_a.parse_objects` from Array#parse_objects
|
367
|
+
# @return [Array<Parse::Object>] an array of Parse Object subclasses representing this collection.
|
368
|
+
def parse_objects
|
369
|
+
collection.to_a.parse_objects
|
370
|
+
end
|
378
371
|
|
372
|
+
# Alias to `to_a.parse_pointers` from Array#parse_pointers
|
373
|
+
# @return [Array<Parse::Pointer>] an array of pointers representing this collection.
|
374
|
+
def parse_pointers
|
375
|
+
collection.to_a.parse_pointers
|
376
|
+
end
|
379
377
|
end
|
378
|
+
end
|