built.io 0.7 → 0.8

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.
data/lib/built/object.rb CHANGED
@@ -25,7 +25,7 @@ module Built
25
25
 
26
26
  instantiate(
27
27
  Built.client.request(uri)
28
- .parsed_response["object"]
28
+ .json["object"]
29
29
  )
30
30
 
31
31
  self
@@ -35,27 +35,34 @@ module Built
35
35
  # @param [Hash] options Options
36
36
  # @option options [Boolean] :timeless Perform a timeless update
37
37
  # @option options [Boolean] :draft Save the object as draft
38
+ # @option options [Boolean] :include_owner Include the owner of the object in the response
39
+ # @option options [Boolean] :include Include a reference field in the response
38
40
  # @raise BuiltAPIError
39
41
  # @return [Object] self
40
42
  def save(options={})
43
+ headers = {}
44
+ query = {}
45
+ unpublish if options[:draft]
46
+ query[:include_owner] = true if options[:include_owner]
47
+ query[:include] = options[:include] if options[:include]
48
+
41
49
  if is_new?
42
50
  # create
43
51
  instantiate(
44
- Built.client.request(uri, :post, wrap)
45
- .parsed_response["object"]
52
+ Built.client.request(uri, :post, wrap, nil, headers)
53
+ .json["object"]
46
54
  )
47
55
  else
48
- headers = {}
49
-
50
56
  headers[:timeless] = true if options[:timeless]
51
- self["published"] = false if options[:draft]
52
57
 
53
58
  # update
54
59
  instantiate(
55
60
  Built.client.request(uri, :put, wrap, nil, headers)
56
- .parsed_response["object"]
61
+ .json["object"]
57
62
  )
58
63
  end
64
+
65
+ self
59
66
  end
60
67
 
61
68
  # Delete this object
@@ -80,27 +87,294 @@ module Built
80
87
  Built::Class.get(@class_uid)
81
88
  end
82
89
 
