spiderfw 0.6.23 → 0.6.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/CHANGELOG +10 -1
  2. data/README.rdoc +1 -1
  3. data/VERSION +1 -1
  4. data/apps/config_editor/_init.rb +1 -2
  5. data/apps/config_editor/controllers/config_editor_controller.rb +1 -7
  6. data/apps/core/admin/controllers/admin_controller.rb +1 -1
  7. data/apps/core/admin/public/css/sass/admin.css +35 -31
  8. data/apps/core/admin/public/sass/admin.scss +6 -1
  9. data/apps/core/components/widgets/crud/crud.shtml +2 -2
  10. data/apps/core/components/widgets/table/table.rb +5 -5
  11. data/apps/core/forms/tags/element_row.erb +15 -10
  12. data/apps/core/forms/widgets/form/form.rb +35 -22
  13. data/apps/core/forms/widgets/inputs/checkbox/checkbox.shtml +2 -2
  14. data/apps/core/forms/widgets/inputs/date_time/date_time.shtml +2 -2
  15. data/apps/core/forms/widgets/inputs/file_input/file_input.shtml +2 -2
  16. data/apps/core/forms/widgets/inputs/html_area/html_area.shtml +2 -2
  17. data/apps/core/forms/widgets/inputs/input/input.shtml +2 -2
  18. data/apps/core/forms/widgets/inputs/password/password.shtml +2 -2
  19. data/apps/core/forms/widgets/inputs/search_select/search_select.shtml +1 -1
  20. data/apps/core/forms/widgets/inputs/select/select.shtml +2 -2
  21. data/apps/core/forms/widgets/inputs/text/text.shtml +2 -2
  22. data/apps/core/forms/widgets/inputs/text_area/text_area.shtml +2 -2
  23. data/apps/core/forms/widgets/inputs/time_span/time_span.shtml +1 -1
  24. data/blueprints/home/config.ru +8 -0
  25. data/lib/spiderfw/app.rb +416 -224
  26. data/lib/spiderfw/cmd/commands/app.rb +243 -239
  27. data/lib/spiderfw/cmd/commands/cert.rb +421 -417
  28. data/lib/spiderfw/cmd/commands/config.rb +85 -82
  29. data/lib/spiderfw/cmd/commands/console.rb +64 -40
  30. data/lib/spiderfw/cmd/commands/content.rb +29 -25
  31. data/lib/spiderfw/cmd/commands/create.rb +58 -54
  32. data/lib/spiderfw/cmd/commands/model.rb +118 -114
  33. data/lib/spiderfw/cmd/commands/setup.rb +55 -51
  34. data/lib/spiderfw/cmd/commands/test.rb +63 -59
  35. data/lib/spiderfw/cmd/commands/webserver.rb +56 -51
  36. data/lib/spiderfw/config/options/spider.rb +4 -3
  37. data/lib/spiderfw/controller/controller.rb +2 -0
  38. data/lib/spiderfw/controller/http_controller.rb +1 -2
  39. data/lib/spiderfw/controller/mixins/static_content.rb +3 -3
  40. data/lib/spiderfw/controller/mixins/visual.rb +30 -15
  41. data/lib/spiderfw/controller/response.rb +84 -0
  42. data/lib/spiderfw/controller/session/file_session.rb +2 -2
  43. data/lib/spiderfw/http/adapters/rack.rb +12 -13
  44. data/lib/spiderfw/http/server.rb +80 -46
  45. data/lib/spiderfw/i18n/cldr.rb +6 -9
  46. data/lib/spiderfw/model/base_model.rb +103 -23
  47. data/lib/spiderfw/model/condition.rb +110 -25
  48. data/lib/spiderfw/model/mappers/db_mapper.rb +14 -6
  49. data/lib/spiderfw/model/mappers/mapper.rb +440 -197
  50. data/lib/spiderfw/model/model.rb +105 -21
  51. data/lib/spiderfw/model/model_hash.rb +9 -1
  52. data/lib/spiderfw/model/query.rb +50 -9
  53. data/lib/spiderfw/model/query_set.rb +211 -44
  54. data/lib/spiderfw/model/request.rb +28 -21
  55. data/lib/spiderfw/model/storage/base_storage.rb +125 -10
  56. data/lib/spiderfw/model/storage/db/db_storage.rb +7 -4
  57. data/lib/spiderfw/model/storage.rb +8 -1
  58. data/lib/spiderfw/setup/spider_setup_wizard.rb +9 -7
  59. data/lib/spiderfw/spider.rb +270 -43
  60. data/lib/spiderfw/templates/layout.rb +9 -4
  61. data/lib/spiderfw/templates/resources/sass.rb +3 -2
  62. data/lib/spiderfw/templates/template.rb +1 -0
  63. data/lib/spiderfw/utils/annotations.rb +3 -1
  64. data/lib/spiderfw/utils/logger.rb +1 -1
  65. data/lib/spiderfw/utils/monkey/symbol.rb +4 -2
  66. data/lib/spiderfw/utils/shared_store/file_shared_store.rb +2 -2
  67. data/lib/spiderfw/utils/thread_out.rb +3 -1
  68. data/public/css/error_page.css +83 -0
  69. data/public/js/error_page.js +5 -0
  70. data/spider.gemspec +4 -1
  71. data/templates/email/error.erb +9 -0
  72. metadata +28 -12
  73. data/apps/config_editor/widgets/edit_bool/edit_bool.rb +0 -8
  74. data/apps/config_editor/widgets/edit_bool/edit_bool.shtml +0 -5
