parse-stack 1.5.2 → 1.5.3

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +5 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +40 -80
  5. data/lib/parse/api/all.rb +7 -0
  6. data/lib/parse/api/analytics.rb +8 -3
  7. data/lib/parse/api/apps.rb +29 -1
  8. data/lib/parse/api/batch.rb +14 -129
  9. data/lib/parse/api/cloud_functions.rb +9 -0
  10. data/lib/parse/api/config.rb +10 -1
  11. data/lib/parse/api/files.rb +7 -2
  12. data/lib/parse/api/hooks.rb +45 -2
  13. data/lib/parse/api/objects.rb +43 -6
  14. data/lib/parse/api/push.rb +6 -1
  15. data/lib/parse/api/schemas.rb +15 -1
  16. data/lib/parse/api/sessions.rb +5 -0
  17. data/lib/parse/api/users.rb +64 -5
  18. data/lib/parse/client/authentication.rb +25 -8
  19. data/lib/parse/client/batch.rb +206 -0
  20. data/lib/parse/client/body_builder.rb +12 -6
  21. data/lib/parse/client/caching.rb +42 -10
  22. data/lib/parse/client/protocol.rb +51 -46
  23. data/lib/parse/client/response.rb +1 -47
  24. data/lib/parse/client.rb +171 -42
  25. data/lib/parse/model/acl.rb +184 -39
  26. data/lib/parse/model/associations/belongs_to.rb +1 -0
  27. data/lib/parse/model/classes/role.rb +7 -1
  28. data/lib/parse/model/classes/session.rb +7 -3
  29. data/lib/parse/model/classes/user.rb +107 -0
  30. data/lib/parse/model/core/actions.rb +166 -115
  31. data/lib/parse/model/core/fetching.rb +105 -0
  32. data/lib/parse/model/core/properties.rb +40 -13
  33. data/lib/parse/model/core/querying.rb +123 -39
  34. data/lib/parse/model/core/schema.rb +22 -32
  35. data/lib/parse/model/object.rb +26 -20
  36. data/lib/parse/model/pointer.rb +1 -0
  37. data/lib/parse/query/constraint.rb +65 -27
  38. data/lib/parse/query/constraints.rb +0 -3
  39. data/lib/parse/query/operation.rb +33 -22
  40. data/lib/parse/query/ordering.rb +10 -5
  41. data/lib/parse/stack/generators/rails.rb +5 -1
  42. data/lib/parse/stack/generators/templates/model_installation.rb +1 -1
  43. data/lib/parse/stack/generators/templates/model_role.rb +1 -1
  44. data/lib/parse/stack/generators/templates/model_session.rb +2 -2
  45. data/lib/parse/stack/generators/templates/model_user.rb +1 -1
  46. data/lib/parse/stack/generators/templates/parse.rb +0 -1
  47. data/lib/parse/stack/railtie.rb +1 -0
  48. data/lib/parse/stack/tasks.rb +3 -1
  49. data/lib/parse/stack/version.rb +3 -1
  50. data/lib/parse/webhooks/registration.rb +3 -3
  51. data/lib/parse/webhooks.rb +88 -7
  52. metadata +5 -3
@@ -4,15 +4,62 @@
4
4
  require_relative '../../query'
5
5
 
6
6
  module Parse
7
-
7
+ # Defines the querying methods applied to a Parse::Object.
8
8
  module Querying
9
9
 
