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
@@ -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
|