parse-stack 1.3.1 → 1.3.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,10 @@
1
1
  require 'active_model'
2
+ require 'active_support'
2
3
  require 'active_support/inflector'
4
+ require 'active_support/core_ext'
3
5
  require 'active_model_serializers'
4
6
  require_relative 'model'
7
+ require 'active_model_serializers'
5
8
  module Parse
6
9
 
7
10
  # A Parse Pointer is the superclass of Parse::Object types. A pointer can be considered
@@ -1,6 +1,6 @@
1
1
  require_relative '../query.rb'
2
2
  require_relative '../client.rb'
3
-
3
+ require 'active_model_serializers'
4
4
  module Parse
5
5
 
6
6
  class Push
@@ -10,7 +10,7 @@ module Parse
10
10
 
11
11
  alias_method :message, :alert
12
12
  alias_method :message=, :alert=
13
-
13
+
14
14
  def self.send(payload)
15
15
  client.push payload.as_json
16
16
  end
@@ -2,7 +2,10 @@ require_relative "client"
2
2
  require_relative "query/operation"
3
3
  require_relative "query/constraints"
4
4
  require_relative "query/ordering"
5
-
5
+ require 'active_model_serializers'
6
+ require 'active_support'
7
+ require 'active_support/inflector'
8
+ require 'active_support/core_ext'
6
9
 
7
10
  module Parse
8
11
  # This is the main engine behind making Parse queries on tables. It takes
@@ -23,7 +26,7 @@ module Parse
23
26
  # You can modify the default client being used by all Parse::Query objects by setting
24
27
  # Parse::Query.client. You can override individual Parse::Query object clients
25
28
  # by changing their client variable to a different Parse::Client object.
26
- attr_accessor :table, :client, :key, :cache, :use_master_key
29
+ attr_accessor :table, :client, :key, :cache, :use_master_key, :session_token
27
30
 
28
31
  # We have a special class method to handle field formatting. This turns
29
32
  # the symbol keys in an operand from one key to another. For example, we can
@@ -34,23 +37,17 @@ module Parse
34
37
  # in lower case). You can specify a different method to call by setting the Parse::Query.field_formatter
35
38
  # variable with the symbol name of the method to call on the object. You can set this to nil
36
39
  # if you do not want any field formatting to be performed.
40
+ @field_formatter = :columnize
37
41
  class << self
38
42
  #field formatter getters and setters.
39
43
  attr_accessor :field_formatter
40
44
 
41
- def field_formatter
42
- #default
43
- @field_formatter ||= :columnize
44
- end
45
-
46
45
  def format_field(str)
47
- res = str.to_s
48
- if field_formatter.present?
49
- formatter = field_formatter.to_sym
50
- # don't format if object d
51
- res = res.send(formatter) if res.respond_to?(formatter)
46
+ res = str.to_s.strip
47
+ if field_formatter.present? && res.respond_to?(field_formatter)
48
+ res = res.send(field_formatter)
52
49
  end
53
- res.strip
50
+ res
54
51
  end
55
52
 
56
53
  # Simple way to create a query.
@@ -78,7 +75,7 @@ module Parse
78
75
  when :skip
79
76
  @skip = 0
80
77
  when :limit
81
- @limit = 100
78
+ @limit = nil
82
79
  when :count
83
80
  @count = 0
84
81
  when :keys
@@ -96,7 +93,7 @@ module Parse
96
93
  @order = []
97
94
  @keys = []
98
95
  @includes = []
99
- @limit = 100
96
+ @limit = nil
100
97
  @skip = 0
101
98
  @table = table
102
99
  @cache = true
@@ -123,6 +120,10 @@ module Parse
123
120
  self.cache = value
124
121
  elsif expression == :use_master_key
125
122
  self.cache = value
123
+ elsif expression == :session
124
+ # you can pass a session token or a Parse::Session
125
+ value = value.is_a?(Parse::Session) ? value.session_token : value
126
+ self.session_token = value
126
127
  else
127
128
  add_constraint(expression, value)
128
129
  end
@@ -176,6 +177,8 @@ module Parse
176
177
  @limit = 11_000
177
178
  elsif count.is_a?(Numeric)
178
179
  @limit = [ 0, count.to_i, 11_000].sort[1]
180
+ else
181
+ @limit = nil
179
182
  end