@@ -2,37 +2,50 @@ module Spider; module Model
2
2
 
3
3
  # The QuerySet expresses represents a Query applied on a Model.
4
4
  # It includes Enumerable, and can be accessed as an Array; but, the QuerySet is lazy, and the actual data will be
5
- # fetched only when actually requested, or when a #load is issued.
6
- # How much data is fetched and kept in memory can be controlled by setting the #fetch_window
7
- # and the #keep_window.
5
+ # fetched only when actually requested, or when a {#load} is issued.
6
+ # How much data is fetched and kept in memory can be controlled by setting the {#fetch_window}
7
+ # and the {#keep_window}.
8
8
  class QuerySet
9
9
  include Enumerable
10
10
  # BaseModel instance pointing to this QuerySet
11
+ # @return [BaseModel]
11
12
  attr_accessor :_parent
12
13
  # Element inside the _parent pointing to this QuerySet.
14
+ # @return [Element]
13
15
  attr_accessor :_parent_element
14
16
  # Disables parent setting for this QuerySet
17
+ # @return [bool]
15
18
  attr_accessor :_no_parent
16
19
  # Raw data returned by the mapper, if requested.
20
+ # @return [Hash]
17
21
  attr_reader :raw_data
18
22
  # An Hash of autoloaded elements.
23
+ # @return [Hash]
19
24
  attr_reader :loaded_elements
20
25
  # The actual fetched objects.
26
+ # @return [Array]
21
27
  attr_reader :objects
22
28
  # The Query
29
+ # @return [Model::Query]
23
30
  attr_accessor :query
24
31
  # Set by mapper
32
+ # @return [Model::Query]
25
33
  attr_accessor :last_query # :nodoc: TODO: remove?
26
- # The BaseModel
34
+ # The BaseModel subclass
35
+ # @return [Class<BaseModel]
27
36
  attr_accessor :model
28
37
  # Total number of objects present in the Storage for the Query
38
+ # @return [Fixnum]
29
39
  attr_accessor :total_rows
30
- # (bool) Wether the QuerySet has been loaded
40
+ # Whether the QuerySet has been loaded
41
+ # @return [bool]
31
42
  attr_reader :loaded
32
- # (Fixnum) How many objects to load at a time. If nil, all the objects returned by the Query
43
+ # How many objects to load at a time. If nil, all the objects returned by the Query
33
44
  # will be loaded.
45
+ # @return [Fixnum]
34
46
  attr_accessor :fetch_window
35
- # (Fixnum) How many objects to keep in memory when advancing the window. If nil, all objects will be kept.
47
+ # How many objects to keep in memory when advancing the window. If nil, all objects will be kept.
48
+ # @return [Fixnum]
36
49
  attr_accessor :keep_window
37
50
  # If something that can't be converted to a @model instance is appended to the QuerySet,
38
51
  # and append_element is set, the appended value will be set on the element named append_element
@@ -45,29 +58,42 @@ module Spider; module Model
45
58
  # cat.friends << friend
46
59
  # # since the junction was created setting append_element = :other_animal, one can do
47
60
  # cat.friends << lion
61
+ # @return [Element]
48
62
  attr_accessor :append_element
49
- # (bool) If false, prevents the QuerySet from loading.
50
- attr_accessor :loadable # :nodoc: TODO: remove?
51
- # Don't put this queryset's objects into the IdentityMapper
63
+ # If false, prevents the QuerySet from loading.
64
+ # @return [bool]
65
+ attr_accessor :loadable
66
+ # If bool, on't put this queryset's objects into the IdentityMapper
67
+ # @return [bool]
52
68
  attr_accessor :_no_identity_mapper
69
+ # @return [bool] True when the QuerySet has been modified after loading
53
70
  attr_accessor :modified
54
71
 
55
72
  # Instantiates a non-autoloading queryset
