volt-repo_cache 0.1.6 → 0.1.7

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