volt-repo_cache 0.1.6 → 0.1.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 474923d9b6d0aea6afc647e672160d1f253105a6
4
- data.tar.gz: 08ba0695263b36cdf2280d9b8e30f60205bc3eb1
3
+ metadata.gz: d6e67fb69f5462671adbe6c70c7d88ff76156bc7
4
+ data.tar.gz: b7dacb4047656a539f2cc858f5ae88f955185d0a
5
5
  SHA512:
6
- metadata.gz: 54f2267798305375f6906383145ed98815b6f90e3227eb0030a8fab82cf5f46653ce6c9909835ae91f9b700276ad94930d0c6ebbfce640c210bb7ab6f8670268
7
- data.tar.gz: 885be0b3b42845d30c497de78b0201643708e26b4bed691d981f4117e3cce722b666bddf70788afe9e2a76676efe9cc8adae66983f7ba6b9f599641c518651f4
6
+ metadata.gz: a6438cc77fd305a203677d88ae2805a538fcebb3c672ea1a8e4ad735c1631f191557ca47a4102508692a3786c5e8584c19b94d11637cdf3de6714fb9038b7257
7
+ data.tar.gz: de00eae7965eb73757fcd19154fab9c8159e345355ecbef617d2af9091158c9ae061f5bfeec206a45887c9a428dfd9933e0e7147edc847cacaa117ead803f748
@@ -58,13 +58,10 @@ module Volt
58
58
  # foreign_collection being lazily initialized.
59
59
  def reciprocal
60
60
  unless @reciprocal
61
- # debug __method__, __LINE__, ""
62
61
  @reciprocal = foreign_collection.associations.values.detect do |a|
63
- # debug __method__, __LINE__, "#{a.foreign_collection.name} ?==? #{local_collection.name}"
64
62
  a.foreign_collection.name == local_collection.name
65
63
  end
66
64
  @reciprocal = :nil unless @reciprocal
67
- # debug __method__, __LINE__, "reciprocal of #{self.inspect} is #{@reciprocal.inspect}"
68
65
  end
69
66
  @reciprocal == :nil ? nil : @reciprocal
70
67
  end
@@ -36,7 +36,6 @@ module Volt
36
36
  # read_only should be inherited by has_... targets
37
37
  #
38
38
  def initialize(**options)
39
- # debug __method__, __LINE__, "@options = #{@options}"
40
39
  @repo = options.delete(:repo) || Volt.current_app.store
41
40
  @collection_options = options.delete(:collections) || {}
42
41
  load
@@ -62,7 +61,6 @@ module Volt
62
61
  def clear
63
62
  # debug __method__, __LINE__
64
63
  @collections.each do |name, collection|
65
- # debug __method__, __LINE__, "name=#{name} collection=#{collection}"
66
64
  collection.send(:uncache)
67
65
  end
68
66
  @collections = {}
@@ -90,20 +88,13 @@ module Volt
90
88
  promises = []
91
89
  @collection_options.each do |given_name, options|
92
90
  name = collection_name(given_name)
93
- # debug __method__, __LINE__
94
91
  collection = Collection.new(cache: self, name: name, options: options)
95
- # debug __method__, __LINE__
96
92
  @collections[name] = collection
97
93
  promises << collection.loaded
98
94
  end
99
- # debug __method__, __LINE__, "promises.size = #{promises.size}"
100
- t1 = Time.now
101
95
  @loaded = Promise.when(*promises).then do
102
- # t2 = Time.now
103
- # debug __method__, __LINE__, "@@loaded = Promise.when(*promises).then took #{t2-t1} seconds"
104
96
  self
105
97
  end
106
- # debug __method__, __LINE__, "@loaded => #{@loaded.class.name}:#{@loaded.value.class.name}"
107
98
  end
108
99
 
109
100
  def collection_name(given_name)
@@ -13,16 +13,14 @@ module Volt
13
13
  attr_reader :model_class
14
14
  attr_reader :repo_collection
15
15
  attr_reader :load_query
16
- attr_reader :loaded_ids
16
+ attr_reader :cached_ids
17
17
  attr_reader :loaded # Promise
18
18
  attr_reader :marked_for_destruction
19
19
  attr_reader :associations
20
20
  attr_reader :read_only
21
21
 
22
22
  def initialize(cache: nil, name: nil, options: {})
23
- # debug __method__, __LINE__, "name: #{name} options: #{options}"
24
23
  super(observer: self)