10
- def self.included(base)
11
- base.extend(ClassMethods)
12
- end
13
-
14
- module ClassMethods
15
-
10
+ # This feature is a small subset of the
11
+ # {http://guides.rubyonrails.org/active_record_querying.html#scopes
12
+ # ActiveRecord named scopes} feature. Scoping allows you to specify
13
+ # commonly-used queries which can be referenced as class method calls and
14
+ # are chainable with other scopes. You can use every {Parse::Query}
15
+ # method previously covered such as `where`, `includes` and `limit`.
16
+ #
17
+ # class Article < Parse::Object
18
+ # property :published, :boolean
19
+ # scope :published, -> { query(published: true) }
20
+ # end
21
+ #
22
+ # This is the same as defining your own class method for the query.
23
+ #
24
+ # class Article < Parse::Object
25
+ # def self.published
26
+ # query(published: true)
27
+ # end
28
+ # end
29
+ #
30
+ # You can also chain scopes and pass parameters. In addition, boolean and
31
+ # enumerated properties have automatically generated scopes for you to use.
32
+ #
33
+ # class Article < Parse::Object
34
+ # scope :published, -> { query(published: true) }
35
+ #
36
+ # property :comment_count, :integer
37
+ # property :category
38
+ # property :approved, :boolean
39
+ #
40
+ # scope :published_and_commented, -> { published.where :comment_count.gt => 0 }
41
+ # scope :popular_topics, ->(name) { published_and_commented.where category: name }
42
+ # end
43
+ #
44
+ # # simple scope
45
+ # Article.published # => where published is true
46
+ #
47
+ # # chained scope
48
+ # Article.published_and_commented # published is true and comment_count > 0
49
+ #
50
+ # # scope with parameters
51
+ # Article.popular_topic("music") # => popular music articles
52
+ # # equivalent: where(published: true, :comment_count.gt => 0, category: name)
53
+ #
54
+ # # automatically generated scope
55
+ # Article.approved(category: "tour") # => where approved: true, category: 'tour'
56
+ #
57
+ # If you would like to turn off automatic scope generation for property types,
58
+ # set the option `:scope` to false when declaring the property.
59
+ # @param name [Symbol] the name of the scope.
60
+ # @param body [Proc] the proc related to the scope.
61
+ # @raise ArgumentError if body parameter does not respond to `call`
62
+ # @return [Symbol] the name of the singleton method created.
16
63
  def scope(name, body)
17
64
  unless body.respond_to?(:call)
18
65
  raise ArgumentError, 'The scope body needs to be callable.'
@@ -60,33 +107,59 @@ module Parse
60
107
  end
61
108
 
62
109
 
63
- # This query method helper returns a Query object tied to a parse class.
64
- # The parse class should be the name of the one that will be sent in the query
65
- # request pointing to the remote table.
66
-
110
+ # Creates a new {Parse::Query} with the given constraints for this class.
111
+ # @example
112
+ # # assume Post < Parse::Object
113
+ # query = Post.query(:updated_at.before => DateTime.now)
114
+ # @return [Parse::Query] a new query with the given constraints for this
115
+ # Parse::Object subclass.
67
116
  def query(constraints = {})
68
117
  Parse::Query.new self.parse_class, constraints
69
118
  end; alias_method :where, :query
70
119
 
71
- def literal_where(clauses = {})
72
- query.where(clauses)
120
+ # @param conditions (see Parse::Query#where)
121
+ # @return (see Parse::Query#where)
122
+ # @see Parse::Query#where
123
+ def literal_where(conditions = {})
124
+ query.where(conditions)
73
125
  end
74
126
 
75
- # Most common method to use when querying a class. This takes a hash of constraints
76
- # and conditions and returns the results.
77
-
78
- def all(constraints = {})
79
- constraints = {limit: :max}.merge(constraints)
127
+ # Fetch all matching objects in this collection matching the constraints.
128
+ # This will be the most common way when querying Parse objects for a subclass.
129
+ # When no block is passed, all objects are returned. Using a block is more memory
130
+ # efficient as matching objects are fetched in batches and discarded after the iteration
131
+ # is completed.
132
+ # @param constraints [Hash] a set of {Parse::Query} constraints.
133
+ # @yield a block to iterate with each matching object.
134
+ # @example
135
+ #
136
+ # songs = Song.all( ... expressions ...) # => array of Parse::Objects
137
+ # # memory efficient for large amounts of records.
138
+ # Song.all( ... expressions ...) do |song|
139
+ # # ... do something with song..
140
+ # end
141
+ #
142
+ # @return [Array<Parse::Object>] an array of matching objects. If a block is passed,
143
+ # an empty array is returned.
144
+ def all(constraints = {limit: :max})
145
+ constraints = constraints.reverse_merge({limit: :max})
80
146
  prepared_query = query(constraints)