90
+ # Assign references based on a condition
91
+ # Searches for objects in the referred class and adds them as references
92
+ # @param [String] path The reference field
93
+ # @param [Query] query The query to apply when searching
94
+ # @return [Object] self
95
+ def set_reference_where(path, query)
96
+ Util.type_check("path", path, String)
97
+ Util.type_check("query", query, Query)
98
+
99
+ self[path] = {
100
+ "WHERE" => query.params["query"]
101
+ }
102
+
103
+ self
104
+ end
105
+
106
+ # Set reference for a field
107
+ # The reference parameter can be an existing uid, an existing object,
108
+ # or a new object. New objects will be created inline before being assigned
109
+ # as references.
110
+ # @param [String] path The path of the reference
111
+ # @param [String, Object, Array<String>, Array<Object>] value The value to assign
112
+ def set_reference(path, value)
113
+ Util.type_check("path", path, String)
114
+ value = value.is_a?(Array) ? value : [value]
115
+
116
+ self[path] = value.map do |val|
117
+ case val.class
118
+ when String
119
+ val
120
+ when Built::Object
121
+ val.is_new? ? val : val.uid
122
+ else
123
+ nil
124
+ end
125
+ end.compact!
126
+
127
+ self
128
+ end
129
+
130
+ # Decrement the value of a number field by the given number
131
+ # @param [String] path The number field
132
+ # @param [Fixnum] number The number to decrement
133
+ # @return [Object] self
134
+ def decrement(path, number=nil)
135
+ Util.type_check("path", path, String)
136
+ Util.type_check("number", number, Fixnum) if number
137
+
138
+ self[path] = {
139
+ "SUB" => number || 1
140
+ }
141
+
142
+ self
143
+ end
144
+
145
+ # Increment the value of a number field by the given number
146
+ # @param [String] path The number field
147
+ # @param [Fixnum] number The number to increment
148
+ # @return [Object] self
149
+ def increment(path, number=nil)
150
+ Util.type_check("path", path, String)
151
+ Util.type_check("number", number, Fixnum) if number
152
+
153
+ self[path] = {
154
+ "ADD" => number || 1
155
+ }
156
+
157
+ self
158
+ end
159
+
160
+ # Multiply the value of a number field by the given number
161
+ # @param [String] path The number field
162
+ # @param [Fixnum] number The number to multiply with
163
+ # @return [Object] self
164
+ def multiply(path, number)
165
+ Util.type_check("path", path, String)
166
+ Util.type_check("number", number, Fixnum)
167
+
168
+ self[path] = {
169
+ "MUL" => number
170
+ }
171
+
172
+ self
173
+ end
174
+
175
+ # Divide the value of a number field by the given number
176
+ # @param [String] path The number field
177
+ # @param [Fixnum] number The number to divide with
178
+ # @return [Object] selfs
179
+ def divide(path, number)
180
+ Util.type_check("path", path, String)
181
+ Util.type_check("number", number, Fixnum)
182
+
183
+ self[path] = {
184
+ "DIV" => number
185
+ }
186
+
187
+ self
188
+ end
189
+
190
+ # Update value at the given index for a multiple field
191
+ # @param [String] path The field name on which the operation is to be applied
192
+ # @param [#read] value Update the field with this value
193
+ # @param [Fixnum] index
194
+ # @return [Object] self
195
+ def update_value(path, value, index)
196
+ # TODO: convert these into operations that are transparently executed on save
197
+ # The user should be able to access the values transparently.
198
+ Util.type_check("path", path, String)
199
+ Util.type_check("index", index, Fixnum)
200
+
201
+ self[path] = {
202
+ "UPDATE" => {
203
+ "data" => value,
204
+ "index" => index
205
+ }
206
+ }
207
+
208
+ self
209
+ end
210
+
211
+ # Pull value from a multiple field
212
+ # @param [String] path The field name on which the operation is to be applied
213
+ # @param [#read] value Pull a certain value from the field
214
+ # @param [Fixnum] index Pull a certain index from the field
215
+ # @return [Object] self
216
+ def pull_value(path, value=nil, index=nil)
217
+ Util.type_check("path", path, String)
218
+ Util.type_check("index", index, Fixnum) if index
219
+
220
+ if value
221
+ value = value.is_a?(Array) ? value : [value]
222
+
223
+ self[path] = {
224
+ "PULL" => {
225
+ "data" => value
226
+ }
227
+ }
228
+ elsif index
229
+ self[path] = {
230
+ "PULL" => {
231
+ "index" => index
232
+ }
233
+ }
234
+ else
235
+ raise BuiltError, I18n.t("objects.pull_require")
236
+ end
237
+
238
+ self
239
+ end
240
+
241
+ # Push value into a multiple field
242
+ # @param [String] path The field name on which the operation is to be applied
243
+ # @param [#read] value Any value you wish to push
244
+ # @param [Fixnum] index The index at which to push
245
+ # @return [Object] self
246
+ def push_value(path, value, index=nil)
247
+ # TODO: also handle ability to push at nested multiples
248
+ Util.type_check("path", path, String)
249
+ Util.type_check("index", index, Fixnum) if index
250
+
251
+ value = value.is_a?(Array) ? value : [value]
252
+
253
+ self[path] = {
254
+ "PUSH" => {
255
+ "data" => value
256
+ }
257
+ }
258
+
259
+ if index
260
+ self[path]["PUSH"]["index"] = index
261
+ end
262
+
263
+ self
264
+ end
265
+
266
+ # Get the location object for this object
267
+ # @return [Location]
268
+ def location
269
+ loc = self[Built::LOCATION_PATH]
270
+ if loc
271
+ Location.new(loc[0], loc[1])
272
+ else
273
+ nil
274
+ end
275
+ end
276
+
277
+ # Set the location
278
+ # @param [Location] loc The location object to set
279
+ def location=(loc)
280
+ Util.type_check("loc", loc, Location)
281
+
282
+ self[Built::LOCATION_PATH] = loc.to_arr
283
+
284
+ self
285
+ end
286
+
287
+ # Get ACL
288
+ # @return [ACL]
289
+ def ACL
290
+ Built::ACL.new(self["ACL"])
291
+ end
292
+
293
+ # Set ACL
294
+ # @param [ACL] acl
295
+ # @return [Object] self
296
+ def ACL=(acl)
297
+ self["ACL"] = {
298
+ "disable" => acl.disabled,
299
+ "others" => acl.others,
300
+ "users" => acl.users,
301
+ "roles" => acl.roles
302
+ }
303
+
304
+ self
305
+ end
306
+
307
+ # Get the version this object is on
308
+ def version
309
+ self["_version"]
310
+ end
311
+
312
+ # Unpublish this object
313
+ # @return [Object] self
314
+ def unpublish
315
+ self["published"] = false
316
+ self
317
+ end
318
+
319
+ # Publish this object
320
+ # @return [Object] self
321
+ def publish
322
+ self["published"] = true
323
+ self
324
+ end
325
+
326
+ # Is this object published?
327
+ # @return [Boolean]
328
+ def is_published?
329
+ self["published"]
330
+ end
331
+
332
+ # Get tags for this object
333
+ def tags
334
+ self["tags"] || []
335
+ end
336
+
337
+ # Add new tags
338
+ # @param [Array<String>] tags An array of strings. Can also be a single tag.
339
+ # @return [Object] self
340
+ def add_tags(tags)
341
+ tags = tags.is_a?(Array) ? tags : [tags]
342
+ self["tags"] ||= []
343
+ self["tags"].concat(tags)
344
+ self
345
+ end
346
+
347
+ # Remove tags
348
+ # @param [Array<String>] tags An array of strings. Can also be a single tag.
349
+ # @return [Object] self
350
+ def remove_tags(tags)
351
+ tags = tags.is_a?(Array) ? tags : [tags]
352
+ self["tags"] ||= []
353
+ self["tags"] = self["tags"] - tags
354
+ self
355
+ end
83
356
 