73
+ # @param [Class<BaseModel] model
74
+ # @param [Query|Object] query_or_val see {QuerySet.new}
75
+ # @return [QuerySet]
56
76
  def self.static(model, query_or_val=nil)
57
77
  qs = self.new(model, query_or_val)
58
78
  qs.autoload = false
59
79
  return qs
60
80
  end
61
81
 
82
+ # Instantiates an autoloading queryset
83
+ # @param [Class<BaseModel] model
84
+ # @param [Query|Object] query_or_val see {QuerySet.new}
85
+ # @return [QuerySet]
62
86
  def self.autoloading(model, query_or_val=nil)
63
87
  qs = self.new(model, query_or_val)
64
88
  qs.autoload = true
65
89
  return qs
66
90
  end
67
91
 
68
- # The first argument must be a BaseModel subclass.
69
- # The second argument may be a Query, or data that will be passed to #set_data. If data is passed,
70
- # the QuerySet will be instantiated with autoload set to false.
92
+ # @param [Class<BaseModel] model The BaseModel subclass
93
+ # @param [Query|Array|BaseModel] query_or_val Can be a Query, or data.
94
+ # * If a Query is given, the QuerySet will autoload using Query.
95
+ # * If data is given, the QuerySet will be static (not autoloading),
96
+ # and the data will be passed to {#set_data}.
71
97
  def initialize(model, query_or_val=nil)
72
98
  @model = model
73
99
  model.extend_queryset(self)
@@ -101,39 +127,53 @@ module Spider; module Model
101
127
  end
102
128
 
103
129
 
104
- # Model mapper.
130
+ # @return [Model::Mapper] The model's mapper
105
131
  def mapper
106
132
  @model.mapper
107
133
  end
108
134
 
109
135
  # Sets a fixed value: it will be applied to every object.
136
+ # @param [Symbol] name
137
+ # @param [Object] value
138
+ # @return [void]
110
139
  def fixed(name, value)
111
140
  @fixed[name] = value
112
141
  end
113
142
 
114
143
  # Enables or disables autoload; if the second argument is true, will traverse
115
144
  # contained objects.
116
- def autoload(bool, traverse=true)
117
- @autoload = bool
118
- @objects.each{ |obj| obj.autoload = bool } if traverse
145
+ # @param [bool] value Enable or disable autoload
146
+ # @param [bool] traverse If true, set autoload to value on contained objects as well
147
+ # @return [void]
148
+ def autoload(value, traverse=true)
149
+ @autoload = value
150
+ @objects.each{ |obj| obj.autoload = value } if traverse
119
151
  end
120
152
 
121
- # Enables or disables autoload.
153
+ # See #{#autoload}
154
+ # @param [bool] value
155
+ # @return [void]
122
156
  def autoload=(bool)
123
157
  autoload(bool)
124
158
  end
125
159
 
160
+ # @return [bool] True if autoload is enabled, False otherwise
126
161
  def autoload?
127
162
  @autoload ? true : false
128
163
  end
129
164
 
130
165
  # Sets containing model and element.
166
+ # @param [BaseModel] obj
167
+ # @param [Symbol] element Name of the element inside the parent which points to this QuerySet
168
+ # @return [void]
131
169
  def set_parent(obj, element)
132
170
  @_parent = obj
133
171
  @_parent_element = element
134
172
  end
135
173
 
136
174
  # Disables autoload. If a block is given, the current autoload value will be restored after yielding.
175
+ # @param [bool] traverse If true, apply to children as well
176
+ # @return [void]
137
177
  def no_autoload(traverse=true)
138
178
  prev_autoload = autoload?
139
179
  self.autoload(false, traverse)
@@ -141,7 +181,10 @@ module Spider; module Model
141
181
  self.autoload(prev_autoload, traverse)
142
182
  end
143
183
 
144
- # Adds objects to the QuerySet. The argument must be an Enumerable (and should contain BaseModel instances).
184
+ # Adds objects to the QuerySet
185
+ # @param [Enumerable|Object] data If the argument is an Enumerable, its contents will be appendend to the QuerySet;
186
+ # otherwise, the object will be appended.
187
+ # @return [void]
145
188
  def set_data(data)
146
189
  if (data.is_a?(Enumerable))
147
190
  data.each do |val|
@@ -153,6 +196,9 @@ module Spider; module Model
153
196
 
154
197
  end
155
198
 
199
+ # Changes the model of the QuerySet; will call {BaseModel#become} on children.
200
+ # @param [Class<BaseModel] model The model to change to
201
+ # @return [self]
156
202
  def change_model(model)
157
203
  @model = model
158
204
  @objects.each_index do |i|
@@ -162,6 +208,9 @@ module Spider; module Model
162
208
  end
163
209
 