81
147
  return prepared_query.results(&Proc.new) if block_given?
82
148
  prepared_query.results
83
149
  end
84
150
 
85
- # returns the first item matching the constraint. If constraint parameter is numeric,
86
- # then we treat it as a count.
87
- # Ex. Object.first( :name => "Anthony" ) (returns single object)
88
- # Ex. Object.first(3) # first 3 objects (array of 3 objects)
89
-
151
+ # Returns the first item matching the constraint.
152
+ # @overload first(count = 1)
153
+ # @param count [Interger] The number of items to return.
154
+ # @example
155
+ # Object.first(2) # => an array of the first 2 objects in the collection.
156
+ # @return [Parse::Object] if count == 1
157
+ # @return [Array<Parse::Object>] if count > 1
158
+ # @overload first(constraints = {})
159
+ # @param constraints [Hash] a set of {Parse::Query} constraints.
160
+ # @example
161
+ # Object.first( :name => "Anthony" )
162
+ # @return [Parse::Object] the first matching object.
90
163
  def first(constraints = {})
91
164
  fetch_count = 1
92
165
  if constraints.is_a?(Numeric)
@@ -99,12 +172,20 @@ module Parse
99
172
  return res.first fetch_count
100
173
  end
101
174
 
102
- # creates a count request (which is more performant when counting objects)
103
-
175
+ # Creates a count request which is more performant when counting objects.
176
+ # @example
177
+ # # number of songs with a like count greater than 20.
178
+ # count = Song.count( :like_count.gt => 20 )
179
+ # @param constraints (see #all)
180
+ # @return [Interger] the number of records matching the query.
181
+ # @see Parse::Query#count
104
182
  def count(constraints = {})
105
183
  query(constraints).count
106
184
  end
107
185
 
186
+ # Find objects matching the constraint ordered by the descending created_at date.
187
+ # @param constraints (see #all)
188
+ # @return [Array<Parse::Object>]
108
189
  def newest(constraints = {})
109
190
  constraints.merge!(order: :created_at.desc)
110
191
  _q = query(constraints)
@@ -112,6 +193,9 @@ module Parse
112
193
  _q
113
194
  end
114
195
 
196
+ # Find objects matching the constraint ordered by the ascending created_at date.
197
+ # @param constraints (see #all)
198
+ # @return [Array<Parse::Object>]
115
199
  def oldest(constraints = {})
116
200
  constraints.merge!(order: :created_at.asc)
117
201
  _q = query(constraints)
@@ -119,18 +203,20 @@ module Parse
119
203
  _q
120
204
  end
121
205
 
122
- # Find objects based on objectIds. The result is a list (or single item) of the
123
- # objects that were successfully found.
124
- # Example:
125
- # Object.find "<objectId>"
126
- # Object.find "<objectId>", "<objectId>"....
127
- # Object.find ["<objectId>", "<objectId>"]
128
- # Additional named parameters:
129
- # type: - :parrallel by default - makes all find requests in parallel vs serial.
130
- # :batch - makes a single query request for all objects with a "contained in" query.
131
- # compact: - true by default, removes any nil values from the array as it is potential
132
- # that an object with a specified ID does not exist.
133
-
206
+ # Find objects for a given objectId in this collection.The result is a list
207
+ # (or single item) of the objects that were successfully found.
208
+ # @example
209
+ # Object.find "<objectId>"
210
+ # Object.find "<objectId>", "<objectId>"....
211
+ # Object.find ["<objectId>", "<objectId>"]
212
+ # @param parse_ids [String] the objectId to find.
213
+ # @param type [Symbol] the fetching methodology to use if more than one id was passed.
214
+ # - *:parallel* : Utilizes parrallel HTTP requests to fetch all objects requested.
215
+ # - *:batch* : This uses a batch fetch request using a contained_in clause.
216
+ # @param compact [Boolean] whether to remove nil items from the returned array for objects
217
+ # that were not found.
218
+ # @return [Parse::Object] if only one id was provided as a parameter.
219
+ # @return [Array<Parse::Object>] if more than one id was provided as a parameter.
134
220
  def find(*parse_ids, type: :parallel, compact: true)
