Class: QueryTracker

Inherits:
Object show all
Defined in:
app/volt/tasks/live_query/query_tracker.rb

Overview

The query tracker runs queries and then tracks the changes that take place.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(live_query, data_store) ⇒ QueryTracker

Returns a new instance of QueryTracker.



5
6
7
8
9
10
11
12
13
# File 'app/volt/tasks/live_query/query_tracker.rb', line 5

def initialize(live_query, data_store)
  @live_query = live_query
  @data_store = data_store

  # Stores the list of id's currently associated with this query
  @current_ids = []
  @results = []
  @results_hash = {}
end

Instance Attribute Details

#resultsObject

Returns the value of attribute results.



4
5
6
# File 'app/volt/tasks/live_query/query_tracker.rb', line 4

def results
  @results
end

Instance Method Details

#detect_added_and_moved(skip_channel) ⇒ Object

Loop through the new list, tracking in the old, notifies of any that have been added or moved.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'app/volt/tasks/live_query/query_tracker.rb', line 56

def detect_added_and_moved(skip_channel)
  previous_index = 0
  @current_ids.each_with_index do |id, index|
    if (cur_previous = @previous_ids[previous_index]) && cur_previous == id
      # Same in both previous and new
      previous_index += 1
      next
    end

    # We have an item that didn't match the current position's previous
    # TODO: make a hash so we don't have to do include?
    if @previous_ids.include?(id)
      # The location from the previous has changed, move to correct location.

      # Remove from previous_ids, since it will be moved and we will be past it.
      @previous_ids.delete(id)

      @live_query.notify_moved(id, index, skip_channel)
    else
      # TODO: Faster lookup
      data = @results_hash[id]
      @live_query.notify_added(index, data, skip_channel)
    end
  end
end

#detect_changed(skip_channel) ⇒ Object

Finds all items in the previous results that have new values, and alerts of changes.



84
85
86
87
88
89
90
91
92
93
# File 'app/volt/tasks/live_query/query_tracker.rb', line 84

def detect_changed(skip_channel)
  not_added_or_removed = @previous_ids & @current_ids

  not_added_or_removed.each do |id|
    if @previous_results_hash[id] != (data = @results_hash[id])
      # Data hash changed
      @live_query.notify_changed(id, data, skip_channel)
    end
  end
end

#detect_removed(skip_channel) ⇒ Object



43
44
45
46
47
48
49
50
51
52
# File 'app/volt/tasks/live_query/query_tracker.rb', line 43

def detect_removed(skip_channel)
  # Removed models
  removed_ids = @previous_ids - @current_ids
  if removed_ids.size > 0
    @live_query.notify_removed(removed_ids, skip_channel)
  end

  # Update @previous_ids to relect the removed
  @previous_ids = @previous_ids & @current_ids
end

#process_changes(skip_channel) ⇒ Object

Looks at the changes in the last run and sends out notices all changes.



33
34
35
36
37
38
39
40
41
# File 'app/volt/tasks/live_query/query_tracker.rb', line 33

def process_changes(skip_channel)
  if @previous_ids
    detect_removed(skip_channel)

    detect_added_and_moved(skip_channel)

    detect_changed(skip_channel)
  end
end

#run(skip_channel = nil) ⇒ Object

Runs the query, stores the results and updates the current_ids



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'app/volt/tasks/live_query/query_tracker.rb', line 16

def run(skip_channel = nil)
  @previous_results = @results
  @previous_results_hash = @results_hash
  @previous_ids = @current_ids

  # Run the query again
  @results = @data_store.query(@live_query.collection, @live_query.query)

  # Update the current_ids
  @current_ids = @results.map { |r| r['_id'] }
  @results_hash = Hash[@results.map { |r| [r['_id'], r] }]

  process_changes(skip_channel)
end