164
210
  # Adds an object to the set. Also stores the raw data if it is passed as the second parameter.
211
+ # @param [BaseModel] obj The object to add
212
+ # @param [Hash] raw Optional raw data associated to the object
213
+ # @return [void]
165
214
  def <<(obj, raw=nil)
166
215
  return merge(obj) if (obj.class == QuerySet)
167
216
  unless (obj.is_a?(@model))
@@ -178,6 +227,8 @@ module Spider; module Model
178
227
 
179
228
 
180
229
  # Accesses an object. Data will be loaded according to fetch_window.
230
+ # @param [Fixnum] index
231
+ # @return [BaseModel]
181
232
  def [](index)
182
233
  if (index.is_a?(Range))
183
234
  return index.map{ |i| self[i] }
@@ -196,7 +247,10 @@ module Spider; module Model
196
247
  return val
197
248
  end
198
249
 
199
- # Sets an object.
250
+ # Sets an object
251
+ # @param [Fixnum] index
252
+ # @param [BaseModel] val
253
+ # @return [void]
200
254
  def []=(index, val)
201
255
  #load_to_index(index) unless loaded?(index) || !autoload?
202
256
  val = instantiate_object(val) unless val.is_a?(@model)
@@ -208,7 +262,8 @@ module Spider; module Model
208
262
  @objects[array_index] = val
209
263
  end
210
264
 
211
- # Checks contained objects' loaded elements.
265
+ # Ensures children's loaded_elments match the QuerySet's ones.
266
+ # @return [void]
212
267
  def update_loaded_elements
213
268
 
214
269
  return if currently_empty?
@@ -223,6 +278,7 @@ module Spider; module Model
223
278
  @loaded_elements.merge!(f_loaded)
224
279
  end
225
280
 
281
+ # @return [true] True if the QuerySet, or any of its children, has been modified since loading
226
282
  def modified?
227
283
  return true if @modified
228
284
  @objects.each do |obj|
@@ -231,22 +287,29 @@ module Spider; module Model
231
287
  return false
232
288
  end
233
289
 
234
- # Returns the last object.
290
+ # @return [BaseModel] The last object in the QuerySet
235
291
  def last
236
292
  load unless (@loaded || !autoload?) && loaded?(total_rows-1)
237
293
  @objects.last
238
294
  end
239
295
 
240
- # Deletes object at the given index.
296
+ # Removes the object at the given index from the QuerySet
297
+ # @param [Fixnum] index
298
+ # @return [BaseModel|nil] The removed object
241
299
  def delete_at(index)
242
300
  @objects.delete_at(index)
243
301
  end
244
302
 
303
+ # Removes the given object from the QuerySet
304
+ # @param [BaseModel] obj
305
+ # @return [BaseModel|nil] The removed object
245
306
  def delete(obj)
246
307
  @objects.delete(obj)
247
308
  end
248
309
 
249
310
  # Returns a new QuerySet containing objects from both this and the other.
311
+ # @param [QuerySet] other
312
+ # @return [QuerySet]
250
313
  def +(other)
251
314
  qs = self.clone
252
315
  other.each do |obj|
@@ -256,22 +319,27 @@ module Spider; module Model
256
319
  end
257
320
 
258
321
  # Number of objects fetched. Will call load if not loaded yet.
259
- # Note: this is not the total number of objects corresponding to the Query;
322
+ # Note: this is not the total number of objects responding to the Query;
260
323
  # it may be equal to the fetch_window, or to the @query.limit.
324
+ # @return [Fixnum] length
261
325
  def length
262
326
  load unless @loaded || !autoload?
263
327
  @objects.length
264
328
  end
265
329
 
266
- # Like #select, but returns an array
330
+ # Like {#select}, but returns an array
331
+ # @return [Array]
267
332
  alias :select_array :select
268
333
 
269
334
  # Returns a (static) QuerySet of the objects for which the block evaluates to true.
335
+ # @param [Proc] proc The block to evaluate
336
+ # @return [QuerySet]
270
337
  def select(&proc)
271
338
  return QuerySet.new(@model, select_array(&proc))
272
339
  end
273
340
 
274
341
  # True if the query had a limit, and more results can be fetched.
342
+ # @return [bool] True if there are more objects to fetch from the storage.
275
343
  def has_more?
276
344
  return true if autoload? && !@loaded
277
345
  return false unless query.limit
@@ -280,26 +348,32 @@ module Spider; module Model
280
348
  end
281
349
 
282
350
  # Total number of objects that would be returned had the Query no limit.
351
+ # @return [Fixnum] The total number of rows corresponding to the Query (without limit).
283
352
  def total_rows
284
353
  return @total_rows ? @total_rows : (@total_rows = @model.mapper.count(@query.condition))