180
183
 
181
184
  @results = nil
@@ -314,6 +317,12 @@ module Parse
314
317
  opts = {}
315
318
  opts[:cache] = false unless self.cache
316
319
  opts[:use_mster_key] = self.use_master_key
320
+ opts[:session_token] = self.session_token
321
+ # for now, don't cache requests where we disable master_key or provide session token
322
+ if opts[:use_mster_key] == false || opts[:session_token].present?
323
+ opts[:cache] = false
324
+ end
325
+
317
326
  response = client.find_objects(@table, compiled_query.as_json, opts )
318
327
  if response.error?
319
328
  puts "[ParseQuery] #{response.error}"
@@ -323,7 +332,7 @@ module Parse
323
332
 
324
333
  def results(raw: false)
325
334
  if @results.nil?
326
- if @limit <= 1_000
335
+ if @limit.nil? || @limit.to_i <= 1_000
327
336
  response = fetch!( compile )
328
337
  return [] if response.error?
329
338
  items = raw ? response.results : decode(response.results)
@@ -347,7 +356,11 @@ module Parse
347
356
  compile.as_json
348
357
  end
349
358
 
350
- def compile(encode = true)
359
+ def prepared(includeClassName: false)
360
+ compile(encode: false, includeClassName: includeClassName)
361
+ end
362
+
363
+ def compile(encode: true, includeClassName: false)
351
364
  q = {} #query
352
365
  q[:limit] = 11_000 if @limit == :max || @limit == :all
353
366
  q[:limit] = @limit if @limit.is_a?(Numeric) && @limit > 0
@@ -366,6 +379,9 @@ module Parse
366
379
  q[:limit] = 0
367
380
  q[:count] = 1
368
381
  end
382
+ if includeClassName
383
+ q[:className] = @table
384
+ end
369
385
  q
370
386
  end
371
387
 
@@ -123,8 +123,8 @@ module Parse
123
123
  #d = d.pointer if d.is_a?(Parse::Object) #simplified query object
124
124
  # d = d.compile
125
125
  if d.is_a?(Parse::Query)
126
- compiled = d.compile(false)
127
- compiled["className"] = d.table
126
+ compiled = d.compile(encode: false, includeClassName: true)
127
+ # compiled["className"] = d.table
128
128
  d = compiled
129
129
  end
130
130
  d
@@ -24,29 +24,34 @@ module Parse
24
24
  class LessOrEqualConstraint < Constraint
25
25
  contraint_keyword :$lte
26
26
  register :lte
27
+ register :less_than_or_equal
27
28
  register :on_or_before
28
29
  end
29
30
 
30
31
  class LessThanConstraint < Constraint
31
32
  contraint_keyword :$lt
32
33
  register :lt
34
+ register :less_than
33
35
  register :before
34
36
  end
35
37
 
36
38
  class GreaterThanConstraint < Constraint
37
39
  contraint_keyword :$gt
38
40
  register :gt
41
+ register :greater_than
39
42
  register :after
40
43
  end
41
44
 
42
45
  class GreaterOrEqualConstraint < Constraint
43
46
  contraint_keyword :$gte
44
47
  register :gte
48
+ register :greater_than_or_equal
45
49
  register :on_or_after
46
50
  end
47
51
 
48
52
  class NotEqualConstraint < Constraint
49
53
  contraint_keyword :$ne
54
+ register :ne
50
55
  register :not
51
56
  end
52
57
 
@@ -98,6 +103,7 @@ module Parse
98
103
 
99
104
  class NotContainedInConstraint < Constraint
100
105
  contraint_keyword :$nin
106
+ register :nin
101
107
  register :not_in
102
108
  register :not_contained_in
103
109
  end
@@ -115,20 +121,53 @@ module Parse
115
121
  register :select
116
122
 
117
123
  def build