25
- # debug __method__, __LINE__
26
24
  @cache = cache
27
25
  @name = name
28
26
  @load_query = options[:query] || options[:where]
@@ -33,7 +31,6 @@ module Volt
33
31
  @repo_collection = @cache.repo.send(name)
34
32
  init_associations(options)
35
33
  load
36
- # debug __method__, __LINE__
37
34
  end
38
35
 
39
36
  # hide circular reference to cache
@@ -70,7 +67,7 @@ module Volt
70
67
  append(hash.to_h)
71
68
  end
72
69
 
73
- # Appends a model to the collection.
70
+ # Appends a new model to the collection.
74
71
  # Model may be a hash which will be converted.
75
72
  # (See #induct for more.)
76
73
  # If the model belongs_to any other owners, the foreign id(s)
@@ -78,8 +75,8 @@ module Volt
78
75
  # in the cache - it is easier to ask the owner for a new
79
76
  # instance (e.g. product.recipe.new_ingredient).
80
77
  # NB: Returns the newly appended model.
81
- def append(model, error_if_present: true, error_unless_new: true, notify: true)
82
- model = induct(model, error_unless_new: error_unless_new, error_if_present: error_if_present)
78
+ def append(model, notify: true)
79
+ model = induct(model, loaded_from_repo: false)
83
80
  __append__(model, notify: notify)
84
81
  model
85
82
  end
@@ -123,7 +120,7 @@ module Volt
123
120
  # Remove model from marked_for_destruction bucket.
124
121
  # Don't worry if we can't find it.
125
122
  def destroyed(model)
126
- @loaded_ids.delete(model.id)
123
+ @cached_ids.delete(model.id)
127
124
  @marked_for_destruction.delete(model.id)
128
125
  end
129
126
 
@@ -131,17 +128,13 @@ module Volt
131
128
  # that a model has been added or removed. Pass
132
129
  # this on to associations.
133
130
  def observe(action, model)
134
- # debug __method__, __LINE__, "action=#{action} model=#{model} associations=#{associations}"
135
131
  # notify owner model(s) of appended model that it has been added
136
132
  notify_associations(action, model)
137
133
  end
138
134
 
139
135
  def notify_associations(action, model)
140
- # debug __method__, __LINE__, "action=#{action} model=#{model} associations=#{associations}"
141
136
  associations.each_value do |assoc|
142
- # debug __method__, __LINE__, "calling notify_associates(#{assoc}, #{action}, #{model})"
143
137
  notify_associates(assoc, action, model)
144
- # debug __method__, __LINE__, "called notify_associates(#{assoc}, #{action}, #{model})"
145
138
  end
146
139
  end
147
140
 
@@ -152,22 +145,17 @@ module Volt
152
145
  # association may be owner customer - thus
153
146
  # association will be belongs_to
154
147
  def notify_associates(assoc, action, model)
155
- # debug __method__, __LINE__, "action=#{action} model=#{model} assoc=#{assoc} reciprocate=#{assoc.reciprocal}"
156
148
  if assoc.reciprocal
157
149
  local_id = model.send(assoc.local_id_field)
158
- # debug __method__, __LINE__, "local_id #{assoc.local_id_field}=#{local_id}"
159
150
  if local_id # may not be set yet
160
151
  assoc.foreign_collection.each do |other|
161
- # debug __method__, __LINE__, "calling #{assoc.foreign_id_field} on #{other}"
162
152
  foreign_id = other.send(assoc.foreign_id_field)
163
153
  if local_id == foreign_id
164
- # debug __method__, __LINE__, "foreign_id==local_id of #{other}, calling other.refresh_association(#{assoc.foreign_name})"
165
154
  other.send(:refresh_association, assoc.reciprocal)
166
155
  end
167
156
  end
168
157
  end
169
158
  end
170
- # debug __method__, __LINE__
171
159
  end
172
160
 
173
161
  # 'Induct' a model into the cache via this collection.
@@ -193,66 +181,64 @@ module Volt
193
181
  # associational integrity in the cache.
194
182
  #
195
183
  # Returns the inducted model.
