parse-stack 1.5.2 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
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;