Class: ActiveTracker::Model

Inherits:
Object
  • Object
show all
Defined in:
lib/active_tracker/model.rb

Defined Under Namespace

Classes: NotFound

Constant Summary collapse

PREFIX =
"/ActiveTracker".freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key, value, persisted = true) ⇒ Model

Returns a new instance of Model.



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/active_tracker/model.rb', line 113

def initialize(key, value, persisted = true)
  @attrs = {key: key, persisted: persisted}
  key = key.gsub(/^A#{PREFIX}/, "")
  parts = key.split("/")
  _ = parts.shift # Starts with a /
  _ = parts.shift # then comes PREFIX
  @attrs[:type] = parts.shift
  @attrs[:data_type] = parts.pop
  t = parts.shift
  @attrs[:log_at] = Time.parse(t) rescue t
  @attrs[:tags] = {}
  parts.sort.each do |part|
    tag_name, tag_value = part.split(":")
    if tag_name == "id"
      @attrs[:id] = tag_value
    else
      @attrs[:tags][tag_name.to_sym] = CGI.unescape("#{tag_value}")
    end
  end
  value = JSON.parse(value)
  self.send("data=", value)
  value.each do |key, value|
    self.send("#{key}=", value)
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, value = nil) ⇒ Object



143
144
145
146
147
148
149
# File 'lib/active_tracker/model.rb', line 143

def method_missing(name, value = nil)
  if name.to_s.end_with?("=")
    @attrs[name.to_s.gsub("=", "").to_sym] = value
  else
    @attrs[name]
  end
end

Class Method Details

.all(type, tags: {}, data_type: nil) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/active_tracker/model.rb', line 27

def self.all(type, tags: {}, data_type: nil)
  return [] if ActiveTracker.connection_offline?

  keys = "#{PREFIX}/#{type}/"

  keys += "*"

  keys += tags.sort_by { |k,v| k.to_s }.map do |k,v|
    "#{k}:#{CGI.escape(v.to_s)}"
  end.join("*")

  keys += "*" unless keys.end_with?("*")

  if data_type
    keys += "/#{data_type}"
  end

  connection = ActiveTracker.connection
  result = connection.keys(keys).sort { |a,b| b <=> a }.map { |key| self.new(key, {}.to_json) }
end

.delete(key) ⇒ Object



23
24
25
# File 'lib/active_tracker/model.rb', line 23

def self.delete(key)
  ActiveTracker.connection.del(key)
end

.find(key) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/active_tracker/model.rb', line 7

def self.find(key)
  return nil if ActiveTracker.connection_offline?

  connection = ActiveTracker.connection
  value = connection.get(key)
  if value.nil?
    raise NotFound.new("Couldn't find entry - #{key}")
  else
    if value.start_with?(PREFIX)
      find(value)
    else
      self.new(key, value)
    end
  end
end

.find_or_create(type, tags: {}, data_type: nil) {|obj| ... } ⇒ Object

Yields:

  • (obj)


79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/active_tracker/model.rb', line 79

def self.find_or_create(type, tags: {}, data_type: nil)
  keys = all(type, tags: tags, data_type: data_type)
  if keys.length > 0
    obj = find(keys.first.key) rescue nil
  end

  if !obj
    obj = new(generate_key(type, "-", tags, data_type), {}.to_json, false)
  end
  yield obj
  obj.save
end

.generate_key(type, log_time, tags, data_type) ⇒ Object



48
49
50
51
52
53
54
55
56
57
# File 'lib/active_tracker/model.rb', line 48

def self.generate_key(type, log_time, tags, data_type)
  key = PREFIX + "/#{type}/#{log_time}"
  converted_tags = tags.sort_by { |k,v| k.to_s }.map {|k,v| "#{k}:#{CGI.escape(v.to_s)}"}
  if converted_tags.any?
    key = key + "/" + converted_tags.join("/")
  end
  key += "/#{data_type}"
  key.gsub!(%r{/{2,}}, '/')
  key
end

.paginate(items, page, per_page) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/active_tracker/model.rb', line 92

def self.paginate(items, page, per_page)
  page = (page || 1).to_i

  total = items.length
  start_point = (page - 1) * per_page

  items = items[start_point, per_page]

  total_pages = total / per_page
  total_pages += 1 if (total % per_page != 0)

  window = []
  window << page - 2 if page > 2
  window << page - 1 if page > 1
  window << page
  window << page + 1 if (total_pages - page) > 0
  window << page + 2 if (total_pages - page) > 1

  [items, {total: total, total_pages: total_pages, page: page, window: window}]
end

.save(type, data, tags: {}, data_type: nil, expiry: 7.days, log_at: Time.current) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/active_tracker/model.rb', line 59

def self.save(type, data, tags: {}, data_type: nil, expiry: 7.days, log_at: Time.current)
  return nil if ActiveTracker.connection_offline?

  if log_at.respond_to?(:strftime)
    log_time = log_at.strftime("%Y%m%d%H%M%S")
  else
    log_time = log_at
  end
  key = generate_key(type, log_time, tags, data_type)
  value = data.to_json
  connection = ActiveTracker.connection
  connection.set(key, value)
  connection.expire(key, expiry)
  if tags[:id].present?
    connection.set(tags[:id], key)
    connection.expire(tags[:id], expiry)
  end
  key
end

Instance Method Details

#saveObject



139
140
141
# File 'lib/active_tracker/model.rb', line 139

def save
  self.class.save(@attrs[:type], data, tags: {id: id}.merge(@attrs[:tags]), data_type: @attrs[:data_type], expiry: expiry, log_at: log_at)
end