285
354
  end
286
355
 
287
356
  # Current number of objects fetched.
357
+ # @return [Fixnum]
288
358
  def current_length
289
359
  @objects.length
290
360
  end
291
361
 
292
- # True if no objects were fetched (yet).
362
+ # Returns true if the QuerySet has no elements. Will load if the QuerySet is autoloading.
363
+ # @return [bool] True if QuerySet is empty
293
364
  def empty?
294
365
  load unless @loaded || !autoload?
295
366
  @objects.empty?
296
367
  end
297
368
 
369
+ # @return [bool] True if no object has been fetched yet.
298
370
  def currently_empty?
299
371
  @objects.empty?
300
372
  end
301
373
 
302
374
  # Index objects by some elements.
375
+ # @param [*Element] elements Elements to index on
376
+ # @return [self]
303
377
  def index_by(*elements)
304
378
  names = elements.map{ |el| (el.is_a?(Spider::Model::Element)) ? el.name.to_s : el.to_s }
305
379
  index_name = names.sort.join(',')
@@ -308,8 +382,10 @@ module Spider; module Model
308
382
  return self
309
383
  end
310
384
 
385
+
311
386
  # Rebuild object index.
312
- def reindex # :nodoc:
387
+ # @return [self]
388
+ def reindex
313
389
  @index_lookup.each_key do |index|
314
390
  @index_lookup[index] = {}
315
391
  end
@@ -320,6 +396,8 @@ module Spider; module Model
320
396
  end
321
397
 
322
398
  # Adds object to the index
399
+ # @param [BaseModel] obj
400
+ # @return [void]
323
401
  def index_object(obj) # :nodoc:
324
402
  @index_lookup.keys.each do |index_by|
325
403
  names = index_by.split(',')
@@ -330,7 +408,9 @@ module Spider; module Model
330
408
  end
331
409
  end
332
410
 
333
- # FIXME: ???
411
+ # @param [BaseModel] obj
412
+ # @param [Symbol|String] name Element name
413
+ # @return [String] The index key for an object's element
334
414
  def search_key(obj, name) # :nodoc:
335
415
  sub = obj.is_a?(Hash) ? obj[name] : obj.get(name.to_sym)
336
416
  if (sub.is_a?(Spider::Model::BaseModel))
@@ -346,17 +426,22 @@ module Spider; module Model
346
426
  end
347
427
 
348
428
  # Remove all elements from self
429
+ # @return [void]
349
430
  def clear
350
431
  @objects = []
351
432
  @index_lookup.each_key{ |k| @index_lookup[k] = {} }
352
433
  end
353
434
 
354
435
  # Iterates on currently loaded objects
436
+ # @yield [BaseModel]
437
+ # @return [void]
355
438
  def each_current
356
439
  @objects.each { |obj| yield obj }
357
440
  end
358
441
 
359
442
  # Iterates on objects, loading when needed.
443
+ # @yield [BaseModel]
444
+ # @return [void]
360
445
  def each
361
446
  self.each_rolling_index do |i|
362
447
  obj = @objects[i]
@@ -370,6 +455,8 @@ module Spider; module Model
370
455
 
371
456
  # Iterates yielding the internal objects index. Will load when needed. If a window is
372
457
  # used, the index will roll back to 0 on every window.
458
+ # @yield [BaseModel]
459
+ # @return [void]
373
460
  def each_rolling_index
374
461
  @window_current_start = nil if (@fetch_window)
375
462
  while (!@fetch_window || has_more?)
@@ -382,6 +469,8 @@ module Spider; module Model
382
469
  end
383
470
 
384
471
  # Iterates yielding the queryset index. Will load when needed.
472
+ # @yield [Fixnum]
473
+ # @return [void]
385
474
  def each_index
386
475
  self.each_rolling_index do |i|
387
476
  i += @window_current_start-1 if @window_current_start
@@ -390,6 +479,8 @@ module Spider; module Model
390
479
  end
391
480
 
392
481
  # Iterates on indexes without loading.
482
+ # @yield [Fixnum]
483
+ # @return [void]
393
484
  def each_current_index
394
485
  @objects.each_index do |i|
395
486
  i += @window_current_start-1 if @window_current_start
@@ -398,11 +489,22 @@ module Spider; module Model
398
489
  end
399
490
 
400
491
  # Merges the content of another QuerySet.
492
+ # @param [QuerySet] query_set
493
+ # @return [void]
401
494
  def merge(query_set)
402
495
  @objects += query_set.instance_variable_get(:"@objects")
403
496
  reindex
404
497
  end
405
498
 
