Class: Persistors::ArrayStore

Inherits:
Store show all
Defined in:
lib/volt/models/persistors/array_store.rb

Constant Summary collapse

@@query_pool =
QueryListenerPool.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Store

#read_new_model, #saved?

Methods inherited from Base

#changed

Constructor Details

#initialize(model, tasks = nil) ⇒ ArrayStore

Returns a new instance of ArrayStore.



15
16
17
18
19
20
# File 'lib/volt/models/persistors/array_store.rb', line 15

def initialize(model, tasks=nil)
  super

  @query = ReactiveValue.from_hash(@model.options[:query] || {})

end

Instance Attribute Details

#modelObject (readonly)

Returns the value of attribute model.



8
9
10
# File 'lib/volt/models/persistors/array_store.rb', line 8

def model
  @model
end

#stateObject

Returns the value of attribute state.



9
10
11
# File 'lib/volt/models/persistors/array_store.rb', line 9

def state
  @state
end

Class Method Details

.query_poolObject



11
12
13
# File 'lib/volt/models/persistors/array_store.rb', line 11

def self.query_pool
  @@query_pool
end

Instance Method Details

#add(index, data) ⇒ Object

Called from backend



111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/volt/models/persistors/array_store.rb', line 111

def add(index, data)
  $loading_models = true

  new_options = @model.options.merge(path: @model.path + [:[]], parent: @model)

  # Find the existing model, or create one
  new_model = @@identity_map.find(data['_id']) { Model.new(data.symbolize_keys, new_options) }

  @model.insert(index, new_model)

  $loading_models = false
end

#added(model, index) ⇒ Object

When a model is added to this collection, we call its “changed” method. This should trigger a save.



150
151
152
153
154
155
156
157
158
159
# File 'lib/volt/models/persistors/array_store.rb', line 150

def added(model, index)
  unless defined?($loading_models) && $loading_models
    model.persistor.changed
  end

  if model.persistor
    # Tell the persistor it was added
    model.persistor.add_to_collection
  end
end

#change_state_to(new_state) ⇒ Object

Called from the QueryListener when the data is loaded



50
51
52
53
54
55
# File 'lib/volt/models/persistors/array_store.rb', line 50

def change_state_to(new_state)
  @state = new_state

  # Trigger changed on the 'state' method
  @model.trigger_for_methods!('changed', :state, :loaded?)
end

#channel_nameObject



143
144
145
# File 'lib/volt/models/persistors/array_store.rb', line 143

def channel_name
  @model.path[-1]
end

#event_added(event, scope_provider, first) ⇒ Object



27
28
29
30
31
# File 'lib/volt/models/persistors/array_store.rb', line 27

def event_added(event, scope_provider, first)
  puts "ADD EV: #{event} - #{first}"
  # First event, we load the data.
  load_data if first
end

#event_removed(event, no_more_events) ⇒ Object



33
34
35
36
37
38
# File 'lib/volt/models/persistors/array_store.rb', line 33

def event_removed(event, no_more_events)
  # Remove listener where there are no more events on this model
  if no_more_events && @query_listener && @model.listeners.size == 0
    stop_listening
  end
end

#find(query = {}) ⇒ Object



104
105
106
107
108
# File 'lib/volt/models/persistors/array_store.rb', line 104

def find(query={})
  model = ArrayModel.new([], @model.options.merge(:query => query))

  return ReactiveValue.new(model)
end

#load_dataObject

Called the first time data is requested from this collection



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/volt/models/persistors/array_store.rb', line 58

def load_data
  # Don't load data from any queried
  if @state == :not_loaded || @state == :dirty
    puts "Load Data"
    change_state_to :loading

    @query_changed_listener.remove if @query_changed_listener
    if @query.reactive?
      # Query might change, change the query when it does
      @query_changed_listener = @query.on('changed') do
        stop_listening

        load_data
      end
    end

    run_query(@model, @query.deep_cur)
  end
end

#loadedObject

Called when a collection loads



23
24
25
# File 'lib/volt/models/persistors/array_store.rb', line 23

def loaded
  change_state_to :not_loaded
end

#remove(ids) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/volt/models/persistors/array_store.rb', line 124

def remove(ids)
  $loading_models = true
  ids.each do |id|
    puts "delete at: #{id} on #{@model.inspect}"

    # TODO: optimize this delete so we don't need to loop
    @model.each_with_index do |model, index|
      puts "#{model._id.inspect} vs #{id.inspect} - #{index}"
      if model._id == id
        del = @model.delete_at(index)
        puts "DELETED AT #{index}: #{del.inspect} - #{@model.inspect}"
        break
      end
    end
  end

  $loading_models = false
end

#removed(model) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/volt/models/persistors/array_store.rb', line 161

def removed(model)
  if model.persistor
    # Tell the persistor it was removed
    model.persistor.remove_from_collection
  end

  if $loading_models
    return
  else
    puts "delete #{channel_name} - #{model.attributes[:_id]}"
    @tasks.call('StoreTasks', 'delete', channel_name, model.attributes[:_id])
  end
end

#run_query(model, query = {}) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/volt/models/persistors/array_store.rb', line 84

def run_query(model, query={})
  collection = model.path.last
  # Scope to the parent
  if model.path.size > 1
    parent = model.parent

    parent.persistor.ensure_setup if parent.persistor

    if parent && (attrs = parent.attributes) && attrs[:_id].true?
      query[:"#{model.path[-3].singularize}_id"] = attrs[:_id]
    end
  end

  @query_listener = @@query_pool.lookup(collection, query) do
    # Create if it does not exist
    QueryListener.new(@@query_pool, @tasks, collection, query)
  end
  @query_listener.add_store(model.persistor)
end

#stop_listeningObject

Called when an event is removed and we no longer want to keep in sync with the database.



42
43
44
45
46
47
# File 'lib/volt/models/persistors/array_store.rb', line 42

def stop_listening
  @query_listener.remove_store(self)
  @query_listener = nil

  change_state_to :dirty
end

#unload_dataObject

Clear out the models data, since we’re not listening anymore.



79
80
81
82
# File 'lib/volt/models/persistors/array_store.rb', line 79

def unload_data
  change_state_to :not_loaded
  @model.clear
end