135
221
  # flatten the list of Object ids.
136
222
  parse_ids.flatten!
@@ -160,8 +246,6 @@ module Parse
160
246
  as_array ? results : results.first
161
247
  end; alias_method :get, :find
162
248
 
163
- end # ClassMethods
164
-
165
249
  end # Querying
166
250
 
167
251
 
@@ -4,24 +4,12 @@
4
4
  require_relative "properties"
5
5
 
6
6
  module Parse
7
- # Upgrade all
8
- def self.auto_upgrade!
9
- klassModels = Parse::Object.descendants
10
- klassModels.sort_by { |c| c.parse_class }.each do |klass|
11
- yield(klass) if block_given?
12
- klass.auto_upgrade!
13
- end
14
- end
15
-
7
+ # Defines the Schema methods applied to a Parse::Object.
16
8
  module Schema
17
9
 
18
- def self.included(base)
19
- base.extend(ClassMethods)
20
- end
21
-
22
- module ClassMethods
23
-
24
- # returns the schema of the defined class in the Parse JSON format.
10
+ # Generate a Parse-server compatible schema hash for performing changes to the
11
+ # structure of the remote collection.
12
+ # @return [Hash] the schema for this Parse::Object subclass.
25
13
  def schema
26
14
  sch = { className: parse_class, fields: {} }
27
15
  #first go through all the attributes
@@ -54,25 +42,36 @@ module Parse
54
42
  sch
55
43
  end
56
44
 
57
- # updates the remote schema using Parse::Client
45
+ # Update the remote schema for this Parse collection.
46
+ # @param schema_updates [Hash] the changes to be made to the schema.
47
+ # @return [Parse::Response]
58
48
  def update_schema(schema_updates = nil)
59
49
  schema_updates ||= schema
60
50
  client.update_schema parse_class, schema_updates
61
51
  end
62
52
 
53
+ # Create a new collection for this model with the schema defined by the local
54
+ # model.
55
+ # @return [Parse::Response]
56
+ # @see Schema.schema
63
57
  def create_schema
64
58
  client.create_schema parse_class, schema
65
59
  end
66
60
 
67
- # fetches the current schema of this table.
61
+ # Fetche the current schema for this collection from Parse server.
62
+ # @return [Parse::Response]
68
63
  def fetch_schema
69
64
  client.schema parse_class
70
65
  end
71
66
 
72
- # A class method for non-destructive auto upgrading a remote schema based on the properties
73
- # and relations you have defined. If the table doesn't exist, we create the schema
74
- # from scratch - otherwise we fetched the current schema, calculate the differences
75
- # and add the missing columns. WE DO NOT REMOVE any columns.
67
+ # A class method for non-destructive auto upgrading a remote schema based
68
+ # on the properties and relations you have defined in your local model. If
69
+ # the collection doesn't exist, we create the schema. If the collection already
70
+ # exists, the current schema is fetched, and only add the additional fields
71
+ # that are missing.
72
+ # @note No columns or fields are removed, this is a safe non-destructive upgrade.
73
+ # @return [Parse::Response] if the remote schema was modified.
74
+ # @return [Boolean] if no changes were made to the schema, it returns true.
76
75
  def auto_upgrade!
77
76
  response = fetch_schema
78
77
  if response.success?
@@ -86,18 +85,9 @@ module Parse
86
85
  end
87
86
  return true if current_schema[:fields].empty?
88
87
  return update_schema( current_schema )
89
- else
90
- return create_schema
91
88
  end
92
- #fetch_schema.success? ? update_schema : create_schema
89
+ create_schema
93
90
  end
94
- #def diff(h2);self.dup.delete_if { |k, v| h2[k] == v }.merge(h2.dup.delete_if { |k, v| self.has_key?(k) }); end;
95
-
96
- end
97
-
98
- def schema
99
- self.class.schema
100
- end
101
91
 
102
92
  end
103
93
  end
@@ -21,6 +21,7 @@ require_relative "date"
21
21
  require_relative "acl"
22
22
  require_relative "push"