499
+ # Returns true if the QuerySet includes the given value.
500
+ #
501
+ # The value can be a BaseModel, which will be searched as it is;
502
+ #
503
+ # a Hash, in which case an Object with all the given values will be searched;
504
+ #
505
+ # or an Object, which will be searched as the (only) primary key of a contained model
506
+ # @param [BaseModel|Hash|Object] val The value to be checked
507
+ # @return [bool]
406
508
  def include?(val)
407
509
  self.each do |obj|
408
510
  if val.is_a?(BaseModel)
@@ -424,6 +526,8 @@ module Spider; module Model
424
526
  end
425
527
 
426
528
  # Searchs the index for objects matching the given params.
529
+ # @param [Hash] params A set of conditions. Keys must match already created indexes.
530
+ # @return [QuerySet] A new QuerySet with objects matching params
427
531
  def find(params)
428
532
  sorted_keys = params.keys.map{|k| k.to_s}.sort.map{|k| k.to_sym}
429
533
  index = sorted_keys.map{ |key| key.to_s }.join(',')
@@ -436,12 +540,16 @@ module Spider; module Model
436
540
  return QuerySet.new(@model, result)
437
541
  end
438
542
 
439
- # Calls Query.order_by
543
+ # Calls {Query#order_by} on the QuerySet's query
544
+ # @param [*Element]
545
+ # @return [self]
440
546
  def order_by(*elements)
441
- @query.order_by *elements
547
+ @query.order_by(*elements)
442
548
  return self
443
549
  end
444
550
 
551
+ # Calls {Query#with_polymorphs} on the QuerySet's query
552
+ # @return [self]
445
553
  def with_polymorphs
446
554
  @model.polymorphic_models.each do |model, attributes|
447
555
  @query.with_polymorph(model)
@@ -450,6 +558,9 @@ module Spider; module Model
450
558
  end
451
559
 
452
560
  # Sets the value of an element on all currently loaded objects.
561
+ # @param [Element|Symbol] element
562
+ # @param [Object] value
563
+ # @return [void]
453
564
  def set(element, value)
454
565
  element_name = element.is_a?(Element) ? element.name : element
455
566
  fixed(element_name, value)
@@ -462,6 +573,7 @@ module Spider; module Model
462
573
  end
463
574
 
464
575
  # Executes the query and fetches the objects; (the next batch if a fetch_window is set).
576
+ # @return [self]
465
577
  def load
466
578
  return self unless loadable?
467
579
  clear
@@ -474,7 +586,8 @@ module Spider; module Model
474
586
  return self
475
587
  end
476
588
 
477
- # Start for the query to get index i
589
+ # @param [Fixnum] i
590
+ # @return [Fixnum] The index to start with to get the page containing the i-th element
478
591
  def start_for_index(i) # :nodoc:
479
592
  return 1 unless @fetch_window
480
593
  page = i / @fetch_window + 1
@@ -482,6 +595,8 @@ module Spider; module Model
482
595
  end
483
596
 
484
597
  # Loads objects up to index i
598
+ # @param [Fixnum] i Index
599
+ # @return [void]
485
600
  def load_to_index(i)
486
601
  return load unless @fetch_window
487
602
  page = i / @fetch_window + 1
@@ -489,6 +604,8 @@ module Spider; module Model
489
604
  end
490
605
 
491
606
  # Loads the next batch of objects.
607
+ # @param [Fixnum] Page to load (defaults to next page)
608
+ # @return [self]
492
609
  def load_next(page=nil)
493
610
  if (@fetch_window)
494
611
  @query.limit = @fetch_window
@@ -507,7 +624,9 @@ module Spider; module Model
507
624
  end
508
625
 
509
626
  # If a Fixnum is passed, will tell if the given index is loaded.
510
- # With no argument, will tell if the QuerySet is loaded
627
+ # With no argument, will tell if the QuerySet is fully loaded
628
+ # @param [Fixnum] index
629
+ # @return [bool]
511
630
  def loaded?(index=nil)
512
631
  return @loaded if !@loaded || !index || !@fetch_window
513
632
  return false unless @window_current_start
@@ -515,35 +634,45 @@ module Spider; module Model
515
634
  return false
516
635
  end
517
636
 
637
+ # Sets that the QuerySet is or is not loaded
638
+ # @param [bool] val
639
+ # @return [void]
518
640
  def loaded=(val)
519
641
  @loaded = val
520
642
  @modified = false if @loaded
521
643
  end
522
644
 
645
+ # @return [bool] True if the QuerySet can be loaded
523
646
  def loadable?
524
647
  @loadable
525
648
  end
526
649
 
527
650
  # Saves each object in the QuerySet.
651
+ # @return [void]
528
652
  def save
529
653
  no_autoload(false){ each{ |obj| obj.save } }
530
654
  end
531
655
 