118
- select_key = @value.key.present? ? @value.key : @operation.operand
119
- select_query = formatted_value
120
- { @operation.operand => { key => { query: select_query, key: select_key } } }
124
+
125
+ # if it's a hash, then it should be {:key=>"objectId", :query=>[]}
126
+ remote_field_name = @operation.operand
127
+ query = nil
128
+ if @value.is_a?(Hash)
129
+ res = @value.symbolize_keys
130
+ remote_field_name = res[:key] || remote_field_name
131
+ query = res[:query]
132
+ unless query.is_a?(Parse::Query)
133
+ raise "Invalid Parse::Query object provided in :query field of value: #{@operation.operand}.#{$dontSelect} => #{@value}"
134
+ end
135
+ query = query.compile(encode: false, includeClassName: true)
136
+ elsif @value.is_a?(Parse::Query)
137
+ # if its a query, then assume dontSelect key is the same name as operand.
138
+ query = @value.compile(encode: false, includeClassName: true)
139
+ else
140
+ raise "Invalid `:select` query constraint. It should follow the format: :field.select => { key: 'key', query: '<Parse::Query>' }"
141
+ end
142
+ { @operation.operand => { :$select => { key: remote_field_name, query: query } } }
121
143
  end
122
144
  end
123
145
 
124
146
  class RejectionConstraint < Constraint
125
147
  #requires that a key's value not match a value for a key in the result of a different query
126
148
  contraint_keyword :$dontSelect
149
+ register :dont_select
127
150
  register :reject
128
151
  def build
129
- reject_key = @value.key.present? ? @value.key : @operation.operand
130
- reject_query = formatted_value
131
- { @operation.operand => { key => { query: reject_query, key: reject_key } } }
152
+
153
+ # if it's a hash, then it should be {:key=>"objectId", :query=>[]}
154
+ remote_field_name = @operation.operand
155
+ query = nil
156
+ if @value.is_a?(Hash)
157
+ res = @value.symbolize_keys
158
+ remote_field_name = res[:key] || remote_field_name
159
+ query = res[:query]
160
+ unless query.is_a?(Parse::Query)
161
+ raise "Invalid Parse::Query object provided in :query field of value: #{@operation.operand}.#{$dontSelect} => #{@value}"
162
+ end
163
+ query = query.compile(encode: false, includeClassName: true)
164
+ elsif @value.is_a?(Parse::Query)
165
+ # if its a query, then assume dontSelect key is the same name as operand.
166
+ query = @value.compile(encode: false, includeClassName: true)
167
+ else
168
+ raise "Invalid `:reject` query constraint. It should follow the format: :field.reject => { key: 'key', query: '<Parse::Query>' }"
169
+ end
170
+ { @operation.operand => { :$dontSelect => { key: remote_field_name, query: query } } }
132
171
  end
133
172
  end
134
173
 
@@ -186,4 +225,21 @@ module Parse
186
225
 
187
226
  end
188
227
 
228
+ class WithinGeoBoxQueryConstraint < Constraint
229
+ contraint_keyword :$within
230
+ register :within_box
231
+
232
+ def build
233
+ geopoint_values = formatted_value
234
+ unless geopoint_values.is_a?(Array) && geopoint_values.count == 2 &&
235
+ geopoint_values.first.is_a?(Parse::GeoPoint) && geopoint_values.last.is_a?(Parse::GeoPoint)
236
+ raise( '[Parse::Query] Invalid query value parameter passed to `within_box` constraint. ' +
237
+ 'Values in array must be `Parse::GeoPoint` objects and ' +
238
+ 'it should be in an array format: [southwestPoint, northeastPoint]' )
239
+ end
240
+ { @operation.operand => { :$within => { :$box => geopoint_values } } }
241
+ end
242
+
243
+ end
244
+
189
245
  end
@@ -1,3 +1,4 @@
1
+ require 'active_support'
1
2
  require 'active_support/inflector'
2
3
 
3
4
  # The base operation class used in generating queries.
@@ -6,6 +6,7 @@ require_relative 'webhooks'
6
6
 
7
7
  module Parse
8
8
  module Stack
9
+
9
10
  # Your code goes here...
10
11
  end
11
12
  end
