parse-stack 1.7.3 → 1.9.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 +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
|