196
- def induct(model_or_hash, error_unless_new: true, error_if_present: true)
197
- created_in_cache = false
198
- if model_or_hash.is_a?(Hash)
199
- created_in_cache = true
200
- model = model_class.new(model_or_hash, options: {persistor: cache.persistor})
201
- else
202
- model = model_or_hash
203
- # unless model.persistor.class == cache.persistor.class
204
- # raise RuntimeError, "model persistor is #{model.persistor} but should be #{cache.persistor}"
205
- # end
206
- unless model.class == model_class
207
- raise ArgumentError, "#{model} must be a #{model_class_name}"
208
- end
209
- if error_unless_new && (!model.created_in_cache? || model.new?)
210
- raise ArgumentError, "#{model} must be new (not stored) or have been created in cache"
184
+ def induct(model_or_hash, loaded_from_repo: false)
185
+ model = if Hash === model_or_hash
186
+ if loaded_from_repo
187
+ raise TypeError, "cannot induct stored model from a hash #{model_or_hash}"
211
188
  end
212
- if error_if_present && @loaded_ids.include?(model.id)
213
- raise RuntimeError, "cannot add #{model} already in cached collection"
189
+ model_class.new(model_or_hash, options: {persistor: cache.persistor})
190
+ else
191
+ if !loaded_from_repo && model_or_hash.buffer?
192
+ raise TypeError, "cannot induct new model_or_hash #{model_or_hash} with buffer"
214
193
  end
194
+ model_or_hash
195
+ end
196
+ unless model.class == model_class
197
+ raise ArgumentError, "#{model} must be a #{model_class_name}"
198
+ end
199
+ if model.cached?
200
+ __debug __method__, __LINE__, "id=#{model.id} model.cached?=#{model.cached?}"
201
+ raise TypeError, "model.id #{model.id} already in cache"
215
202
  end
216
- @loaded_ids << model.id
217
- patch_for_cache(model, created_in_cache)
203
+ @cached_ids << model.id
204
+ RepoCache::Model.induct_to_cache(model, self, loaded_from_repo)
218
205
  model
219
206
  end
220
207
 
208
+ def cached?(model)
209
+ @cached_ids.include?(model.id)
210
+ end
211
+
221
212
  def load
222
- # debug __method__, __LINE__
223
- @loaded_ids = Set.new # append/delete will update
213
+ @cached_ids = Set.new # append/delete will update
224
214
  q = @load_query ? repo_collection.where(@load_query) : repo_collection
225
- # t1 = Time.now
226
215
  @loaded = q.all.collect{|e|e}.then do |models|
227
- # t2 = Time.now
228
- # debug __method__, __LINE__, "#{name} read_only=#{read_only} query promise resolved to #{models.size} models in #{t2-t1} seconds"
229
- models.each do |model|
230
- append(read_only ? model : model.buffer, error_unless_new: false, notify: false)
216
+ models.each do |_model|
217
+ model = read_only ? _model : _model.buffer
218
+ induct(model, loaded_from_repo: true)
219
+ __append__(model, notify: false)
231
220
  end
232
- # t3 = Time.now
233
- # debug __method__, __LINE__, "#{name} loaded ids for #{models.size} #{name} in #{t3-t2} seconds"
234
221
  self
235
222
  end
236
- # debug __method__, __LINE__, "@loaded => #{@loaded.class.name}:#{@loaded.value.class.name}"
237
223
  end
238
224
 
239
225
  def init_associations(options)
240
- # debug __method__, __LINE__, "options = #{options}"
241
226
  @associations = {}
242
227
  [:belongs_to, :has_one, :has_many].each do |type|
243
228
  arrify(options[type]).map(&:to_sym).each do |foreign_name|
244
229
  @associations[foreign_name] = Association.new(self, foreign_name, type)
245
- # debug __method__, __LINE__, "@associations[#{foreign_name}] = #{@associations[foreign_name].inspect}"
246
230
  end
247
231
  end
248
232
  end
249
233
 
250
- def patch_for_cache(model, created_in_cache)
251
- unless model.respond_to?(:patched_for_cache?)
252
- RepoCache::Model.patch_for_cache(model, self, created_in_cache)
253
- end
254
- model
255
- end
234
+ def __debug(method, line, msg = nil)
235
+ s = "{__FILE__}[#{line}]:#{self.class.name}##{method}: #{msg}"
236
+ if RUBY_PLATFORM == 'opal'
237
+ Volt.logger.debug s
238
+ else
239
+ puts s
240
+ end
241
+ end
256
242
 
257
243
  end
258
244
  end
@@ -4,19 +4,31 @@
4
4
  # methods to the module and provides
5
5
  # the instance as argument.
6
6
 
7
+ module Volt
8
+ class Model
9
+ def stored?
10
+ false
11
+ end
12
+
13
+ def cached?
14
+ false
15
+ end
16
+ end
17
+ end
18
+
7
19
  module Volt