656
+ # Calls {BaseModel.save!} on each object in the QuerySet.
657
+ # @return [void]
532
658
  def save!
533
659
  no_autoload(false){ each{ |obj| obj.save! } }
534
660
  end
535
661
 
536
- # Calls #BaseModel.insert on each object in the QuerySet.
662
+ # Calls {BaseModel.insert} on each object in the QuerySet.
663
+ # @return [void]
537
664
  def insert
538
665
  no_autoload(false){ each{ |obj| obj.insert } }
539
666
  end
540
667
 
541
- # Calls #BaseModel.update on each object in the QuerySet.
668
+ # Calls {BaseModel.update} on each object in the QuerySet.
669
+ # @return [void]
542
670
  def update
543
671
  no_autoload(false){ each{ |obj| obj.update } }
544
672
  end
545
673
 
546
- # Calls #BaseModel.save_all on each object in the QuerySet.
674
+ # Calls {BaseModel.save_all} on each object in the QuerySet.
675
+ # @return [void]
547
676
  def save_all(params={})
548
677
  @objects.each do |obj|
549
678
  # next if (unit_of_work && !unit_of_work.save?(obj))
@@ -552,6 +681,8 @@ module Spider; module Model
552
681
  end
553
682
 
554
683
  # Returns a new instance of @model from val.
684
+ # @param [Object] val
685
+ # @return [BaseModel] The created object
555
686
  def instantiate_object(val=nil)
556
687
  if (@append_element && !val.is_a?(@model) && !(val.is_a?(Hash) && val[@append_element]))
557
688
  val = @model.elements[@append_element].type.new(val) unless (val.is_a?(BaseModel))
@@ -567,10 +698,12 @@ module Spider; module Model
567
698
  return obj
568
699
  end
569
700
 
701
+ # @return [String] A textual description of the QuerySet
570
702
  def inspect
571
703
  return "#{self.class.name}:\n@model=#{@model}, @query=#{query.inspect}, @objects=#{@objects.inspect}"
572
704
  end
573
705
 
706
+ # @return [String] The JSON representation of the QuerySet
574
707
  def to_json(state=nil, &proc)
575
708
  load unless loaded? || !autoload?
576
709
  res = "[" +
@@ -580,17 +713,20 @@ module Spider; module Model
580
713
  end
581
714
 
582
715
 
583
- # Returns an array with the results of calling #BaseModel.cut on each object.
716
+ # @param [*Object] (see {BaseModel.cut})
717
+ # @return [Array] An array with the results of calling {BaseModel.cut} on each object.
584
718
  def cut(*params)
585
719
  load unless loaded? || !autoload?
586
720
  return self.map{ |obj| obj.cut(*params) }
587
721
  end
588
722
 
589
- # Returns an array with the results of calling #BaseModel.to_hash_array on each object.
723
+ # @return [Array] An array with the results of calling #BaseModel.to_hash_array on each object.
590
724
  def to_hash_array
591
725
  return self.map{ |obj| obj.to_hash }
592
726
  end
593
727
 
728
+ # @param [String|Symbol] Element name (or dotted element path) to index by
729
+ # @return [Hash] A Hash, indexed by the value of element on the object
594
730
  def to_indexed_hash(element)
595
731
  hash = {}
596
732
  self.each do |row|
@@ -599,7 +735,8 @@ module Spider; module Model
599
735
  hash
600
736
  end
601
737
 
602
- # Prints an ASCII table
738
+ # Prints an ASCII table of the QuerySet
739
+ # @return [void]
603
740
  def table
604
741
 
605
742
  # Functions for determining terminal size:
@@ -674,14 +811,17 @@ module Spider; module Model
674
811
 
675
812
  end
676
813
 
814
+ # @return [Array] The Array corresponding to the QuerySet
677
815
  def to_a
678
816
  self.map{ |row| row }
679
817
  end
680
818
 
819
+ # @return [Array] A reversed Array
681
820
  def reverse
682
821
  self.to_a.reverse
683
822
  end
684
823
 
824
+ # @return [Array] Calls map on currently loaded objects
685
825
  def map_current
686
826
  a = []
687
827
  each_current{ |row| a << yield(row) }
@@ -689,6 +829,7 @@ module Spider; module Model
689
829
  end
690
830
 
691
831
  # Returns an array of Hashes, with each value of the object is converted to string.
832
+ # @return [Array]
692
833
  def to_flat_array
693
834
  map do |obj|
694
835
  h = {}
@@ -699,18 +840,25 @@ module Spider; module Model
699
840
  end
700
841
  end
701
842
 
843
+ # Removes the objects for which the block returns true from the QuerySet
844
+ # @yield [BaseModel]
845
+ # @return [void]
702
846
  def reject!(&proc)