23
23
  require_relative 'core/actions'
24
+ require_relative 'core/fetching'
24
25
  require_relative 'core/querying'
25
26
  require_relative "core/schema"
26
27
  require_relative "core/properties"
@@ -32,7 +33,17 @@ require_relative "associations/has_many"
32
33
  module Parse
33
34
  # @return [Array] an array of registered Parse::Object subclasses.
34
35
  def self.registered_classes
35
- Parse::Object.descendants.map { |m| m.parse_class }.uniq
36
+ Parse::Object.descendants.map(&:parse_class).uniq
37
+ end
38
+
39
+ # Perform a non-destructive upgrade of all your Parse schemas in the backend
40
+ # based on the property definitions of your local {Parse::Object} subclasses.
41
+ def self.auto_upgrade!
42
+ klassModels = Parse::Object.descendants
43
+ klassModels.sort_by(&:parse_class).each do |klass|
44
+ yield(klass) if block_given?
45
+ klass.auto_upgrade!
46
+ end
36
47
  end
37
48
 
38
49
  # This is the core class for all app specific Parse table subclasses. This class
@@ -53,10 +64,8 @@ module Parse
53
64
  # Properties:
54
65
  #
55
66
  # All columns in a Parse object are considered a type of property (ex. string, numbers, arrays, etc)
56
- # except in two cases - Pointers and Relations. For the list of basic supported data types, please see the
57
- # Properties module variable Parse::Properties::TYPES . When defining a property,
58
- # dynamic methods are created that take advantage of all the ActiveModel
59
- # plugins (dirty tracking, callbacks, json, etc).
67
+ # except in two cases - Pointers and Relations. For a detailed discussion of properties, see
68
+ # The {https://github.com/modernistik/parse-stack#defining-properties Defining Properties} section.
60
69
  #
61
70
  # Associations:
62
71
  #
@@ -74,27 +83,18 @@ module Parse
74
83
  # without requiring an explicit intermediary Parse table or class. This feature
75
84
  # is also implemented using the `:has_many` method but passing the option of `:relation`.
76
85
  #
77
- #
78
- # Querying:
79
- # The querying module provides all the general methods to be able to find and query a specific
80
- # Parse table.
81
- #
82
- # Fetching:
83
- # The fetching modules supports fetching data from Parse (depending on the state of the object),
84
- # and providing some autofetching features when traversing relational objects and properties.
85
- #
86
- # Schema:
87
- # The schema module provides methods to modify the Parse table remotely to either add or create
88
- # any locally define properties in ruby and have those be reflected in the Parse application.
86
+ # @see Associations::BelongsTo
87
+ # @see Associations::HasOne
88
+ # @see Associations::HasMany
89
89
  class Object < Pointer
90
90
  include Properties
91
91
  include Associations::HasOne
92
92
  include Associations::BelongsTo
93
93
  include Associations::HasMany
94
- include Querying
94
+ extend Querying
95
+ extend Schema
95
96
  include Fetching
96
97
  include Actions
97
- include Schema
98
98
  BASE_OBJECT_CLASS = "Parse::Object".freeze
99
99
 
100
100
  # @return [Model::TYPE_OBJECT]
@@ -145,7 +145,7 @@ module Parse
145
145
 
146
146
  attr_accessor :disable_serialized_string_date, :parse_class, :acl
147
147
 
148
- # @!attribute [rw] disable_serialized_string_date
148
+ # @!attribute disable_serialized_string_date
149
149
  # Disables returning a serialized string date properties when encoding to JSON.
150
150
  # This affects created_at and updated_at fields in order to be backwards compatible with old SDKs.
151
151
  # @return [Boolean]
@@ -191,6 +191,12 @@ module Parse
191
191
  end
192
192
  alias_method :className, :parse_class
193
193
 
194
+ # @return [Hash] the schema structure for this Parse collection from the server.
195
+ # @see Parse::Schema
196
+ def schema
197
+ self.class.schema
198
+ end
199
+
194
200
  # @return [Hash] a json-hash representing this object.
195
201
  def as_json(*args)
196
202
  pointer? ? pointer : super(*args)