8
20
  module RepoCache
9
21
  module Model
10
22
  extend Volt::RepoCache::Util
11
23
 
12
- def self.patch_for_cache(model, collection, created_in_cache)
13
- # debug __method__, __LINE__, "patch_for_cache [#{collection.name}] : #{model.to_h}"
24
+ def self.induct_to_cache(model, collection, loaded_from_repo)
25
+ # debug_model __method__, __LINE__, "patch_for_cache [#{collection.name}] : #{model.to_h}"
14
26
 
15
27
  # Volt sets @new to false if any attribute changes - not what we want
16
- model.instance_variable_set(:@__cache__created_in_cache, created_in_cache)
17
- model.instance_variable_set(:@__cache__collection, collection)
18
- model.instance_variable_set(:@__cache__associations, {})
19
- model.instance_variable_set(:@__cache__marked_for_destruction, false)
28
+ model.instance_variable_set(:@cache__stored, loaded_from_repo)
29
+ model.instance_variable_set(:@cache__collection, collection)
30
+ model.instance_variable_set(:@cache__associations, {})
31
+ model.instance_variable_set(:@cache__marked_for_destruction, false)
20
32
  # TODO: if model is not buffered, then trap all
21
33
  # field set value methods and raise exception -
22
34
  # unless buffered the model is read only.
@@ -47,7 +59,7 @@ module Volt
47
59
  # e.g. product.recipe
48
60
  m = foreign_name
49
61
  model.define_singleton_method(m) do
50
- # debug __method__, __LINE__, "defining #{model.class.name}##{m}"
62
+ # debug_model __method__, __LINE__, "defining #{model.class.name}##{m}"
51
63
  get_association(assoc)
52
64
  end
53
65
 
@@ -99,34 +111,38 @@ module Volt
99
111
  true
100
112
  end
101
113
 
102
- def model.created_in_cache?
103
- @__cache__created_in_cache
114
+ def model.stored?
115
+ @cache__stored
104
116
  end
105
117
 
106
118
  # Returns true if the model has been marked
107
119
  # for destruction on flush. Otherwise false.
108
120
  def model.marked_for_destruction?
109
- @__cache__marked_for_destruction
121
+ @cache__marked_for_destruction
122
+ end
123
+
124
+ def model.cached?
125
+ @cache__collection.cached?(self)
110
126
  end
111
127
 
112
128
  # Returns the cached collected the model belongs to.
113
129
  def model.collection
114
- @__cache__collection
130
+ @cache__collection
115
131
  end
116
132
 
117
133
  # Returns the cache the model belongs to.
118
134
  def model.cache
119
- @__cache__collection.cache
135
+ @cache__collection.cache
120
136
  end
121
137
 
122
138
  # Hide circular reference to collection
123
139
  # when doing inspection.
124
140
  def model.inspect
125
- if @__cache__collection
126
- __tmp = @__cache__collection
127
- @__cache__collection = "{{#{@__cache__collection.name}}}"
141
+ if @cache__collection
142
+ __tmp = @cache__collection
143
+ @cache__collection = "{{#{@cache__collection.name}}}"
128
144
  result = super
129
- @__cache__collection = __tmp
145
+ @cache__collection = __tmp
130
146
  result
131
147
  else
132
148
  super
@@ -147,10 +163,10 @@ module Volt
147
163
  # prevent collection going in circles on this
148
164
  # (we don't know whether initial request was to
149
165
  # self or to collection which holds self)
150
- unless @__cache__marked_for_destruction
151
- # debug __method__, __LINE__, "marking #{self} for destruction"
152
- @__cache__marked_for_destruction = true
153
- @__cache__collection.send(:mark_model_for_destruction, self)
166
+ unless @cache__marked_for_destruction
167
+ # debug_model __method__, __LINE__, "marking #{self} for destruction"
168
+ @cache__marked_for_destruction = true
169
+ @cache__collection.send(:mark_model_for_destruction, self)
154
170
  mark_associations_for_destruction
155
171
  end
156
172
  end
@@ -173,22 +189,23 @@ module Volt
173
189
  # - any part of it may fail without unwinding the whole
174
190
  def model.flush!
175
191
  fail_if_read_only(__method__)
176
- if @__cache__marked_for_destruction
177
- # debug __method__, __LINE__, "marked for destruction so call destroy on #{to_h}"
192
+ if @cache__marked_for_destruction
193
+ # debug_model __method__, __LINE__, "marked for destruction so call destroy on #{to_h}"
178
194
  __destroy__