703
847
  @objects.reject!(&proc)
704
848
  end
705
849
 
850
+ # Removes all objects from the QuerySet
851
+ # @return [void]
706
852
  def empty!
707
853
  @objects = []
708
854
  end
709
855
 
856
+ # @return [String] All the objects, to_s, joined by ', '
710
857
  def to_s
711
858
  self.map{ |o| o.to_s }.join(', ')
712
859
  end
713
860
 
861
+ # Missing methods will be sent to the query
714
862
  def method_missing(method, *args, &proc)
715
863
  el = @model.elements[method]
716
864
  if (el && el.model? && el.reverse)
@@ -720,6 +868,8 @@ module Spider; module Model
720
868
  return super
721
869
  end
722
870
 
871
+ # @param [Element|Symbol] element
872
+ # @return [QuerySet] The QuerySet corresponding to an element in the current QuerySet
723
873
  def element_queryset(el)
724
874
  el = @model.elements[el] if el.is_a?(Symbol)
725
875
  condition = el.condition
@@ -735,6 +885,8 @@ module Spider; module Model
735
885
  # Given a dotted path, will return an array of all objects reachable by that path
736
886
  # Example
737
887
  # objectset.all_children('friends.collegues.addresses.street_name')
888
+ # @param [String] path
889
+ # @return [Array] An array of all found objects
738
890
  def all_children(path)
739
891
  if (path.length > 0)
740
892
  children = @objects.map{ |obj| obj.all_children(path.clone) }.flatten
@@ -744,28 +896,36 @@ module Spider; module Model
744
896
  end
745
897
 
746
898
  # Registers that the element has been loaded.
899
+ # @param [Element|Symbol]
900
+ # @return [void]
747
901
  def element_loaded(element)
748
902
  element = element.name if element.is_a?(Element)
749
903
  @loaded_elements[element] = true
750
904
  end
751
905
 
752
- # Returns whether the element has been loaded from the Storage.
906
+ # @param [Element|Symbol]
907
+ # @return [bool] True if the element has been loaded from the Storage.
753
908
  def element_loaded?(element)
754
909
  element = element.name if element.is_a?(Element)
755
910
  @loaded_elements[element]
756
911
  end
757
912
 
758
- # Returns the QuerySet IdentityMapper instance
913
+ # Returns the current QuerySet IdentityMapper instance, or instantiates a new one
914
+ # @return [IdentityMapper] The IdentityMapper
759
915
  def identity_mapper
760
916
  return Spider::Model.identity_mapper if Spider::Model.identity_mapper
761
917
  @identity_mapper ||= IdentityMapper.new
762
918
  end
763
919
 
764
- # Assigns an IdentityMapper
920
+ # Assigns an IdentityMapper to the QuerySet
921
+ # @param [IdentityMapper] im
922
+ # @return [void]
765
923
  def identity_mapper=(im)
766
924
  @identity_mapper = im
767
925
  end
768
926
 
927
+ # Calls {Query#with_superclass} on the query.
928
+ # @return [self]
769
929
  def with_superclass
770
930
  @query.with_superclass
771
931
  return self
@@ -775,29 +935,35 @@ module Spider; module Model
775
935
  # Condition, request and query methods #
776
936
  ########################################
777
937
 
778
- # Calls #Query.where
938
+ # Calls {Query#where} on the query.
939
+ # @return {self}
779
940
  def where(*params, &proc)
780
941
  @query.where(*params, &proc)
781
942
  return self
782
943
  end
783
944
 
784
- # Calls #Query.limit
945
+ # Calls {Query.limit} on the query
946
+ # @return {self}
785
947
  def limit(n)
786
948
  @query.limit = n
787
949
  return self
788
950
  end
789
951
 
790
- # Calls #Query.offset
952
+ # Calls {Query.offset}
953
+ # @return {self}
791
954
  def offset(n)
792
955
  @query.offset = n
793
956
  return self
794
957
  end
795
958
 
959
+ # Calls {Query.page} on the Query
960
+ # @return {self}
796
961
  def page(page, rows)
797
962
  @query.page(page, rows)
798
963
  self
799
964
  end
800
965
 
966
+ # @return [Fixnum|nil] Total number of available pages for current query (or nil if no limit is set)
801
967
  def pages
802
968
  return nil unless @query.limit
803
969
  (self.total_rows.to_f / @query.limit).ceil
@@ -808,6 +974,7 @@ module Spider; module Model
808
974
  # end
809
975
 
810
976
  # Performs a deep copy
977
+ # @return [QuerySet]
811
978
  def clone
812
979
  c = self.class.new(self.model, self.query.clone)
813
980
  c.autoload = self.autoload?