84
357
  # Is this a new, unsaved object?
85
358
  # @return [Boolean]
86
359
  def is_new?
87
- Util.blank?(self["uid"])
360
+ Util.blank?(uid)
88
361
  end
89
362
 
90
363
  # Initialize a new object
91
364
  # @param [String] class_uid The uid of the class to which this object belongs
92
- # @param [Hash] data Data to initialize the object with
93
- def initialize(class_uid, data=nil)
365
+ # @param [String] uid The uid of an existing object, if this is an existing object
366
+ def initialize(class_uid, uid=nil)
94
367
  if !class_uid
95
368
  raise BuiltError, I18n.t("objects.class_uid")
96
369
  end
97
370
 
98
371
  @class_uid = class_uid
99
372
 
100
- if data
101
- instantiate(data)
373
+ if uid
374
+ self.uid = uid
102
375
  end
103
376
 
377
+ clean_up!
104
378
  self
105
379
  end
106
380
 
@@ -131,6 +405,7 @@ module Built
131
405
  end
132
406
 
133
407
  class << self
408
+ # @api private
134
409
  def instantiate(data)
135
410
  doc = new
136
411
  doc.instantiate(data)
data/lib/built/query.rb CHANGED
@@ -24,136 +24,196 @@ module Built
24
24
  }
25
25
  end
26
26
 
27
- # Where given key matches value
28
- # @param [String] key The key on which to search
27
+ # Where given field matches value
28
+ # @param [String] field The field on which to search
29
29
  # @param [Object] value The value with which to match
30
30
  # @return [Query] self
31
- def where(key, value)
32
- @params["query"][key] = value
31
+ def where(field, value)
32
+ @params["query"][field] = value
33
33
 
34
34
  self
35
35
  end
36
36
 
37
- # To check that the key has a value greater than the one specified
38
- # @param [String] key The key
37
+ # To check that the field has a value greater than the one specified
38
+ # @param [String] field The field
39
39
  # @param [Object] value The value
40
40
  # @return [Query] self
41
- def greater_than(key, value)
42
- @params["query"][key] = {"$gt" => value}
41
+ def greater_than(field, value)
42
+ @params["query"][field] = {"$gt" => value}
43
43
 
44
44
  self
45
45
  end
46
46
 
47
- # To check that the key has a value greater than OR equaling the one specified
48
- # @param [String] key The key
47
+ # To check that the field has a value greater than OR equaling the one specified
48
+ # @param [String] field The field
49
49
  # @param [Object] value The value
50
50
  # @return [Query] self
51
- def greater_than_equal(key, value)
52
- @params["query"][key] = {"$gte" => value}
51
+ def greater_than_equal(field, value)
52
+ @params["query"][field] = {"$gte" => value}
53
53
 
54
54
  self
55
55
  end
56
56
 
57
- # To check that the key has a value less than the one specified
58
- # @param [String] key The key
57
+ # To check that the field has a value less than the one specified
58
+ # @param [String] field The field
59
59
  # @param [Object] value The value