179
195
  else
180
- if @__cache__created_in_cache || dirty?
181
- # debug __method__, __LINE__, "is dirty: #{to_h}"
182
- if @__cache__created_in_cache
183
- # debug __method__, __LINE__, "new: #{self.class.name}::#{self.id}"
184
- @__cache__created_in_cache = false
185
- @__cache__collection.repo_collection << self
186
- else
187
- # debug __method__, __LINE__,"dirty: #{self.class.name}::#{self.id}"
196
+ if dirty?
197
+ debug_model __method__, __LINE__, "@cache__stored=#{@cache__stored} dirty?=#{dirty?} to_h=#{to_h}"
198
+ if stored?
199
+ # debug_model __method__, __LINE__,"dirty: #{self.class.name}::#{self.id}"
188
200
  __save__
201
+ else
202
+ debug_model __method__, __LINE__, "<< to repo: #{self.class.name}::#{self.to_h}"
203
+ @cache__stored = true
204
+ @cache__collection.repo_collection << self
205
+ # TODO: big problem! once new model saved it should become buffer in cache!
189
206
  end
190
207
  else
191
- # debug __method__, __LINE__, "not dirty: #{to_h}"
208
+ # debug_model __method__, __LINE__, "not dirty: #{to_h}"
192
209
  # neither new nor dirty but
193
210
  # stay in the promise chain
194
211
  Promise.value(self)
@@ -208,7 +225,8 @@ module Volt
208
225
  self.class.fields_data.keys.each do |field|
209
226
  return true if changed?(field)
210
227
  end
211
- @__cache__created_in_cache
228
+ # if not stored then I'm dirty
229
+ !@cache__stored
212
230
  end
213
231
 
214
232
  # Destroys (deletes) the model in database.
@@ -252,7 +270,7 @@ module Volt
252
270
  # #######################################
253
271
 
254
272
  def model.fail_if_read_only(what)
255
- if @__cache__collection.read_only
273
+ if @cache__collection.read_only
256
274
  raise RuntimeError, "cannot #{what} for read only cache collection/model"
257
275
  end
258
276
  end
@@ -260,26 +278,26 @@ module Volt
260
278
 
261
279
  # private
262
280
  def model.uncache
263
- @__cache__associations.clear if @__cache__associations
281
+ @cache__associations.clear if @cache__associations
264
282
  if false
265
283
  instance_variables.each do |v|
266
284
  if v.to_s =~ /__cache__/
267
- # debug __method__, __LINE__, "removing instance variable '#{v}'"
285
+ # debug_model __method__, __LINE__, "removing instance variable '#{v}'"
268
286
  set_instance_variable(v, nil)
269
287
  end
270
288
  end
271
289
  elsif false
272
- @__cache__associations.clear if @__cache__associations
290
+ @cache__associations.clear if @cache__associations
273
291
  instance_variables.each do |v|
274
292
  if v.to_s =~ /__cache__/
275
- # debug __method__, __LINE__, "removing instance variable '#{v}'"
293
+ # debug_model __method__, __LINE__, "removing instance variable '#{v}'"
276
294
  remove_instance_variable(v)
277
295
  end
278
296
  end
279
297
  # WARNING - assumes no singleton methods other than those we've attached
280
298
  singleton_methods.each do |m|
281
- unless m == :debug || m == :uncache
282
- # debug __method__, __LINE__, "removing singleton method '#{m}'"
299
+ unless m == :debug_model || m == :uncache
300
+ # debug_model __method__, __LINE__, "removing singleton method '#{m}'"
283
301
  @@___m___ = m # m is out of scope in class << self TODO: anything nicer?
284
302
  class << self # weird syntax to remove singleton method
285
303
  remove_method(@@___m___)
@@ -288,7 +306,7 @@ module Volt
288
306
  end
289
307
  @@___m___ = nil
290
308
  class << self
291
- remove_method(:debug)
309
+ remove_method(:debug_model)
292
310
  remove_method(:uncache)
293
311
  end
294
312
  end
@@ -302,10 +320,10 @@ module Volt
302
320
  #
303
321
  # Raise error unless caller's class namespace is Volt::RepoCache.
304
322
  def model.refresh_association(association)
305
- # debug __method__, __LINE__, "association=#{association.foreign_name}"
323
+ # debug_model __method__, __LINE__, "association=#{association.foreign_name}"
306
324
  # refresh the association query
