parse-stack 1.7.3 → 1.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +36 -0
- data/.solargraph.yml +23 -0
- data/.travis.yml +6 -3
- data/Changes.md +84 -22
- data/Gemfile +14 -12
- data/Gemfile.lock +110 -60
- data/README.md +67 -24
- data/Rakefile +14 -14
- data/bin/parse-console +1 -0
- data/lib/parse/api/aggregate.rb +59 -0
- data/lib/parse/api/all.rb +2 -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 +9 -14
- 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 +55 -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 +19 -24
- data/lib/parse/model/associations/collection_proxy.rb +328 -317
- data/lib/parse/model/associations/has_many.rb +22 -27
- data/lib/parse/model/associations/has_one.rb +7 -12
- data/lib/parse/model/associations/pointer_collection_proxy.rb +5 -13
- 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 +21 -17
- 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 +53 -68
- data/lib/parse/model/core/querying.rb +292 -282
- data/lib/parse/model/core/schema.rb +89 -92
- data/lib/parse/model/date.rb +16 -23
- 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 +58 -70
- 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 +70 -37
- data/lib/parse/query/constraint.rb +4 -6
- data/lib/parse/query/constraints.rb +62 -20
- data/lib/parse/query/operation.rb +8 -11
- data/lib/parse/query/ordering.rb +45 -49
- data/lib/parse/stack.rb +15 -11
- 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 +28 -28
- data/parse-stack.png +0 -0
- metadata +27 -25
- data/.github/parse-ruby-sdk.png +0 -0
data/lib/parse/query.rb
CHANGED
@@ -5,11 +5,11 @@ require_relative "client"
|
|
5
5
|
require_relative "query/operation"
|
6
6
|
require_relative "query/constraints"
|
7
7
|
require_relative "query/ordering"
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
8
|
+
require "active_model"
|
9
|
+
require "active_model_serializers"
|
10
|
+
require "active_support"
|
11
|
+
require "active_support/inflector"
|
12
|
+
require "active_support/core_ext"
|
13
13
|
|
14
14
|
module Parse
|
15
15
|
# The {Parse::Query} class provides the lower-level querying interface for
|
@@ -62,7 +62,7 @@ module Parse
|
|
62
62
|
# You can build your own custom query constraints by creating a `Parse::Constraint`
|
63
63
|
# subclass. For all these `where` clauses assume `q` is a `Parse::Query` object.
|
64
64
|
class Query
|
65
|
-
extend
|
65
|
+
extend ::ActiveModel::Callbacks
|
66
66
|
include Parse::Client::Connectable
|
67
67
|
include Enumerable
|
68
68
|
# @!group Callbacks
|
@@ -196,8 +196,8 @@ module Parse
|
|
196
196
|
# @param table [String] the name of the Parse collection to query. (ex. "_User")
|
197
197
|
# @param constraints [Hash] a set of query constraints.
|
198
198
|
# @return [Query] a new query for the Parse collection with the passed in constraints.
|
199
|
-
def all(table, constraints = {limit: :max})
|
200
|
-
self.new(table, constraints.reverse_merge({limit: :max}))
|
199
|
+
def all(table, constraints = { limit: :max })
|
200
|
+
self.new(table, constraints.reverse_merge({ limit: :max }))
|
201
201
|
end
|
202
202
|
|
203
203
|
# This methods takes a set of constraints and merges them to build a final
|
@@ -205,7 +205,7 @@ module Parse
|
|
205
205
|
# @param where [Array] an array of {Parse::Constraint} objects.
|
206
206
|
# @return [Hash] a hash representing the compiled query
|
207
207
|
def compile_where(where)
|
208
|
-
constraint_reduce(
|
208
|
+
constraint_reduce(where)
|
209
209
|
end
|
210
210
|
|
211
211
|
# @!visibility private
|
@@ -214,7 +214,7 @@ module Parse
|
|
214
214
|
clauses.reduce({}) do |clause, subclause|
|
215
215
|
#puts "Merging Subclause: #{subclause.as_json}"
|
216
216
|
|
217
|
-
clause.deep_merge!(
|
217
|
+
clause.deep_merge!(subclause.as_json || {})
|
218
218
|
clause
|
219
219
|
end
|
220
220
|
end
|
@@ -228,7 +228,6 @@ module Parse
|
|
228
228
|
query.define_singleton_method(:inspect) { self.results.to_a.inspect }
|
229
229
|
end
|
230
230
|
end
|
231
|
-
|
232
231
|
end
|
233
232
|
|
234
233
|
# @!attribute [r] client
|
@@ -314,7 +313,7 @@ module Parse
|
|
314
313
|
elsif expression == :keys
|
315
314
|
keys value
|
316
315
|
elsif expression == :key
|
317
|
-
|
316
|
+
keys [value]
|
318
317
|
elsif expression == :skip
|
319
318
|
skip value
|
320
319
|
elsif expression == :limit
|
@@ -334,6 +333,7 @@ module Parse
|
|
334
333
|
end # each
|
335
334
|
self #chaining
|
336
335
|
end
|
336
|
+
|
337
337
|
alias_method :query, :conditions
|
338
338
|
alias_method :append, :conditions
|
339
339
|
|
@@ -418,7 +418,7 @@ module Parse
|
|
418
418
|
# @param amount [Integer] The number of records to skip.
|
419
419
|
# @return [self]
|
420
420
|
def skip(amount)
|
421
|
-
@skip = [0,amount.to_i].max
|
421
|
+
@skip = [0, amount.to_i].max
|
422
422
|
@results = nil
|
423
423
|
self #chaining
|
424
424
|
end
|
@@ -434,11 +434,11 @@ module Parse
|
|
434
434
|
# Song.all :limit => 2025 # large limits supported.
|
435
435
|
# Song.all :limit => :max # as many records as possible.
|
436
436
|
# @param count [Integer,Symbol] The number of records to return. You may pass :max
|
437
|
-
# to get as many
|
437
|
+
# to get as many records as possible (Parse-Server dependent).
|
438
438
|
# @return [self]
|
439
439
|
def limit(count)
|
440
440
|
if count.is_a?(Numeric)
|
441
|
-
@limit = [
|
441
|
+
@limit = [0, count.to_i].max
|
442
442
|
elsif count == :max
|
443
443
|
@limit = :max
|
444
444
|
else
|
@@ -497,10 +497,15 @@ module Parse
|
|
497
497
|
# # add where :like_count is greater than 20
|
498
498
|
# query.add_constraint(:like_count.gt, 20)
|
499
499
|
#
|
500
|
+
# # same, but ignore field formatting
|
501
|
+
# query.add_constraint(:like_count.gt, 20, filter: false)
|
502
|
+
#
|
500
503
|
# @param operator [Parse::Operator] an operator object containing the operation and operand.
|
501
504
|
# @param value [Object] the value for the constraint.
|
505
|
+
# @param opts [Object] A set of options. Passing :filter with false, will skip field formatting.
|
506
|
+
# @see Query#format_field
|
502
507
|
# @return [self]
|
503
|
-
def add_constraint(operator, value = nil,
|
508
|
+
def add_constraint(operator, value = nil, opts = {})
|
504
509
|
@where ||= []
|
505
510
|
constraint = operator # assume Parse::Constraint
|
506
511
|
unless constraint.is_a?(Parse::Constraint)
|
@@ -579,7 +584,7 @@ module Parse
|
|
579
584
|
# @return [Query] the combined query with an OR clause.
|
580
585
|
def or_where(where_clauses = [])
|
581
586
|
where_clauses = where_clauses.where if where_clauses.is_a?(Parse::Query)
|
582
|
-
where_clauses = Parse::Query.new(@table, where_clauses
|
587
|
+
where_clauses = Parse::Query.new(@table, where_clauses).where if where_clauses.is_a?(Hash)
|
583
588
|
return self if where_clauses.blank?
|
584
589
|
# we can only have one compound query constraint. If we need to add another OR clause
|
585
590
|
# let's find the one we have (if any)
|
@@ -589,7 +594,7 @@ module Parse
|
|
589
594
|
# if we don't have a OR clause to reuse, then create a new one with then
|
590
595
|
# current set of constraints
|
591
596
|
if compound.blank?
|
592
|
-
compound = Parse::Constraint::CompoundQueryConstraint.new :or, [
|
597
|
+
compound = Parse::Constraint::CompoundQueryConstraint.new :or, [Parse::Query.compile_where(remaining_clauses)]
|
593
598
|
end
|
594
599
|
# then take the where clauses from the second query and append them.
|
595
600
|
compound.value.push Parse::Query.compile_where(where_clauses)
|
@@ -601,10 +606,39 @@ module Parse
|
|
601
606
|
# @see #or_where
|
602
607
|
# @return [Query] the combined query with an OR clause.
|
603
608
|
def |(other_query)
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
609
|
+
raise ArgumentError, "Parse queries must be of the same class #{@table}." unless @table == other_query.table
|
610
|
+
copy_query = self.clone
|
611
|
+
copy_query.or_where other_query.where
|
612
|
+
copy_query
|
613
|
+
end
|
614
|
+
|
615
|
+
# Queries can be made using distinct, allowing you find unique values for a specified field.
|
616
|
+
# For this to be performant, please remember to index your database.
|
617
|
+
# @example
|
618
|
+
# # Return a set of unique city names
|
619
|
+
# # for users who are greater than 21 years old
|
620
|
+
# Parse::Query.all(distinct: :age)
|
621
|
+
# query = Parse::Query.new("_User")
|
622
|
+
# query.where :age.gt => 21
|
623
|
+
# # triggers query
|
624
|
+
# query.distinct(:city) #=> ["San Diego", "Los Angeles", "San Juan"]
|
625
|
+
# @note This feature requires use of the Master Key in the API.
|
626
|
+
# @param field [Symbol|String] The name of the field used for filtering.
|
627
|
+
# @version 1.8.0
|
628
|
+
def distinct(field)
|
629
|
+
if field.nil? == false && field.respond_to?(:to_s)
|
630
|
+
# disable counting if it was enabled.
|
631
|
+
old_count_value = @count
|
632
|
+
@count = nil
|
633
|
+
compile_query = compile # temporary store
|
634
|
+
# add distinct field
|
635
|
+
compile_query[:distinct] = Query.format_field(field).to_sym
|
636
|
+
@count = old_count_value
|
637
|
+
# perform aggregation
|
638
|
+
return client.aggregate_objects(@table, compile_query.as_json, _opts).result
|
639
|
+
else
|
640
|
+
raise ArgumentError, "Invalid field name passed to `distinct`."
|
641
|
+
end
|
608
642
|
end
|
609
643
|
|
610
644
|
# Perform a count query.
|
@@ -620,7 +654,7 @@ module Parse
|
|
620
654
|
def count
|
621
655
|
old_value = @count
|
622
656
|
@count = 1
|
623
|
-
res = client.find_objects(@table, compile.as_json, _opts
|
657
|
+
res = client.find_objects(@table, compile.as_json, _opts).count
|
624
658
|
@count = old_value
|
625
659
|
res
|
626
660
|
end
|
@@ -629,8 +663,8 @@ module Parse
|
|
629
663
|
# @return [Array]
|
630
664
|
# @see Array#each
|
631
665
|
def each
|
632
|
-
|
633
|
-
|
666
|
+
return results.enum_for(:each) unless block_given? # Sparkling magic!
|
667
|
+
results.each(&Proc.new)
|
634
668
|
end
|
635
669
|
|
636
670
|
# @yield a block yield for each object in the result
|
@@ -684,7 +718,7 @@ module Parse
|
|
684
718
|
compiled_query[:limit] = _limit if _limit < batch_size
|
685
719
|
end
|
686
720
|
|
687
|
-
response = fetch!(
|
721
|
+
response = fetch!(compiled_query)
|
688
722
|
break if response.error? || response.results.empty?
|
689
723
|
|
690
724
|
items = response.results
|
@@ -732,13 +766,13 @@ module Parse
|
|
732
766
|
# @param compiled_query [Hash] the compiled query
|
733
767
|
# @return [Parse::Response] a response for a query request.
|
734
768
|
def fetch!(compiled_query)
|
735
|
-
|
736
|
-
response = client.find_objects(@table, compiled_query.as_json, _opts )
|
769
|
+
response = client.find_objects(@table, compiled_query.as_json, _opts)
|
737
770
|
if response.error?
|
738
771
|
puts "[ParseQuery] #{response.error}"
|
739
772
|
end
|
740
773
|
response
|
741
774
|
end
|
775
|
+
|
742
776
|
alias_method :execute!, :fetch!
|
743
777
|
|
744
778
|
# Executes the query and builds the result set of Parse::Objects that matched.
|
@@ -767,7 +801,7 @@ module Parse
|
|
767
801
|
if block_given?
|
768
802
|
max_results(raw: raw, &Proc.new)
|
769
803
|
elsif @limit.is_a?(Numeric)
|
770
|
-
response = fetch!(
|
804
|
+
response = fetch!(compile)
|
771
805
|
return [] if response.error?
|
772
806
|
items = raw ? response.results : decode(response.results)
|
773
807
|
return items.each(&Proc.new) if block_given?
|
@@ -778,6 +812,7 @@ module Parse
|
|
778
812
|
end
|
779
813
|
@results
|
780
814
|
end
|
815
|
+
|
781
816
|
alias_method :result, :results
|
782
817
|
|
783
818
|
# Similar to {#results} but takes an additional set of conditions to apply. This
|
@@ -787,7 +822,7 @@ module Parse
|
|
787
822
|
# @return [Array<Hash>] if raw is set to true, a set of Parse JSON hashes.
|
788
823
|
# @return [Array<Parse::Object>] if raw is set to false, a list of matching Parse::Object subclasses.
|
789
824
|
# @see #results
|
790
|
-
def all(expressions = {limit: :max})
|
825
|
+
def all(expressions = { limit: :max })
|
791
826
|
conditions(expressions)
|
792
827
|
return results(&Proc.new) if block_given?
|
793
828
|
results
|
@@ -825,9 +860,9 @@ module Parse
|
|
825
860
|
q[:limit] = @limit if @limit.is_a?(Numeric) && @limit > 0
|
826
861
|
q[:skip] = @skip if @skip > 0
|
827
862
|
|
828
|
-
q[:include] = @includes.join(
|
829
|
-
q[:keys] = @keys.join(
|
830
|
-
q[:order] = @order.join(
|
863
|
+
q[:include] = @includes.join(",") unless @includes.empty?
|
864
|
+
q[:keys] = @keys.join(",") unless @keys.empty?
|
865
|
+
q[:order] = @order.join(",") unless @order.empty?
|
831
866
|
unless @where.empty?
|
832
867
|
q[:where] = Parse::Query.compile_where(@where)
|
833
868
|
q[:where] = q[:where].to_json if encode
|
@@ -847,15 +882,13 @@ module Parse
|
|
847
882
|
|
848
883
|
# @return [Hash] a hash representing just the `where` clause of this query.
|
849
884
|
def compile_where
|
850
|
-
self.class.compile_where(
|
885
|
+
self.class.compile_where(@where || [])
|
851
886
|
end
|
852
887
|
|
853
888
|
# Retruns a formatted JSON string representing the query, useful for debugging.
|
854
889
|
# @return [String]
|
855
890
|
def pretty
|
856
|
-
JSON.pretty_generate(
|
891
|
+
JSON.pretty_generate(as_json)
|
857
892
|
end
|
858
|
-
|
859
893
|
end # Query
|
860
|
-
|
861
894
|
end # Parse
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require_relative
|
5
|
-
require
|
6
|
-
require
|
4
|
+
require_relative "operation"
|
5
|
+
require "time"
|
6
|
+
require "date"
|
7
7
|
|
8
8
|
module Parse
|
9
9
|
# Constraints are the heart of the Parse::Query system.
|
@@ -39,12 +39,11 @@ module Parse
|
|
39
39
|
# it most likely is just the field name, so let's assume they want
|
40
40
|
# the default equality operation.
|
41
41
|
if operation.is_a?(Operation) == false && operation.respond_to?(:to_sym)
|
42
|
-
|
42
|
+
operation = Operation.new(operation.to_sym, self.class.operand)
|
43
43
|
end
|
44
44
|
@operation = operation
|
45
45
|
@value = value
|
46
46
|
yield(self) if block_given?
|
47
|
-
|
48
47
|
end
|
49
48
|
|
50
49
|
class << self
|
@@ -122,7 +121,6 @@ module Parse
|
|
122
121
|
end
|
123
122
|
d
|
124
123
|
end
|
125
|
-
|
126
124
|
end
|
127
125
|
|
128
126
|
# @return [Integer] the precedence of this constraint
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require_relative
|
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)
|
@@ -60,7 +60,7 @@ module Parse
|
|
60
60
|
value = formatted_value
|
61
61
|
# if it is already a pointer value, just return the constraint. Allows for
|
62
62
|
# supporting strings, symbols and pointers.
|
63
|
-
return { @operation.operand
|
63
|
+
return { @operation.operand => value } if value.is_a?(Parse::Pointer)
|
64
64
|
|
65
65
|
begin
|
66
66
|
klass = className.constantize
|
@@ -79,9 +79,8 @@ module Parse
|
|
79
79
|
raise ArgumentError, "#{self.class}: value must be of string type representing a Parse object id."
|
80
80
|
end
|
81
81
|
value.strip!
|
82
|
-
return { @operation.operand
|
82
|
+
return { @operation.operand => klass.pointer(value) }
|
83
83
|
end
|
84
|
-
|
85
84
|
end
|
86
85
|
|
87
86
|
# Equivalent to the `$or` Parse query operation. This is useful if you want to
|
@@ -101,7 +100,6 @@ module Parse
|
|
101
100
|
or_clauses = formatted_value
|
102
101
|
return { :$or => Array.wrap(or_clauses) }
|
103
102
|
end
|
104
|
-
|
105
103
|
end
|
106
104
|
|
107
105
|
# Equivalent to the `$lte` Parse query operation. The alias `on_or_before` is provided for readability.
|
@@ -154,6 +152,7 @@ module Parse
|
|
154
152
|
register :less_than
|
155
153
|
register :before
|
156
154
|
end
|
155
|
+
|
157
156
|
# Equivalent to the `$gt` Parse query operation. The alias `after` is provided for readability.
|
158
157
|
# q.where :field.gt => value
|
159
158
|
# q.where :field.after => date
|
@@ -252,13 +251,12 @@ module Parse
|
|
252
251
|
end
|
253
252
|
|
254
253
|
if value == true
|
255
|
-
return { @operation.operand => { key => false} }
|
254
|
+
return { @operation.operand => { key => false } }
|
256
255
|
else
|
257
256
|
#current bug in parse where if you want exists => true with geo queries
|
258
257
|
# we should map it to a "not equal to null" constraint
|
259
258
|
return { @operation.operand => { Parse::Constraint::NotEqualConstraint.key => nil } }
|
260
259
|
end
|
261
|
-
|
262
260
|
end
|
263
261
|
end
|
264
262
|
|
@@ -319,7 +317,6 @@ module Parse
|
|
319
317
|
val = [val].compact unless val.is_a?(Array)
|
320
318
|
{ @operation.operand => { key => val } }
|
321
319
|
end
|
322
|
-
|
323
320
|
end
|
324
321
|
|
325
322
|
# Equivalent to the `$nin` Parse query operation. Checks whether the value in
|
@@ -357,7 +354,6 @@ module Parse
|
|
357
354
|
val = [val].compact unless val.is_a?(Array)
|
358
355
|
{ @operation.operand => { key => val } }
|
359
356
|
end
|
360
|
-
|
361
357
|
end
|
362
358
|
|
363
359
|
# Equivalent to the $all Parse query operation. Checks whether the value in
|
@@ -585,7 +581,6 @@ module Parse
|
|
585
581
|
contraint_keyword :$notInQuery
|
586
582
|
register :excludes
|
587
583
|
register :not_in_query
|
588
|
-
|
589
584
|
end
|
590
585
|
|
591
586
|
# Equivalent to the `$nearSphere` Parse query operation. This is only applicable
|
@@ -631,7 +626,6 @@ module Parse
|
|
631
626
|
end
|
632
627
|
{ @operation.operand => { key => point } }
|
633
628
|
end
|
634
|
-
|
635
629
|
end
|
636
630
|
|
637
631
|
# Equivalent to the `$within` Parse query operation and `$box` geopoint
|
@@ -661,10 +655,10 @@ module Parse
|
|
661
655
|
def build
|
662
656
|
geopoint_values = formatted_value
|
663
657
|
unless geopoint_values.is_a?(Array) && geopoint_values.count == 2 &&
|
664
|
-
|
665
|
-
raise(ArgumentError,
|
666
|
-
|
667
|
-
|
658
|
+
geopoint_values.first.is_a?(Parse::GeoPoint) && geopoint_values.last.is_a?(Parse::GeoPoint)
|
659
|
+
raise(ArgumentError, "[Parse::Query] Invalid query value parameter passed to `within_box` constraint. " +
|
660
|
+
"Values in array must be `Parse::GeoPoint` objects and " +
|
661
|
+
"it should be in an array format: [southwestPoint, northeastPoint]")
|
668
662
|
end
|
669
663
|
{ @operation.operand => { :$within => { :$box => geopoint_values } } }
|
670
664
|
end
|
@@ -703,17 +697,65 @@ module Parse
|
|
703
697
|
def build
|
704
698
|
geopoint_values = formatted_value
|
705
699
|
unless geopoint_values.is_a?(Array) &&
|
706
|
-
geopoint_values.all? {|point| point.is_a?(Parse::GeoPoint) } &&
|
700
|
+
geopoint_values.all? { |point| point.is_a?(Parse::GeoPoint) } &&
|
707
701
|
geopoint_values.count > 2
|
708
|
-
raise ArgumentError,
|
709
|
-
|
710
|
-
|
702
|
+
raise ArgumentError, "[Parse::Query] Invalid query value parameter passed to" \
|
703
|
+
" `within_polygon` constraint: Value must be an array with 3" \
|
704
|
+
" or more `Parse::GeoPoint` objects"
|
711
705
|
end
|
712
706
|
|
713
707
|
{ @operation.operand => { :$geoWithin => { :$polygon => geopoint_values } } }
|
714
708
|
end
|
715
709
|
end
|
716
710
|
|
717
|
-
|
711
|
+
# Equivalent to the full text search support with `$text` with a set of search crieteria.
|
712
|
+
class FullTextSearchQueryConstraint < Constraint
|
713
|
+
# @!method text_search
|
714
|
+
# A registered method on a symbol to create the constraint. Maps to Parse
|
715
|
+
# operator "$text" with "$search" subconstraint. Takes a hash of parameters.
|
716
|
+
# @example
|
717
|
+
# # As many points as you want
|
718
|
+
# q.where :field.text_search => {parameters}
|
719
|
+
#
|
720
|
+
# Where `parameters` can be one of:
|
721
|
+
# $term : Specify a field to search (Required)
|
722
|
+
# $language : Determines the list of stop words and the rules for tokenizer.
|
723
|
+
# $caseSensitive : Enable or disable case sensitive search.
|
724
|
+
# $diacriticSensitive : Enable or disable diacritic sensitive search
|
725
|
+
#
|
726
|
+
# @note This method will automatically add `$` to each key of the parameters
|
727
|
+
# hash if it doesn't already have it.
|
728
|
+
# @return [WithinPolygonQueryConstraint]
|
729
|
+
# @version 1.8.0 (requires Server v2.5.0 or later)
|
730
|
+
contraint_keyword :$text
|
731
|
+
register :text_search
|
718
732
|
|
733
|
+
# @return [Hash] the compiled constraint.
|
734
|
+
def build
|
735
|
+
params = formatted_value
|
736
|
+
|
737
|
+
params = { :$term => params.to_s } if params.is_a?(String) || params.is_a?(Symbol)
|
738
|
+
|
739
|
+
unless params.is_a?(Hash)
|
740
|
+
raise ArgumentError, "[Parse::Query] Invalid query value parameter passed to" \
|
741
|
+
" `text_search` constraint: Value must be a string or a hash of parameters."
|
742
|
+
end
|
743
|
+
|
744
|
+
params = params.inject({}) do |h, (k, v)|
|
745
|
+
u = k.to_s
|
746
|
+
u = u.columnize.prepend("$") unless u.start_with?("$")
|
747
|
+
h[u] = v
|
748
|
+
h
|
749
|
+
end
|
750
|
+
|
751
|
+
unless params["$term"].present?
|
752
|
+
raise ArgumentError, "[Parse::Query] Invalid query value parameter passed to" \
|
753
|
+
" `text_search` constraint: Missing required `$term` subkey.\n" \
|
754
|
+
"\tExample: #{@operation.operand}.text_search => { term: 'text to search' }"
|
755
|
+
end
|
756
|
+
|
757
|
+
{ @operation.operand => { :$text => { :$search => params } } }
|
758
|
+
end
|
759
|
+
end
|
760
|
+
end
|
719
761
|
end
|