60
60
  # @return [Query] self
61
- def less_than(key, value)
62
- @params["query"][key] = {"$lt" => value}
61
+ def less_than(field, value)
62
+ @params["query"][field] = {"$lt" => value}
63
63
 
64
64
  self
65
65
  end
66
66
 
67
- # To check that the key has a value less than OR equaling the one specified
68
- # @param [String] key The key
67
+ # To check that the field has a value less than OR equaling the one specified
68
+ # @param [String] field The field
69
69
  # @param [Object] value The value
70
70
  # @return [Query] self
71
- def less_than_equal(key, value)
72
- @params["query"][key] = {"$lte" => value}
71
+ def less_than_equal(field, value)
72
+ @params["query"][field] = {"$lte" => value}
73
73
 
74
74
  self
75
75
  end
76
76
 
77
- # To check that the key has a value not equaling the one specified
78
- # @param [String] key The key
77
+ # To check that the field has a value not equaling the one specified
78
+ # @param [String] field The field
79
79
  # @param [Object] value The value
80
80
  # @return [Query] self
81
- def not_equal(key, value)
82
- @params["query"][key] = {"$ne" => value}
81
+ def not_equal(field, value)
82
+ @params["query"][field] = {"$ne" => value}
83
83
 
84
84
  self
85
85
  end
86
86
 
87
- # Sort results in ascending order for the given key
88
- # @param [String] key The key by which to sort
87
+ # Sort results in ascending order for the given field
88
+ # @param [String] field The field by which to sort
89
89
  # @return [Query] self
90
- def ascending(key)
91
- @params["asc"] = key
90
+ def ascending(field)
91
+ @params["asc"] = field
92
92
 
93
93
  self
94
94
  end
95
95
 
96
- # Sort results in descending order for the given key
97
- # @param [String] key The key by which to sort
96
+ # Sort results in descending order for the given field
97
+ # @param [String] field The field by which to sort
98
98
  # @return [Query] self
99
- def descending(key)
100
- @params["desc"] = key
99
+ def descending(field)
100
+ @params["desc"] = field
101
101
 
102
102
  self
103
103
  end
104
104
 
105
- # To check that the value for a key is contained in a given array
106
- # @param [String] key The key to check
105
+ # To check that the value for a field is contained in a given array
106
+ # @param [String] field The field to check
107
107
  # @param [Array] array An array of values
108
108
  # @return [Query] self
109
- def contained_in(key, array)
110
- @params["query"][key] = {"$in" => array}
109
+ def contained_in(field, array)
110
+ @params["query"][field] = {"$in" => array}
111
111
 
112
112
  self
113
113
  end
114
114
 
115
- # To check that the value for a key is NOT contained in a given array
116
- # @param [String] key The key to check
115
+ # To check that the value for a field is NOT contained in a given array
116
+ # @param [String] field The field to check
117
117
  # @param [Array] array An array of values
118
118
  # @return [Query] self
119
- def not_contained_in(key, array)
120
- @params["query"][key] = {"$nin" => array}
119
+ def not_contained_in(field, array)
120
+ @params["query"][field] = {"$nin" => array}
121
121
 
122
122
  self
123
123
  end
124
124
 
125
- # To check that the given key exists
126
- # @param [String] key
125
+ # To check that the given field exists
126
+ # @param [String] field
127
127
  # @return [Query] self
128
- def exists(key)
129
- @params["query"][key] = {"$exists" => true}
128
+ def exists(field)
129
+ @params["query"][field] = {"$exists" => true}
130
130
 
131
131
  self
132
132
  end
133
133
 
134
- # To check that the given key does not exist
135
- # @param [String] key
134
+ # To check that the given field does not exist
135
+ # @param [String] field
136
136
  # @return [Query] self
137
- def not_exists(key)
138
- @params["query"][key] = {"$exists" => false}
137
+ def not_exists(field)
138
+ @params["query"][field] = {"$exists" => false}
139
139
 
140
140
  self
141
141
  end
142
142
 
143
143
  # Reference query a field
144
- # @param [String] key
144
+ # @param [String] field
145
145
  # @param [Query] query