307
325
  result = get_association(association, refresh: true)
308
- # debug __method__, __LINE__, "#{self} association=#{association} result=#{result}"
326
+ # debug_model __method__, __LINE__, "#{self} association=#{association} result=#{result}"
309
327
  end
310
328
  model.singleton_class.send(:private, :refresh_association)
311
329
 
@@ -322,22 +340,22 @@ module Volt
322
340
  # (e.g. console) running.
323
341
  # Returns a promise with destroyed model proxy as value.
324
342
  def model.__destroy__
325
- # debug __method__, __LINE__
343
+ # debug_model __method__, __LINE__
326
344
  fail_if_read_only(__method__)
327
- # debug __method__, __LINE__
328
- promise = if created_in_cache? || new?
329
- Promise.value(self)
330
- else
345
+ # debug_model __method__, __LINE__
346
+ promise = if stored?
331
347
  destroy(caller: self)
348
+ else
349
+ Promise.value(self)
332
350
  end
333
- # debug __method__, __LINE__
351
+ # debug_model __method__, __LINE__
334
352
  promise.then do |m|
335
- # debug __method__, __LINE__, "destroy promise resolved to #{m}"
336
- @__cache__collection.destroyed(self)
353
+ # debug_model __method__, __LINE__, "destroy promise resolved to #{m}"
354
+ @cache__collection.destroyed(self)
337
355
  uncache
338
356
  self
339
357
  end.fail do |errors|
340
- # debug __method__, __LINE__, "destroy failed => #{errors}"
358
+ # debug_model __method__, __LINE__, "destroy failed => #{errors}"
341
359
  errors
342
360
  end
343
361
  end
@@ -355,23 +373,23 @@ module Volt
355
373
  # Relies on cached collections notifying
356
374
  # associated models when to refresh.
357
375
  def model.get_association(assoc, refresh: false)
358
- # debug __method__, __LINE__, "#{self.class.name}:#{id} assoc=#{assoc.foreign_name} refresh: #{refresh}"
376
+ # debug_model __method__, __LINE__, "#{self.class.name}:#{id} assoc=#{assoc.foreign_name} refresh: #{refresh}"
359
377
  foreign_name = assoc.foreign_name
360
- @__cache__associations[foreign_name] = nil if refresh
361
- prior = @__cache__associations[foreign_name]
378
+ @cache__associations[foreign_name] = nil if refresh
379
+ prior = @cache__associations[foreign_name]
362
380
  local_id = self.send(assoc.local_id_field)
363
381
  foreign_id_field = assoc.foreign_id_field
364
- # debug __method__, __LINE__, "foreign_id_field=#{foreign_id_field}"
382
+ # debug_model __method__, __LINE__, "foreign_id_field=#{foreign_id_field}"
365
383
  result = if prior && match?(prior, foreign_id_field, local_id)
366
384
  prior
367
385
  else
368
386
  q = {foreign_id_field => local_id}
369
- # debug __method__, __LINE__
387
+ # debug_model __method__, __LINE__
370
388
  r = assoc.foreign_collection.query(q) || []
371
- # debug __method__, __LINE__
372
- @__cache__associations[foreign_name] = assoc.has_many? ? ModelArray.new(contents: r) : r.first
389
+ # debug_model __method__, __LINE__
390
+ @cache__associations[foreign_name] = assoc.has_many? ? ModelArray.new(contents: r) : r.first
373
391
  end
374
- # debug __method__, __LINE__
392
+ # debug_model __method__, __LINE__
375
393
  result
376
394
  end
377
395
  model.singleton_class.send(:private, :get_association)
@@ -434,7 +452,7 @@ module Volt
434
452
  # has_many then any prior associated values
435
453
  # will be marked for destruction.
436
454
  #
437
- # NB we don't immediately update local @__cache__associations,
455
+ # NB we don't immediately update local @cache__associations,
438
456
  # but wait to be notified by associated collections
439
457
  # of changes we make to them. This ensures that
440
458
  # if changes are made to those collections that
@@ -536,11 +554,11 @@ module Volt
536
554
  fail_if_read_only(__method__)
537
555
  validate_ownership(assoc, other, require_foreign_id: false) do |prior_foreign_id|
538
556
  # after validation we can be sure prior_foreign_id == self.id
539
- # debug __method__, __LINE__
557
+ # debug_model __method__, __LINE__
540
558
  unless prior_foreign_id
