parse-stack 1.5.1 → 1.5.2
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/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
@@ -3,20 +3,60 @@
|
|
3
3
|
|
4
4
|
require_relative 'constraint'
|
5
5
|
|
6
|
-
#
|
6
|
+
# Each constraint type is a subclass of Parse::Constraint
|
7
7
|
# We register each keyword (which is the Parse query operator)
|
8
8
|
# and the local operator we want to use. Each of the registered local
|
9
9
|
# operators are added as methods to the Symbol class.
|
10
10
|
# For more information: https://parse.com/docs/rest/guide#queries
|
11
11
|
# For more information about the query design pattern from DataMapper
|
12
12
|
# that inspired this, see http://datamapper.org/docs/find.html
|
13
|
-
class ParseConstraintError < StandardError; end;
|
14
|
-
module Parse
|
15
13
|
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
module Parse
|
18
|
+
# Error for when there is a problem with the input passed to a constraint.
|
19
|
+
class ConstraintError < StandardError; end;
|
20
|
+
|
21
|
+
# A constraint for matching by a specific objectId value.
|
22
|
+
#
|
23
|
+
# # where this Parse object equals the object in the column `field`.
|
24
|
+
# q.where :field => Parse::Pointer("Field", "someObjectId")
|
25
|
+
# # alias, shorthand when we infer `:field` maps to `Field` parse class.
|
26
|
+
# q.where :field.id => "someObjectId"
|
27
|
+
# # "field":{"__type":"Pointer","className":"Field","objectId":"someObjectId"}}
|
28
|
+
#
|
29
|
+
# class Artist < Parse::Object
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# class Song < Parse::Object
|
33
|
+
# belongs_to :artist
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# artist = Artist.first # get any artist
|
37
|
+
# artist_id = artist.id # ex. artist.id
|
38
|
+
#
|
39
|
+
# # find all songs for this artist object
|
40
|
+
# Song.all :artist => artist
|
41
|
+
# In some cases, you do not have the Parse object, but you have its `objectId`.
|
42
|
+
# You can use the objectId in the query as follows:
|
43
|
+
#
|
44
|
+
# # shorthand if you are using convention. Will infer class `Artist`
|
45
|
+
# Song.all :artist.id => artist_id
|
46
|
+
#
|
47
|
+
# # other approaches, same result
|
48
|
+
# Song.all :artist => Artist.pointer(artist_id)
|
49
|
+
# Song.all :artist => Parse::Pointer.new("Artist", artist_id)
|
50
|
+
#
|
16
51
|
class ObjectIdConstraint < Constraint
|
52
|
+
# @!method id
|
53
|
+
# A registered method on a symbol to create the constraint.
|
54
|
+
# @example
|
55
|
+
# q.where :field.id => "someObjectId"
|
56
|
+
# @return [ObjectIdConstraint]
|
17
57
|
register :id
|
18
58
|
|
19
|
-
|
59
|
+
# @return [Hash] the compiled constraint.
|
20
60
|
def build
|
21
61
|
className = operand.to_parse_class
|
22
62
|
value = formatted_value
|
@@ -27,14 +67,14 @@ module Parse
|
|
27
67
|
end
|
28
68
|
|
29
69
|
unless klass.present? && klass.is_a?(Parse::Object) == false
|
30
|
-
raise
|
70
|
+
raise ConstraintError, "#{self.class}: No Parse class defined for #{operand} as '#{className}'"
|
31
71
|
end
|
32
72
|
|
33
73
|
# allow symbols
|
34
74
|
value = value.to_s if value.is_a?(Symbol)
|
35
75
|
|
36
76
|
unless value.is_a?(String) && value.strip.present?
|
37
|
-
raise
|
77
|
+
raise ConstraintError, "#{self.class}: value must be of string type representing a Parse object id."
|
38
78
|
end
|
39
79
|
value.strip!
|
40
80
|
return { @operation.operand => klass.pointer(value) }
|
@@ -42,67 +82,171 @@ module Parse
|
|
42
82
|
|
43
83
|
end
|
44
84
|
|
85
|
+
# Equivalent to the `$or` Parse query operation. This is useful if you want to
|
86
|
+
# find objects that match several queries. We overload the `|` operator in
|
87
|
+
# order to have a clean syntax for joining these `or` operations.
|
88
|
+
# or_query = query1 | query2 | query3
|
89
|
+
# query = Player.where(:wins.gt => 150) | Player.where(:wins.lt => 5)
|
90
|
+
#
|
91
|
+
# query.or_where :field => value
|
92
|
+
#
|
45
93
|
class CompoundQueryConstraint < Constraint
|
46
94
|
contraint_keyword :$or
|
47
95
|
register :or
|
48
96
|
|
97
|
+
# @return [Hash] the compiled constraint.
|
49
98
|
def build
|
50
99
|
or_clauses = formatted_value
|
51
|
-
|
52
|
-
return { :$or => or_clauses }
|
100
|
+
return { :$or => Array.wrap(or_clauses) }
|
53
101
|
end
|
54
102
|
|
55
103
|
end
|
56
104
|
|
105
|
+
# Equivalent to the `$lte` Parse query operation. The alias `on_or_before` is provided for readability.
|
106
|
+
# q.where :field.lte => value
|
107
|
+
# q.where :field.on_or_before => date
|
108
|
+
#
|
109
|
+
# q.where :created_at.on_or_before => DateTime.now
|
110
|
+
# @see LessThanConstraint
|
57
111
|
class LessThanOrEqualConstraint < Constraint
|
112
|
+
# @!method lte
|
113
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$lte".
|
114
|
+
# @example
|
115
|
+
# q.where :field.lte => value
|
116
|
+
# @return [LessThanOrEqualConstraint]
|
117
|
+
|
118
|
+
# @!method less_than_or_equal
|
119
|
+
# Alias for {lte}
|
120
|
+
# @return [LessThanOrEqualConstraint]
|
121
|
+
|
122
|
+
# @!method on_or_before
|
123
|
+
# Alias for {lte} that provides better readability when constraining dates.
|
124
|
+
# @return [LessThanOrEqualConstraint]
|
58
125
|
contraint_keyword :$lte
|
59
126
|
register :lte
|
60
127
|
register :less_than_or_equal
|
61
128
|
register :on_or_before
|
62
129
|
end
|
63
130
|
|
131
|
+
# Equivalent to the `$lt` Parse query operation. The alias `before` is provided for readability.
|
132
|
+
# q.where :field.lt => value
|
133
|
+
# q.where :field.before => date
|
134
|
+
#
|
135
|
+
# q.where :created_at.before => DateTime.now
|
64
136
|
class LessThanConstraint < Constraint
|
137
|
+
# @!method lt
|
138
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$lt".
|
139
|
+
# @example
|
140
|
+
# q.where :field.lt => value
|
141
|
+
# @return [LessThanConstraint]
|
142
|
+
|
143
|
+
# @!method less_than
|
144
|
+
# # Alias for {lt}.
|
145
|
+
# @return [LessThanConstraint]
|
146
|
+
|
147
|
+
# @!method before
|
148
|
+
# Alias for {lt} that provides better readability when constraining dates.
|
149
|
+
# @return [LessThanConstraint]
|
65
150
|
contraint_keyword :$lt
|
66
151
|
register :lt
|
67
152
|
register :less_than
|
68
153
|
register :before
|
69
154
|
end
|
70
|
-
|
155
|
+
# Equivalent to the `$gt` Parse query operation. The alias `after` is provided for readability.
|
156
|
+
# q.where :field.gt => value
|
157
|
+
# q.where :field.after => date
|
158
|
+
#
|
159
|
+
# q.where :created_at.after => DateTime.now
|
160
|
+
# @see GreaterThanOrEqualConstraint
|
71
161
|
class GreaterThanConstraint < Constraint
|
162
|
+
# @!method gt
|
163
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$gt".
|
164
|
+
# @example
|
165
|
+
# q.where :field.gt => value
|
166
|
+
# @return [GreaterThanConstraint]
|
167
|
+
|
168
|
+
# @!method greater_than
|
169
|
+
# # Alias for {gt}.
|
170
|
+
# @return [GreaterThanConstraint]
|
171
|
+
|
172
|
+
# @!method after
|
173
|
+
# Alias for {gt} that provides better readability when constraining dates.
|
174
|
+
# @return [GreaterThanConstraint]
|
72
175
|
contraint_keyword :$gt
|
73
176
|
register :gt
|
74
177
|
register :greater_than
|
75
178
|
register :after
|
76
179
|
end
|
77
180
|
|
181
|
+
# Equivalent to the `$gte` Parse query operation. The alias `on_or_after` is provided for readability.
|
182
|
+
# q.where :field.gte => value
|
183
|
+
# q.where :field.on_or_after => date
|
184
|
+
#
|
185
|
+
# q.where :created_at.on_or_after => DateTime.now
|
186
|
+
# @see GreaterThanConstraint
|
78
187
|
class GreaterThanOrEqualConstraint < Constraint
|
188
|
+
# @!method gte
|
189
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$gte".
|
190
|
+
# @example
|
191
|
+
# q.where :field.gte => value
|
192
|
+
# @return [GreaterThanOrEqualConstraint]
|
193
|
+
|
194
|
+
# @!method greater_than_or_equal
|
195
|
+
# # Alias for {gte}.
|
196
|
+
# @return [GreaterThanOrEqualConstraint]
|
197
|
+
|
198
|
+
# @!method on_or_after
|
199
|
+
# Alias for {gte} that provides better readability when constraining dates.
|
200
|
+
# @return [GreaterThanOrEqualConstraint]
|
79
201
|
contraint_keyword :$gte
|
80
202
|
register :gte
|
81
203
|
register :greater_than_or_equal
|
82
204
|
register :on_or_after
|
83
205
|
end
|
84
206
|
|
207
|
+
# Equivalent to the `$ne` Parse query operation. Where a particular field is not equal to value.
|
208
|
+
# q.where :field.not => value
|
85
209
|
class NotEqualConstraint < Constraint
|
210
|
+
# @!method not
|
211
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$ne".
|
212
|
+
# @example
|
213
|
+
# q.where :field.not => value
|
214
|
+
# @return [NotEqualConstraint]
|
215
|
+
|
216
|
+
# @!method ne
|
217
|
+
# # Alias for {not}.
|
218
|
+
# @return [NotEqualConstraint]
|
86
219
|
contraint_keyword :$ne
|
87
220
|
register :not
|
88
221
|
register :ne
|
89
222
|
end
|
90
223
|
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
#
|
224
|
+
# Provides a mechanism using the equality operator to check for `(undefined)` values.
|
225
|
+
# Nullabiliity constraint maps the `$exists` Parse clause to enable checking for
|
226
|
+
# existance in a column when performing geoqueries due to a Parse limitation.
|
227
|
+
# q.where :field.null => false
|
228
|
+
# @note Parse currently has a bug that if you select items near a location
|
229
|
+
# and want to make sure a different column has a value, you need to
|
230
|
+
# search where the column does not contanin a null/undefined value.
|
231
|
+
# Therefore we override the build method to change the operation to a
|
232
|
+
# {NotEqualConstraint}.
|
233
|
+
# @see ExistsConstraint
|
97
234
|
class NullabilityConstraint < Constraint
|
235
|
+
# @!method null
|
236
|
+
# A registered method on a symbol to create the constraint.
|
237
|
+
# @example
|
238
|
+
# q.where :field.null => true
|
239
|
+
# @return [NullabilityConstraint]
|
98
240
|
contraint_keyword :$exists
|
99
241
|
register :null
|
242
|
+
|
243
|
+
# @return [Hash] the compiled constraint.
|
100
244
|
def build
|
101
245
|
# if nullability is equal true, then $exists should be set to false
|
102
246
|
|
103
247
|
value = formatted_value
|
104
248
|
unless value == true || value == false
|
105
|
-
raise
|
249
|
+
raise ConstraintError, "#{self.class}: Non-Boolean value passed, it must be either `true` or `false`"
|
106
250
|
end
|
107
251
|
|
108
252
|
if value == true
|
@@ -116,27 +260,58 @@ module Parse
|
|
116
260
|
end
|
117
261
|
end
|
118
262
|
|
263
|
+
# Equivalent to the `#exists` Parse query operation. Checks whether a value is
|
264
|
+
# set for key. The difference between this operation and the nullability check
|
265
|
+
# is when using compound queries with location.
|
266
|
+
# q.where :field.exists => true
|
267
|
+
#
|
268
|
+
# @see NullabilityConstraint
|
119
269
|
class ExistsConstraint < Constraint
|
270
|
+
# @!method exists
|
271
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$exists".
|
272
|
+
# @example
|
273
|
+
# q.where :field.exists => true
|
274
|
+
# @return [ExistsConstraint]
|
120
275
|
contraint_keyword :$exists
|
121
276
|
register :exists
|
277
|
+
|
278
|
+
# @return [Hash] the compiled constraint.
|
122
279
|
def build
|
123
280
|
# if nullability is equal true, then $exists should be set to false
|
124
281
|
value = formatted_value
|
125
282
|
|
126
283
|
unless value == true || value == false
|
127
|
-
raise
|
284
|
+
raise ConstraintError, "#{self.class}: Non-Boolean value passed, it must be either `true` or `false`"
|
128
285
|
end
|
129
286
|
|
130
287
|
return { @operation.operand => { key => value } }
|
131
288
|
end
|
132
289
|
end
|
133
290
|
|
134
|
-
#
|
291
|
+
# Equivalent to the `$in` Parse query operation. Checks whether the value in the
|
292
|
+
# column field is contained in the set of values in the target array. If the
|
293
|
+
# field is an array data type, it checks whether at least one value in the
|
294
|
+
# field array is contained in the set of values in the target array.
|
295
|
+
# q.where :field.in => array
|
296
|
+
# q.where :score.in => [1,3,5,7,9]
|
297
|
+
#
|
298
|
+
# @see ContainsAllConstraint
|
299
|
+
# @see NotContainedInConstraint
|
135
300
|
class ContainedInConstraint < Constraint
|
301
|
+
# @!method in
|
302
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$in".
|
303
|
+
# @example
|
304
|
+
# q.where :field.in => array
|
305
|
+
# @return [ContainedInConstraint]
|
306
|
+
|
307
|
+
# @!method contained_in
|
308
|
+
# Alias for {in}
|
309
|
+
# @return [ContainedInConstraint]
|
136
310
|
contraint_keyword :$in
|
137
311
|
register :in
|
138
312
|
register :contained_in
|
139
313
|
|
314
|
+
# @return [Hash] the compiled constraint.
|
140
315
|
def build
|
141
316
|
val = formatted_value
|
142
317
|
val = [val].compact unless val.is_a?(Array)
|
@@ -145,12 +320,36 @@ module Parse
|
|
145
320
|
|
146
321
|
end
|
147
322
|
|
323
|
+
# Equivalent to the `$nin` Parse query operation. Checks whether the value in
|
324
|
+
# the column field is *not* contained in the set of values in the target
|
325
|
+
# array. If the field is an array data type, it checks whether at least one
|
326
|
+
# value in the field array is *not* contained in the set of values in the
|
327
|
+
# target array.
|
328
|
+
#
|
329
|
+
# q.where :field.not_in => array
|
330
|
+
# q.where :player_name.not_in => ["Jonathan", "Dario", "Shawn"]
|
331
|
+
# @see ContainedInConstraint
|
332
|
+
# @see ContainsAllConstraint
|
148
333
|
class NotContainedInConstraint < Constraint
|
334
|
+
# @!method not_in
|
335
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$nin".
|
336
|
+
# @example
|
337
|
+
# q.where :field.not_in => array
|
338
|
+
# @return [NotContainedInConstraint]
|
339
|
+
|
340
|
+
# @!method nin
|
341
|
+
# Alias for {not_in}
|
342
|
+
# @return [NotContainedInConstraint]
|
343
|
+
|
344
|
+
# @!method not_contained_in
|
345
|
+
# Alias for {not_in}
|
346
|
+
# @return [NotContainedInConstraint]
|
149
347
|
contraint_keyword :$nin
|
150
348
|
register :not_in
|
151
349
|
register :nin
|
152
350
|
register :not_contained_in
|
153
351
|
|
352
|
+
# @return [Hash] the compiled constraint.
|
154
353
|
def build
|
155
354
|
val = formatted_value
|
156
355
|
val = [val].compact unless val.is_a?(Array)
|
@@ -159,12 +358,30 @@ module Parse
|
|
159
358
|
|
160
359
|
end
|
161
360
|
|
162
|
-
#
|
361
|
+
# Equivalent to the $all Parse query operation. Checks whether the value in
|
362
|
+
# the column field contains all of the given values provided in the array. Note
|
363
|
+
# that the field column should be of type {Array} in your Parse class.
|
364
|
+
#
|
365
|
+
# q.where :field.all => array
|
366
|
+
# q.where :array_key.all => [2,3,4]
|
367
|
+
#
|
368
|
+
# @see ContainedInConstraint
|
369
|
+
# @see NotContainedInConstraint
|
163
370
|
class ContainsAllConstraint < Constraint
|
371
|
+
# @!method all
|
372
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$all".
|
373
|
+
# @example
|
374
|
+
# q.where :field.all => array
|
375
|
+
# @return [ContainsAllConstraint]
|
376
|
+
|
377
|
+
# @!method contains_all
|
378
|
+
# Alias for {all}
|
379
|
+
# @return [ContainsAllConstraint]
|
164
380
|
contraint_keyword :$all
|
165
381
|
register :all
|
166
382
|
register :contains_all
|
167
383
|
|
384
|
+
# @return [Hash] the compiled constraint.
|
168
385
|
def build
|
169
386
|
val = formatted_value
|
170
387
|
val = [val].compact unless val.is_a?(Array)
|
@@ -172,11 +389,26 @@ module Parse
|
|
172
389
|
end
|
173
390
|
end
|
174
391
|
|
392
|
+
# Equivalent to the `$select` Parse query operation. This matches a value for a
|
393
|
+
# key in the result of a different query.
|
394
|
+
# q.where :field.select => { key: "field", query: query }
|
395
|
+
#
|
396
|
+
# # example
|
397
|
+
# value = { key: 'city', query: Artist.where(:fan_count.gt => 50) }
|
398
|
+
# q.where :hometown.select => value
|
399
|
+
#
|
400
|
+
# # if the local field is the same name as the foreign table field, you can omit hash
|
401
|
+
# # assumes key: 'city'
|
402
|
+
# q.where :city.select => Artist.where(:fan_count.gt => 50)
|
403
|
+
#
|
175
404
|
class SelectionConstraint < Constraint
|
176
|
-
#
|
405
|
+
# @!method select
|
406
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$select".
|
407
|
+
# @return [SelectionConstraint]
|
177
408
|
contraint_keyword :$select
|
178
409
|
register :select
|
179
410
|
|
411
|
+
# @return [Hash] the compiled constraint.
|
180
412
|
def build
|
181
413
|
|
182
414
|
# if it's a hash, then it should be {:key=>"objectId", :query=>[]}
|
@@ -187,24 +419,48 @@ module Parse
|
|
187
419
|
remote_field_name = res[:key] || remote_field_name
|
188
420
|
query = res[:query]
|
189
421
|
unless query.is_a?(Parse::Query)
|
190
|
-
raise
|
422
|
+
raise ConstraintError, "Invalid Parse::Query object provided in :query field of value: #{@operation.operand}.#{$dontSelect} => #{@value}"
|
191
423
|
end
|
192
424
|
query = query.compile(encode: false, includeClassName: true)
|
193
425
|
elsif @value.is_a?(Parse::Query)
|
194
426
|
# if its a query, then assume dontSelect key is the same name as operand.
|
195
427
|
query = @value.compile(encode: false, includeClassName: true)
|
196
428
|
else
|
197
|
-
raise
|
429
|
+
raise ConstraintError, "Invalid `:select` query constraint. It should follow the format: :field.select => { key: 'key', query: '<Parse::Query>' }"
|
198
430
|
end
|
199
431
|
{ @operation.operand => { :$select => { key: remote_field_name, query: query } } }
|
200
432
|
end
|
201
433
|
end
|
202
434
|
|
435
|
+
# Equivalent to the `$dontSelect` Parse query operation. Requires that a field's
|
436
|
+
# value not match a value for a key in the result of a different query.
|
437
|
+
#
|
438
|
+
# q.where :field.reject => { key: :other_field, query: query }
|
439
|
+
#
|
440
|
+
# value = { key: 'city', query: Artist.where(:fan_count.gt => 50) }
|
441
|
+
# q.where :hometown.reject => value
|
442
|
+
#
|
443
|
+
# # if the local field is the same name as the foreign table field, you can omit hash
|
444
|
+
# # assumes key: 'city'
|
445
|
+
# q.where :city.reject => Artist.where(:fan_count.gt => 50)
|
446
|
+
#
|
447
|
+
# @see SelectionConstraint
|
203
448
|
class RejectionConstraint < Constraint
|
204
|
-
|
449
|
+
|
450
|
+
# @!method dont_select
|
451
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$dontSelect".
|
452
|
+
# @example
|
453
|
+
# q.where :field.reject => { key: :other_field, query: query }
|
454
|
+
# @return [RejectionConstraint]
|
455
|
+
|
456
|
+
# @!method reject
|
457
|
+
# Alias for {dont_select}
|
458
|
+
# @return [RejectionConstraint]
|
205
459
|
contraint_keyword :$dontSelect
|
206
|
-
register :dont_select
|
207
460
|
register :reject
|
461
|
+
register :dont_select
|
462
|
+
|
463
|
+
# @return [Hash] the compiled constraint.
|
208
464
|
def build
|
209
465
|
|
210
466
|
# if it's a hash, then it should be {:key=>"objectId", :query=>[]}
|
@@ -215,32 +471,66 @@ module Parse
|
|
215
471
|
remote_field_name = res[:key] || remote_field_name
|
216
472
|
query = res[:query]
|
217
473
|
unless query.is_a?(Parse::Query)
|
218
|
-
raise
|
474
|
+
raise ConstraintError, "Invalid Parse::Query object provided in :query field of value: #{@operation.operand}.#{$dontSelect} => #{@value}"
|
219
475
|
end
|
220
476
|
query = query.compile(encode: false, includeClassName: true)
|
221
477
|
elsif @value.is_a?(Parse::Query)
|
222
478
|
# if its a query, then assume dontSelect key is the same name as operand.
|
223
479
|
query = @value.compile(encode: false, includeClassName: true)
|
224
480
|
else
|
225
|
-
raise
|
481
|
+
raise ConstraintError, "Invalid `:reject` query constraint. It should follow the format: :field.reject => { key: 'key', query: '<Parse::Query>' }"
|
226
482
|
end
|
227
483
|
{ @operation.operand => { :$dontSelect => { key: remote_field_name, query: query } } }
|
228
484
|
end
|
229
485
|
end
|
230
486
|
|
487
|
+
# Equivalent to the `$regex` Parse query operation. Requires that a field value
|
488
|
+
# match a regular expression.
|
489
|
+
#
|
490
|
+
# q.where :field.like => /ruby_regex/i
|
491
|
+
# :name.like => /Bob/i
|
492
|
+
#
|
231
493
|
class RegularExpressionConstraint < Constraint
|
232
494
|
#Requires that a key's value match a regular expression
|
495
|
+
|
496
|
+
# @!method like
|
497
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$regex".
|
498
|
+
# @example
|
499
|
+
# q.where :field.like => /ruby_regex/i
|
500
|
+
# @return [RegularExpressionConstraint]
|
501
|
+
|
502
|
+
# @!method regex
|
503
|
+
# Alias for {like}
|
504
|
+
# @return [RegularExpressionConstraint]
|
233
505
|
contraint_keyword :$regex
|
234
506
|
register :like
|
235
507
|
register :regex
|
236
508
|
end
|
237
509
|
|
238
|
-
#
|
510
|
+
# Equivalent to the `$relatedTo` Parse query operation. If you want to
|
511
|
+
# retrieve objects that are members of a `Relation` field in your Parse class.
|
512
|
+
#
|
513
|
+
# q.where :field.related_to => pointer
|
514
|
+
#
|
515
|
+
# # find all Users who have liked this post object
|
516
|
+
# post = Post.first
|
517
|
+
# users = Parse::User.all :likes.related_to => post
|
518
|
+
#
|
239
519
|
class RelationQueryConstraint < Constraint
|
240
|
-
#
|
520
|
+
# @!method related_to
|
521
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$relatedTo".
|
522
|
+
# @example
|
523
|
+
# q.where :field.related_to => pointer
|
524
|
+
# @return [RelationQueryConstraint]
|
525
|
+
|
526
|
+
# @!method rel
|
527
|
+
# Alias for {related_to}
|
528
|
+
# @return [RelationQueryConstraint]
|
241
529
|
contraint_keyword :$relatedTo
|
242
530
|
register :related_to
|
243
531
|
register :rel
|
532
|
+
|
533
|
+
# @return [Hash] the compiled constraint.
|
244
534
|
def build
|
245
535
|
# pointer = formatted_value
|
246
536
|
# unless pointer.is_a?(Parse::Pointer)
|
@@ -250,23 +540,83 @@ module Parse
|
|
250
540
|
end
|
251
541
|
end
|
252
542
|
|
543
|
+
# Equivalent to the `$inQuery` Parse query operation. Useful if you want to
|
544
|
+
# retrieve objects where a field contains an object that matches another query.
|
545
|
+
#
|
546
|
+
# q.where :field.matches => query
|
547
|
+
# # assume Post class has an image column.
|
548
|
+
# q.where :post.matches => Post.where(:image.exists => true )
|
549
|
+
#
|
253
550
|
class InQueryConstraint < Constraint
|
551
|
+
# @!method matches
|
552
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$inQuery".
|
553
|
+
# @example
|
554
|
+
# q.where :field.matches => query
|
555
|
+
# @return [InQueryConstraint]
|
556
|
+
|
557
|
+
# @!method in_query
|
558
|
+
# Alias for {matches}
|
559
|
+
# @return [InQueryConstraint]
|
254
560
|
contraint_keyword :$inQuery
|
255
561
|
register :matches
|
256
562
|
register :in_query
|
257
563
|
end
|
258
564
|
|
565
|
+
# Equivalent to the `$notInQuery` Parse query operation. Useful if you want to
|
566
|
+
# retrieve objects where a field contains an object that does not match another query.
|
567
|
+
# This is the inverse of the {InQueryConstraint}.
|
568
|
+
#
|
569
|
+
# q.where :field.excludes => query
|
570
|
+
#
|
571
|
+
# q.where :post.excludes => Post.where(:image.exists => true
|
572
|
+
#
|
259
573
|
class NotInQueryConstraint < Constraint
|
574
|
+
# @!method excludes
|
575
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$notInQuery".
|
576
|
+
# @example
|
577
|
+
# q.where :field.excludes => query
|
578
|
+
# @return [NotInQueryConstraint]
|
579
|
+
|
580
|
+
# @!method not_in_query
|
581
|
+
# Alias for {excludes}
|
582
|
+
# @return [NotInQueryConstraint]
|
260
583
|
contraint_keyword :$notInQuery
|
261
584
|
register :excludes
|
262
585
|
register :not_in_query
|
263
586
|
|
264
587
|
end
|
265
588
|
|
589
|
+
# Equivalent to the `$nearSphere` Parse query operation. This is only applicable
|
590
|
+
# if the field is of type `GeoPoint`. This will query Parse and return a list of
|
591
|
+
# results ordered by distance with the nearest object being first.
|
592
|
+
#
|
593
|
+
# q.where :field.near => geopoint
|
594
|
+
#
|
595
|
+
# geopoint = Parse::GeoPoint.new(30.0, -20.0)
|
596
|
+
# PlaceObject.all :location.near => geopoint
|
597
|
+
# If you wish to constrain the geospatial query to a maximum number of _miles_,
|
598
|
+
# you can utilize the `max_miles` method on a `Parse::GeoPoint` object. This
|
599
|
+
# is equivalent to the `$maxDistanceInMiles` constraint used with `$nearSphere`.
|
600
|
+
#
|
601
|
+
# q.where :field.near => geopoint.max_miles(distance)
|
602
|
+
# # or provide a triplet includes max miles constraint
|
603
|
+
# q.where :field.near => [lat, lng, miles]
|
604
|
+
#
|
605
|
+
# geopoint = Parse::GeoPoint.new(30.0, -20.0)
|
606
|
+
# PlaceObject.all :location.near => geopoint.max_miles(10)
|
607
|
+
#
|
608
|
+
# @todo Add support $maxDistanceInKilometers (for kms) and $maxDistanceInRadians (for radian angle).
|
266
609
|
class NearSphereQueryConstraint < Constraint
|
610
|
+
# @!method near
|
611
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$nearSphere".
|
612
|
+
# @example
|
613
|
+
# q.where :field.near => geopoint
|
614
|
+
# q.where :field.near => geopoint.max_miles(distance)
|
615
|
+
# @return [NearSphereQueryConstraint]
|
267
616
|
contraint_keyword :$nearSphere
|
268
617
|
register :near
|
269
618
|
|
619
|
+
# @return [Hash] the compiled constraint.
|
270
620
|
def build
|
271
621
|
point = formatted_value
|
272
622
|
max_miles = nil
|
@@ -282,15 +632,35 @@ module Parse
|
|
282
632
|
|
283
633
|
end
|
284
634
|
|
635
|
+
# Equivalent to the `$within` Parse query operation and `$box` geopoint
|
636
|
+
# constraint. The rectangular bounding box is defined by a southwest point as
|
637
|
+
# the first parameter, followed by the a northeast point. Please note that Geo
|
638
|
+
# box queries that cross the international date lines are not currently
|
639
|
+
# supported by Parse.
|
640
|
+
#
|
641
|
+
# q.where :field.within_box => [soutwestGeoPoint, northeastGeoPoint]
|
642
|
+
#
|
643
|
+
# sw = Parse::GeoPoint.new 32.82, -117.23 # San Diego
|
644
|
+
# ne = Parse::GeoPoint.new 36.12, -115.31 # Las Vegas
|
645
|
+
#
|
646
|
+
# # get all PlaceObjects inside this bounding box
|
647
|
+
# PlaceObject.all :location.within_box => [sw,ne]
|
648
|
+
#
|
285
649
|
class WithinGeoBoxQueryConstraint < Constraint
|
650
|
+
# @!method within_box
|
651
|
+
# A registered method on a symbol to create the constraint. Maps to Parse operator "$within".
|
652
|
+
# @example
|
653
|
+
# q.where :field.within_box => [soutwestGeoPoint, northeastGeoPoint]
|
654
|
+
# @return [WithinGeoBoxQueryConstraint]
|
286
655
|
contraint_keyword :$within
|
287
656
|
register :within_box
|
288
657
|
|
658
|
+
# @return [Hash] the compiled constraint.
|
289
659
|
def build
|
290
660
|
geopoint_values = formatted_value
|
291
661
|
unless geopoint_values.is_a?(Array) && geopoint_values.count == 2 &&
|
292
662
|
geopoint_values.first.is_a?(Parse::GeoPoint) && geopoint_values.last.is_a?(Parse::GeoPoint)
|
293
|
-
raise(
|
663
|
+
raise(ConstraintError, '[Parse::Query] Invalid query value parameter passed to `within_box` constraint. ' +
|
294
664
|
'Values in array must be `Parse::GeoPoint` objects and ' +
|
295
665
|
'it should be in an array format: [southwestPoint, northeastPoint]' )
|
296
666
|
end
|