@@ -65,6 +65,7 @@ module Parse
65
65
  #
66
66
  # @see Parse::Object
67
67
  class Pointer < Model
68
+ # Attributes of a Pointer.
68
69
  ATTRIBUTES = { __type: :string, className: :string, objectId: :string}.freeze
69
70
  # @return [String] the name of the Parse class for this pointer.
70
71
  attr_accessor :parse_class
@@ -3,23 +3,35 @@
3
3
 
4
4
  require_relative 'operation'
5
5
  require 'time'
6
- # Constraints are the heart of the Parse::Query system.
7
- # Each constraint is made up of an Operation and a value (the right side
8
- # of an operator). Constraints are responsible for making their specific
9
- # Parse hash format required when sending Queries to Parse. All constraints can
10
- # be combined by merging different constraints (since they are multiple hashes)
11
- # and some constraints may have higher precedence than others (ex. equality is higher
12
- # precedence than an "in" query).
13
- # All constraints should inherit from Parse::Constraint and should
14
- # register their specific Operation method (ex. :eq or :lte)
15
- # For more information about the query design pattern from DataMapper
16
- # that inspired this, see http://datamapper.org/docs/find.html
6
+
17
7
  module Parse
8
+ # Constraints are the heart of the Parse::Query system.
9
+ # Each constraint is made up of an Operation and a value (the right side
10
+ # of an operator). Constraints are responsible for making their specific
11
+ # Parse hash format required when sending Queries to Parse. All constraints can
12
+ # be combined by merging different constraints (since they are multiple hashes)
13
+ # and some constraints may have higher precedence than others (ex. equality is higher
14
+ # precedence than an "in" query).
15
+ # All constraints should inherit from Parse::Constraint and should
16
+ # register their specific Operation method (ex. :eq or :lte)
17
+ # For more information about the query design pattern from DataMapper
18
+ # that inspired this, see http://datamapper.org/docs/find.html
18
19
  class Constraint
19
20
 
21
+ # @!attribute operation
22
+ # The operation tied to this constraint.
23
+ # @return [Parse::Operation]
24
+
25
+ # @!attribute value
26
+ # The value to be applied to this constraint.
27
+ # @return [Parse::Operation]
28
+
20
29
  attr_accessor :operation, :value
21
- # A constraint needs an operation and a value.
22
- # You may also pass a block to modify the operation if needed
30
+
31
+ # Create a new constraint.
32
+ # @param operation [Parse::Operation] the operation for this constraint.
33
+ # @param value [Object] the value to attach to this constraint.
34
+ # @yield You may also pass a block to modify the operation or value.
23
35
  def initialize(operation, value)
24
36
  # if the first parameter is not an Operation, but it is a symbol
25
37
  # it most likely is just the field name, so let's assume they want
@@ -34,16 +46,22 @@ module Parse
34
46
  end
35
47
 
36
48
  class << self
49
+ # @!attribute key
37
50
  # The class attributes keep track of the Parse key (special Parse
38
51
  # text symbol representing this operation. Ex. local method could be called
39
52
  # .ex, where the Parse Query operation that should be sent out is "$exists")
40
53
  # in this case, key should be set to "$exists"
54
+ # @return [Symbol]
41
55
  attr_accessor :key
56
+
57
+ # @!attribute precedence
42
58
  # Precedence defines the priority of this operation when merging.
43
59
  # The higher the more priority it will receive.
60
+ # @return [Integer]
44
61
  attr_accessor :precedence
45
62
 
46
- # Class access to store the default symbol operand action
63
+ # @!attribute operand
64
+ # @return [Symbol] the operand for this constraint.
47
65
  attr_accessor :operand
48
66
 
49
67
  # Creates a new constraint given an operation and value.
@@ -55,24 +73,33 @@ module Parse
55
73
  operation.constraint(value)
56
74
  end
57
75
 
58
- # method to set the keyword for this Constaint (subclasses)
59
- def contraint_keyword(k)
60
- @key = k
76
+ # Set the keyword for this Constaint. Subclasses should use this method.
77
+ # @param keyword [Symbol]
78
+ # @return (see key)
79
+ def contraint_keyword(keyword)
80
+ @key = keyword
61
81
  end