541
559
  other.send(Util.setter(assoc.foreign_id_field), id)
542
560
  end
543
- # debug __method__, __LINE__
561
+ # debug_model __method__, __LINE__
544
562
  end
545
563
  end
546
564
  model.singleton_class.send(:private, :set_foreign_id)
@@ -572,9 +590,9 @@ module Volt
572
590
  # if it does not match this model's id. Otherwise return true
573
591
  # if the foreign id is not nil. Yield to given block if provided.
574
592
  def model.validate_ownership(assoc, other, require_foreign_id: true, &block)
575
- # debug __method__, __LINE__
593
+ # debug_model __method__, __LINE__
576
594
  foreign_id = other.send(assoc.foreign_id_field)
577
- # debug __method__, __LINE__
595
+ # debug_model __method__, __LINE__
578
596
  if (foreign_id && foreign_id != self.id) || (require_foreign_id && foreign_id.nil?)
579
597
  raise RuntimeError, "#{other} should belong to #{self} or no-one else"
580
598
  end
@@ -617,15 +635,15 @@ module Volt
617
635
  # from flushing associates.
618
636
  def model.flush_associations
619
637
  promises = []
620
- @__cache__collection.associations.values.each do |assoc|
638
+ @cache__collection.associations.values.each do |assoc|
621
639
  if assoc.has_any?
622
- # debug __method__, __LINE__, "association => '#{association}'"
640
+ # debug_model __method__, __LINE__, "association => '#{association}'"
623
641
  model_or_array = send(assoc.foreign_name)
624
- # debug __method__, __LINE__, "model_or_array => '#{model_or_array}'"
642
+ # debug_model __method__, __LINE__, "model_or_array => '#{model_or_array}'"
625
643
  Util.arrify(model_or_array).each do |model|
626
644
  promises << model.flush!
627
645
  end
628
- # debug __method__, __LINE__
646
+ # debug_model __method__, __LINE__
629
647
  end
630
648
  end
631
649
  Promise.when(*promises)
@@ -636,31 +654,31 @@ module Volt
636
654
  # Marks all has_one or has_many models for destruction
637
655
  def model.mark_associations_for_destruction
638
656
  fail_if_read_only(__method__)
639
- @__cache__collection.associations.values.each do |assoc|
657
+ @cache__collection.associations.values.each do |assoc|
640
658
  if assoc.has_any?
641
- # debug __method__, __LINE__, "association => '#{association}'"
659
+ # debug_model __method__, __LINE__, "association => '#{association}'"
642
660
  model_or_array = send(assoc.foreign_name)
643
661
  if model_or_array
644
- # debug __method__, __LINE__, "model_or_array => '#{model_or_array}'"
662
+ # debug_model __method__, __LINE__, "model_or_array => '#{model_or_array}'"
645
663
  Util.arrify(model_or_array).each do |model|
646
664
  model.mark_for_destruction!
647
665
  end
648
- # debug __method__, __LINE__
666
+ # debug_model __method__, __LINE__
649
667
  end
650
668
  end
651
669
  end
652
670
  end
653
671
  model.singleton_class.send(:private, :mark_associations_for_destruction)
654
672
 
655
- def model.debug(method, line, msg = nil)
656
- s = ">>> #{self.class.name}##{method}[#{line}] : #{msg}"
673
+ def model.debug_model(method, line, msg = nil)
674
+ s = "#{__FILE__}[#{line}]:#{self.class.name}##{method}: #{msg}"
657
675
  if RUBY_PLATFORM == 'opal'
658
676
  Volt.logger.debug s
659
677
  else
660
678
  puts s
661
679
  end
662
680
  end
663
- model.singleton_class.send(:private, :debug)
681
+ model.singleton_class.send(:private, :debug_model)
664
682
 
665
683
  end
666
684
 
@@ -160,12 +160,9 @@ module Volt
160
160
  def __remove__(model, error_if_absent: true)
161
161
  index = index {|e| e.id == model.id }
162
162
  if index
163
- result = __delete_at__(index)
164
- # debug __method__, __LINE__, "deleted #{result.class.name} #{result.id}"
165
- result
163
+ __delete_at__(index)
166
164
  elsif error_if_absent
167
165
  msg = "could not find #{model.class.name} with id #{model.id} to delete"
168
- # debug __method__, __LINE__, msg
169
166
  raise RuntimeError, msg
170
167
  end
171
168
  end