146
- def in_query(key, query)
147
- @params["query"][key] = {"$in_query" => query.params["query"]}
146
+ def in_query(field, query)
147
+ @params["query"][field] = {"$in_query" => query.params["query"]}
148
148
 
149
149
  self
150
150
  end
151
151
 
152
152
  # Reference query a field negatively
153
- # @param [String] key
153
+ # @param [String] field
154
154
  # @param [Query] query
155
- def not_in_query(key, query)
156
- @params["query"][key] = {"$nin_query" => query.params["query"]}
155
+ def not_in_query(field, query)
156
+ @params["query"][field] = {"$nin_query" => query.params["query"]}
157
+
158
+ self
159
+ end
160
+
161
+ # Select query a field for arbitrary references
162
+ # @param [String] field The field to query
163
+ # @param [String] class_uid of the class to query
164
+ # @param [String] key to match
165
+ # @param [Query] query to execute on the class
166
+ def select_query(field, class_uid, key, query)
167
+ @params["query"][field] = {
168
+ "$select" => {
169
+ "key" => key,
170
+ "class_uid" => class_uid,
171
+ "query" => query
172
+ }
173
+ }
174
+
175
+ self
176
+ end
177
+
178
+ # Select query a field for arbitrary references, negatively
179
+ # @param [String] field The field to query
180
+ # @param [String] class_uid of the class to query
181
+ # @param [String] key to match
182
+ # @param [Query] query to execute on the class
183
+ def dont_select_query(field, class_uid, key, query)
184
+ @params["query"][field] = {
185
+ "$dont_select" => {
186
+ "key" => key,
187
+ "class_uid" => class_uid,
188
+ "query" => query
189
+ }
190
+ }
191
+
192
+ self
193
+ end
194
+
195
+ # Get objects near a Location or an Object.
196
+ # @param [Location, Object] location The location object or a Built::Object
197
+ # @param [Fixnum] radius The radius in meters
198
+ def near(location, radius)
199
+ @params["query"]["$near"] = {
200
+ "coords" => location.is_a?(Built::Location) ? location.to_arr : {
201
+ "object" => location.uid
202
+ },
203
+ "radius" => radius
204
+ }
205
+
206
+ self
207
+ end
208
+
209
+ # Get objects within a set of location points
210
+ # @param [Array<Location, Object>] Set of location points
211
+ def within(points)
212
+ @params["query"]["$within"] = points.map do |point|
213
+ point.is_a?(Built::Location) ? location.to_arr : {
214
+ "object" => location.uid
215
+ }
216
+ end
157
217
 
158
218
  self
159
219
  end
@@ -193,11 +253,11 @@ module Built
193
253
  end
194
254
 
195
255
  # Include reference fields in the response (joins)
196
- # @param [String] key The reference field to include
256
+ # @param [String] field The reference field to include
197
257
  # @return [Query] self
198
- def include(key)
258
+ def include(field)
199
259
  @params["include"] ||= []
200
- @params["include"] << key
260
+ @params["include"] << field
201
261
 
202
262
  self
203
263
  end
@@ -236,7 +296,7 @@ module Built
236
296
  uri = Built::Object.uri(@class_uid)
237
297
 
238
298
  QueryResponse.new(
239
- Built.client.request(uri, :get, nil, @params).parsed_response,
299
+ Built.client.request(uri, :get, nil, @params).json,
240
300
  @class_uid
241
301
  )
242
302
  end
@@ -266,8 +326,18 @@ module Built
266
326
  def initialize(response, class_uid)
267
327
  @response = response
268
328
 
329
+ obj_class = Built::Object
330
+ case class_uid
331
+ when Built::USER_CLASS_UID
332
+ obj_class = Built::User
333
+ when Built::ROLE_CLASS_UID
334
+ obj_class = Built::Role
335
+ when Built::INST_CLASS_UID
336
+ obj_class = Built::Installation
337
+ end
338
+
269
339
  if response["objects"].is_a?(Array)
270
- @objects = response["objects"].map {|o| Built::Object.new(class_uid, o)}
340
+ @objects = response["objects"].map {|o| obj_class.new(class_uid).instantiate(o)}
271
341
  else
272
342
  @objects = []
273
343
  @count = response["objects"]
data/lib/built/role.rb ADDED
@@ -0,0 +1,4 @@
1
+ module Built
2
+ class Role < Built::Object
3
+ end
4
+ end