62
82
 
63
- def precedence(v = nil)
83
+ # Set the default precedence for this constraint.
84
+ # @param priority [Integer] a higher priority has higher precedence
85
+ # @return [Integer]
86
+ def precedence(priority = nil)
64
87
  @precedence = 0 if @precedence.nil?
65
- @precedence = v unless v.nil?
88
+ @precedence = priority unless priority.nil?
66
89
  @precedence
67
90
  end
68
91
 
69
- # All subclasses should register their operation and themselves
70
- # as the handler.
92
+ # Register the given operand for this Parse::Constraint subclass.
93
+ # @note All subclasses should register their operation and themselves.
94
+ # @param op [Symbol] the operand
95
+ # @param klass [Parse::Constraint] a subclass of Parse::Constraint
96
+ # @return (see Parse::Operation.register)
71
97
  def register(op, klass = self)
72
98
  self.operand ||= op
73
99
  Operation.register op, klass
74
100
  end
75
101
 
102
+ # @return [Object] a formatted value based on the data type.
76
103
  def formatted_value(value)
77
104
  d = value
78
105
  d = { __type: "Date", iso: d.utc.iso8601(3) } if d.respond_to?(:utc)
@@ -91,21 +118,28 @@ module Parse
91
118
 
92
119
  end
93
120
 
121
+ # @return [Integer] the precedence of this constraint
94
122
  def precedence
95
123
  self.class.precedence
96
124
  end
97
125
 
126
+ # @return [Symbol] the Parse keyword for this constraint.
98
127
  def key
99
128
  self.class.key
100
129
  end
101
130
 
131
+ # @!attribute operand
132
+ # @return [Symbol] the operand for the operation.
102
133
  def operand
103
134
  @operation.operand unless @operation.nil?
104
135
  end
136
+
105
137
  def operand=(o)
106
138
  @operation.operand = o unless @operation.nil?
107
139
  end
108
140
 
141
+ # @!attribute operator
142
+ # @return [Symbol] the operator for the operation.
109
143
  def operator
110
144
  @operation.operator unless @operation.nil?
111
145
  end
@@ -114,33 +148,37 @@ module Parse
114
148
  @operation.operator = o unless @operation.nil?
115
149
  end
116
150
 
151
+ # @!visibility private
117
152
  def inspect
118
153
  "<#{self.class} #{operator.to_s}(#{operand.inspect}, `#{value}`)>"
119
154
  end
120
155
 
156
+ # Calls build internally
157
+ # @return [Hash]
121
158
  def as_json(*args)
122
159
  build
123
160
  end
124
161
 
125
- # subclasses should override the build method depending on how they
126
- # need to construct the Parse formatted query hash
127
- # The default case below is for supporting equality.
128
- # Before the final value is set int he hash, we call formatted_value in case
129
- # we need to format the value for particular data types.
162
+ # Builds the JSON hash representation of this constraint for a Parse query.
163
+ # This method should be overriden by subclasses. The default implementation
164
+ # implements buildling the equality constraint.
165
+ # @return [Hash]
130
166
  def build
131
167
  return { @operation.operand => formatted_value } if @operation.operator == :eq || key.nil?
132
168
  { @operation.operand => { key => formatted_value } }
133
169
  end
134
170
 
171
+ # @return [String] string representation of this constraint.
135
172
  def to_s
136
173
  inspect
137
174
  end
138
175
 
139
- # This method formats the value based on some specific data types.
176
+ # @return [Object] formatted value based on the specific data type.
140
177
  def formatted_value
141
178
  self.class.formatted_value(@value)
142
179
  end
143
180
 
181
+ # Registers the default constraint of equality
144
182
  register :eq, Constraint
145
183
  precedence 100
146
184
  end
@@ -11,9 +11,6 @@ require_relative 'constraint'
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
13
 
14
-
15
-
16
-
17
14
  module Parse
18
15
  # Error for when there is a problem with the input passed to a constraint.
19
16
  class ConstraintError < StandardError; end;