@@ -57,20 +57,11 @@ module Volt
57
57
  end
58
58
  end
59
59
 
60
- def debug(method, line, msg = nil)
61
- s = ">>> #{self.class.name}##{method}[#{line}] : #{msg}"
62
- if RUBY_PLATFORM == 'opal'
63
- Volt.logger.debug s
64
- else
65
- puts s
66
- end
67
- end
68
-
69
60
  def time(method, line, msg = nil)
70
61
  t1 = Time.now
71
62
  r = yield
72
63
  t2 = Time.now
73
- debug(method, line, "#{msg} : took #{t2 - t1} seconds")
64
+ debug 1, ->{['nil file', line, method, "#{msg} : took #{t2 - t1} seconds"]}
74
65
  r
75
66
  end
76
67
  end
@@ -1,5 +1,5 @@
1
1
  module Volt
2
2
  module RepoCache
3
- VERSION = "0.1.6"
3
+ VERSION = "0.1.7"
4
4
  end
5
5
  end
@@ -18,21 +18,4 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "volt", "~> 0.9.6"
22
- spec.add_development_dependency "rake"
23
-
24
- # Testing gems
25
- spec.add_development_dependency 'rspec', '~> 3.2.0'
26
- spec.add_development_dependency 'opal-rspec', '~> 0.4.2'
27
- spec.add_development_dependency 'capybara', '~> 2.4.4'
28
- spec.add_development_dependency 'selenium-webdriver', '~> 2.47.0'
29
- spec.add_development_dependency 'chromedriver-helper', '~> 1.0.0'
30
- spec.add_development_dependency 'poltergeist', '~> 1.6.0'
31
-
32
- # Gems to run the dummy app
33
- spec.add_development_dependency 'volt-mongo', '0.1.1'
34
- spec.add_development_dependency 'volt-bootstrap', '~> 0.1.0'
35
- spec.add_development_dependency 'volt-bootstrap_jumbotron_theme', '~> 0.1.0'
36
- spec.add_development_dependency 'volt-user_templates', '~> 0.4.0'
37
- spec.add_development_dependency 'thin', '~> 1.6.0'
38
21
  end
metadata CHANGED
@@ -1,197 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: volt-repo_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Colin Gunn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-03 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: volt
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 0.9.6
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: 0.9.6
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: 3.2.0
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: 3.2.0
55
- - !ruby/object:Gem::Dependency
56
- name: opal-rspec
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 0.4.2
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 0.4.2
69
- - !ruby/object:Gem::Dependency
70
- name: capybara
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 2.4.4
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 2.4.4
83
- - !ruby/object:Gem::Dependency
84
- name: selenium-webdriver
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: 2.47.0
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: 2.47.0
97
- - !ruby/object:Gem::Dependency
98
- name: chromedriver-helper
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: 1.0.0
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: 1.0.0
111
- - !ruby/object:Gem::Dependency
112
- name: poltergeist
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: 1.6.0
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: 1.6.0
125
- - !ruby/object:Gem::Dependency
126
- name: volt-mongo
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - '='
130
- - !ruby/object:Gem::Version
131
- version: 0.1.1
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - '='
137
- - !ruby/object:Gem::Version
138
- version: 0.1.1
139
- - !ruby/object:Gem::Dependency
140
- name: volt-bootstrap
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: 0.1.0
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: 0.1.0
153
- - !ruby/object:Gem::Dependency
154
- name: volt-bootstrap_jumbotron_theme
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - "~>"
158
- - !ruby/object:Gem::Version
159
- version: 0.1.0
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
165
- - !ruby/object:Gem::Version
166
- version: 0.1.0
167
- - !ruby/object:Gem::Dependency
168
- name: volt-user_templates
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - "~>"
172
- - !ruby/object:Gem::Version
173
- version: 0.4.0
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - "~>"
179
- - !ruby/object:Gem::Version
180
- version: 0.4.0
181
- - !ruby/object:Gem::Dependency
182
- name: thin
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - "~>"
186
- - !ruby/object:Gem::Version
187
- version: 1.6.0
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - "~>"
193
- - !ruby/object:Gem::Version
194
- version: 1.6.0
11
+ date: 2016-04-28 00:00:00.000000000 Z
12
+ dependencies: []
195
13
  description: Cache multiple collections or query based subsets from any Volt repository.
196
14
  Provides faster and simpler client-side processing. Reduces the burden of promise
197
15
  handling. Changes - updates, creates and destroys - can be saved (flushed) back