@@ -0,0 +1,107 @@
1
+ require_relative '../stack.rb'
2
+ require 'active_support'
3
+ require 'active_support/inflector'
4
+ require 'active_support/core_ext'
5
+ require 'rake'
6
+ require 'rake/dsl_definition'
7
+
8
+ module Parse
9
+
10
+ module Stack
11
+
12
+ def self.load_tasks
13
+ Parse::Stack::Tasks.new.install_tasks
14
+ end
15
+
16
+ class Tasks
17
+ include Rake::DSL if defined? Rake::DSL
18
+
19
+ def install_tasks
20
+
21
+ namespace :parse do
22
+
23
+ task :env do
24
+ if Rake::Task.task_defined?('environment')
25
+ Rake::Task['environment'].invoke
26
+ end
27
+ end
28
+
29
+ task :verify_env => :env do
30
+
31
+ unless Parse::Client.session?
32
+ raise "Please make sure you have setup the Parse.setup configuration before invoking task. Usually done in the :environment task."
33
+ end
34
+
35
+ endpoint = ENV['HOOKS_URL']
36
+ unless endpoint.empty? || endpoint.starts_with?('https://')
37
+ raise "The ENV variable HOOKS_URL must be a <https> url : '#{endpoint}'. Ex. https://12345678.ngrok.io/webhooks"
38
+ end
39
+
40
+ end
41
+
42
+ desc "Run auto_upgrade on all of your Parse models."
43
+ task :upgrade => :env do
44
+ puts "Auto Upgrading Parse schemas..."
45
+ Parse.auto_upgrade! do |k|
46
+ puts "[+] #{k}"
47
+ end
48
+ end
49
+
50
+ namespace :webhooks do
51
+
52
+ desc "Register local webhooks with Parse server"
53
+ task :register => :verify_env do
54
+ endpoint = ENV['HOOKS_URL']
55
+ puts "Registering Parse Webhooks @ #{endpoint}"
56
+ Rake::Task['parse:webhooks:register:functions'].invoke
57
+ Rake::Task['parse:webhooks:register:triggers'].invoke
58
+ end
59
+
60
+ desc "Remove all locally registered webhooks from the Parse Application"
61
+ task :remove => :verify_env do
62
+ Rake::Task['parse:webhooks:remove:functions'].invoke
63
+ Rake::Task['parse:webhooks:remove:triggers'].invoke
64
+ end
65
+
66
+ namespace :register do
67
+
68
+ task :functions => :verify_env do
69
+ endpoint = ENV['HOOKS_URL']
70
+ Parse::Webhooks.register_functions!(endpoint) do |name|
71
+ puts "[+] function - #{name}"
72
+ end
73
+ end
74
+
75
+ task :triggers => :verify_env do
76
+ endpoint = ENV['HOOKS_URL']
77
+ Parse::Webhooks.register_triggers!(endpoint, {include_wildcard: true}) do |trigger,name|
78
+ puts "[+] #{trigger.to_s.ljust(12, ' ')} - #{name}"
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ namespace :remove do
85
+
86
+ task :functions => :verify_env do
87
+ Parse::Webhooks.remove_all_functions! do |name|
88
+ puts "[-] function - #{name}"
89
+ end
90
+ end
91
+
92
+ task :triggers => :verify_env do
93
+ Parse::Webhooks.remove_all_triggers! do |trigger,name|
94
+ puts "[-] #{trigger.to_s.ljust(12, ' ')} - #{name}"
95
+ end
96
+ end
97
+
98
+ end
99
+
100
+ end # webhooks
101
+
102
+ end # webhooks namespace
103
+ end
104
+ end # Tasks
105
+ end # Webhooks
106
+
107
+ end # Parse
@@ -1,5 +1,5 @@
1
1
  module Parse
2
2
  module Stack
3
- VERSION = "1.3.1"
3
+ VERSION = "1.3.7"
4
4
  end
5
5
  end
@@ -1,8 +1,8 @@
1
-
2
1
  require 'active_model'
3
2
  require 'active_support'
4
3
  require 'active_support/inflector'
5
4
  require 'active_support/core_ext/object'
5
+ require 'active_support/core_ext'
6
6
  require 'active_model_serializers'
7
7
  require 'rack'
8
8
  require_relative 'client'
@@ -90,7 +90,7 @@ module Parse
90
90
  class Webhooks
91
91
 
92
92
  def self.reload!(args = {})
93
-
93
+
94
94
  end
95
95
 
96
96
  include Client::Connectable
@@ -2,6 +2,8 @@ require 'active_model'
2
2
  require 'active_support'
3
3
  require 'active_support/inflector'
4
4
  require 'active_support/core_ext/object'
5
+ require 'active_support/core_ext/string'
6
+ require 'active_support/core_ext'
5
7
  require 'active_model_serializers'
6
8
 
7
9
  module Parse