redistat 0.1.1 → 0.2.0
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.
- data/README.md +5 -0
- data/lib/redistat.rb +4 -2
- data/lib/redistat/database.rb +1 -0
- data/lib/redistat/event.rb +12 -24
- data/lib/redistat/finder.rb +41 -31
- data/lib/redistat/key.rb +40 -21
- data/lib/redistat/label.rb +27 -16
- data/lib/redistat/model.rb +14 -39
- data/lib/redistat/options.rb +43 -0
- data/lib/redistat/summary.rb +13 -5
- data/lib/redistat/version.rb +1 -1
- data/redistat.gemspec +1 -0
- data/spec/event_spec.rb +4 -4
- data/spec/finder_spec.rb +42 -26
- data/spec/key_spec.rb +63 -12
- data/spec/label_spec.rb +28 -18
- data/spec/model_spec.rb +45 -8
- data/spec/options_spec.rb +36 -0
- data/spec/summary_spec.rb +5 -5
- metadata +22 -5
data/README.md
CHANGED
@@ -66,6 +66,11 @@ When retrieving statistics for a given date range, Redistat figures out how to d
|
|
66
66
|
* Anything else that becomes apparent after real-world use.
|
67
67
|
|
68
68
|
|
69
|
+
## Credits
|
70
|
+
|
71
|
+
[Global Personals](http://globalpersonals.co.uk/) deserves a thank you. Currently the primary user of Redistat, they've allowed me to spend some company time to further develop the project.
|
72
|
+
|
73
|
+
|
69
74
|
## Note on Patches/Pull Requests
|
70
75
|
|
71
76
|
* Fork the project.
|
data/lib/redistat.rb
CHANGED
@@ -9,9 +9,10 @@ require 'time_ext'
|
|
9
9
|
require 'json'
|
10
10
|
require 'digest/sha1'
|
11
11
|
|
12
|
-
require 'redistat/
|
12
|
+
require 'redistat/options'
|
13
13
|
require 'redistat/connection'
|
14
14
|
require 'redistat/database'
|
15
|
+
require 'redistat/collection'
|
15
16
|
require 'redistat/date'
|
16
17
|
require 'redistat/date_helper'
|
17
18
|
require 'redistat/event'
|
@@ -34,8 +35,9 @@ module Redistat
|
|
34
35
|
|
35
36
|
KEY_NEXT_ID = ".next_id"
|
36
37
|
KEY_EVENT = ".event:"
|
37
|
-
KEY_LEBELS = "Redistat.
|
38
|
+
KEY_LEBELS = "Redistat.labels:" # used for reverse label hash lookup
|
38
39
|
KEY_EVENT_IDS = ".event_ids"
|
40
|
+
LABEL_INDEX = ".label_index:"
|
39
41
|
GROUP_SEPARATOR = "/"
|
40
42
|
|
41
43
|
class InvalidOptions < ArgumentError; end
|
data/lib/redistat/database.rb
CHANGED
data/lib/redistat/event.rb
CHANGED
@@ -1,40 +1,28 @@
|
|
1
1
|
module Redistat
|
2
2
|
class Event
|
3
3
|
include Database
|
4
|
+
include Options
|
4
5
|
|
5
6
|
attr_reader :id
|
6
7
|
attr_reader :key
|
7
|
-
attr_reader :connection_ref
|
8
8
|
|
9
9
|
attr_accessor :stats
|
10
10
|
attr_accessor :meta
|
11
|
-
attr_accessor :options
|
12
11
|
|
13
|
-
def initialize(scope, label = nil, date = nil, stats = {}, options = {}, meta = {}, is_new = true)
|
14
|
-
@options = parse_options(options)
|
15
|
-
@connection_ref = @options[:connection_ref]
|
16
|
-
@key = Key.new(scope, label, date, @options)
|
17
|
-
@stats = stats ||= {}
|
18
|
-
@meta = meta ||= {}
|
19
|
-
@new = is_new
|
20
|
-
end
|
21
|
-
|
22
|
-
def db
|
23
|
-
super(@connection_ref)
|
24
|
-
end
|
25
|
-
|
26
|
-
def parse_options(options)
|
27
|
-
default_options.each do |opt, val|
|
28
|
-
options[opt] = val if options[opt].nil?
|
29
|
-
end
|
30
|
-
options
|
31
|
-
end
|
32
|
-
|
33
12
|
def default_options
|
34
13
|
{ :depth => :hour,
|
35
14
|
:store_event => false,
|
36
15
|
:connection_ref => nil,
|
37
|
-
:enable_grouping => true
|
16
|
+
:enable_grouping => true,
|
17
|
+
:label_indexing => true }
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(scope, label = nil, date = nil, stats = {}, opts = {}, meta = {}, is_new = true)
|
21
|
+
parse_options(opts)
|
22
|
+
@key = Key.new(scope, label, date, @options)
|
23
|
+
@stats = stats ||= {}
|
24
|
+
@meta = meta ||= {}
|
25
|
+
@new = is_new
|
38
26
|
end
|
39
27
|
|
40
28
|
def new?
|
@@ -75,7 +63,7 @@ module Redistat
|
|
75
63
|
|
76
64
|
def save
|
77
65
|
return false if !self.new?
|
78
|
-
Summary.update_all(@key, @stats, depth_limit, @
|
66
|
+
Summary.update_all(@key, @stats, depth_limit, @options)
|
79
67
|
if @options[:store_event]
|
80
68
|
@id = self.next_id
|
81
69
|
db.hmset("#{self.scope}#{KEY_EVENT}#{@id}",
|
data/lib/redistat/finder.rb
CHANGED
@@ -40,8 +40,12 @@ module Redistat
|
|
40
40
|
|
41
41
|
attr_reader :options
|
42
42
|
|
43
|
-
def initialize(
|
44
|
-
|
43
|
+
def initialize(opts = {})
|
44
|
+
set_options(opts)
|
45
|
+
end
|
46
|
+
|
47
|
+
def options
|
48
|
+
@options ||= {}
|
45
49
|
end
|
46
50
|
|
47
51
|
def all(reload = false)
|
@@ -65,21 +69,27 @@ module Redistat
|
|
65
69
|
all.each_with_index(&block)
|
66
70
|
end
|
67
71
|
|
72
|
+
def children
|
73
|
+
build_key.children.map { |key|
|
74
|
+
self.class.new(options.merge(:label => key.label.to_s))
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
68
78
|
def connection_ref(ref)
|
69
|
-
reset! if
|
70
|
-
|
79
|
+
reset! if options[:connection_ref] != ref
|
80
|
+
options[:connection_ref] = ref
|
71
81
|
self
|
72
82
|
end
|
73
83
|
|
74
84
|
def scope(scope)
|
75
|
-
reset! if
|
76
|
-
|
85
|
+
reset! if !options[:scope].nil? && options[:scope].to_s != scope
|
86
|
+
options[:scope] = Scope.new(scope)
|
77
87
|
self
|
78
88
|
end
|
79
89
|
|
80
90
|
def label(label)
|
81
|
-
reset! if
|
82
|
-
|
91
|
+
reset! if !options[:label].nil? && options[:label].to_s != label
|
92
|
+
options[:label] = Label.new(label)
|
83
93
|
self
|
84
94
|
end
|
85
95
|
|
@@ -89,34 +99,34 @@ module Redistat
|
|
89
99
|
alias :date :dates
|
90
100
|
|
91
101
|
def from(date)
|
92
|
-
reset! if
|
93
|
-
|
102
|
+
reset! if options[:from] != date
|
103
|
+
options[:from] = date
|
94
104
|
self
|
95
105
|
end
|
96
106
|
|
97
107
|
def till(date)
|
98
|
-
reset! if
|
99
|
-
|
108
|
+
reset! if options[:till] != date
|
109
|
+
options[:till] = date
|
100
110
|
self
|
101
111
|
end
|
102
112
|
alias :until :till
|
103
113
|
|
104
114
|
def depth(unit)
|
105
|
-
reset! if
|
106
|
-
|
115
|
+
reset! if options[:depth] != unit
|
116
|
+
options[:depth] = unit
|
107
117
|
self
|
108
118
|
end
|
109
119
|
|
110
120
|
def interval(unit)
|
111
|
-
reset! if
|
112
|
-
|
121
|
+
reset! if options[:interval] != unit
|
122
|
+
options[:interval] = unit
|
113
123
|
self
|
114
124
|
end
|
115
125
|
|
116
|
-
def find(
|
117
|
-
set_options(
|
126
|
+
def find(opts = {})
|
127
|
+
set_options(opts)
|
118
128
|
raise InvalidOptions.new if !valid_options?
|
119
|
-
if
|
129
|
+
if options[:interval].nil? || !options[:interval]
|
120
130
|
find_by_magic
|
121
131
|
else
|
122
132
|
find_by_interval
|
@@ -130,14 +140,14 @@ module Redistat
|
|
130
140
|
opts.each do |key, value|
|
131
141
|
self.send(key, opts.delete(key)) if self.respond_to?(key)
|
132
142
|
end
|
133
|
-
|
143
|
+
self.options.merge!(opts)
|
134
144
|
end
|
135
145
|
|
136
|
-
def find_by_interval
|
146
|
+
def find_by_interval
|
137
147
|
raise InvalidOptions.new if !valid_options?
|
138
148
|
key = build_key
|
139
|
-
col = Collection.new(
|
140
|
-
col.total = Result.new(
|
149
|
+
col = Collection.new(options)
|
150
|
+
col.total = Result.new(options)
|
141
151
|
build_date_sets.each do |set|
|
142
152
|
set[:add].each do |date|
|
143
153
|
result = Result.new
|
@@ -152,11 +162,11 @@ module Redistat
|
|
152
162
|
col
|
153
163
|
end
|
154
164
|
|
155
|
-
def find_by_magic
|
165
|
+
def find_by_magic
|
156
166
|
raise InvalidOptions.new if !valid_options?
|
157
|
-
key =
|
158
|
-
col = Collection.new(
|
159
|
-
col.total = Result.new(
|
167
|
+
key = build_key
|
168
|
+
col = Collection.new(options)
|
169
|
+
col.total = Result.new(options)
|
160
170
|
col << col.total
|
161
171
|
build_date_sets.each do |set|
|
162
172
|
sum = Result.new
|
@@ -174,16 +184,16 @@ module Redistat
|
|
174
184
|
end
|
175
185
|
|
176
186
|
def valid_options?
|
177
|
-
return true if
|
187
|
+
return true if !options[:scope].blank? && !options[:label].blank? && !options[:from].blank? && !options[:till].blank?
|
178
188
|
false
|
179
189
|
end
|
180
190
|
|
181
191
|
def build_date_sets
|
182
|
-
Finder::DateSet.new(
|
192
|
+
Finder::DateSet.new(options[:from], options[:till], options[:depth], options[:interval])
|
183
193
|
end
|
184
194
|
|
185
195
|
def build_key
|
186
|
-
Key.new(
|
196
|
+
Key.new(options[:scope], options[:label])
|
187
197
|
end
|
188
198
|
|
189
199
|
def summarize_add_keys(sets, key, sum)
|
@@ -205,7 +215,7 @@ module Redistat
|
|
205
215
|
end
|
206
216
|
|
207
217
|
def db
|
208
|
-
super(
|
218
|
+
super(options[:connection_ref])
|
209
219
|
end
|
210
220
|
|
211
221
|
end
|
data/lib/redistat/key.rb
CHANGED
@@ -1,24 +1,22 @@
|
|
1
1
|
module Redistat
|
2
2
|
class Key
|
3
|
+
include Database
|
4
|
+
include Options
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
6
|
+
def default_options
|
7
|
+
{ :depth => :hour }
|
8
|
+
end
|
7
9
|
|
8
|
-
def initialize(scope, label_name = nil, time_stamp = nil,
|
9
|
-
|
10
|
-
|
10
|
+
def initialize(scope, label_name = nil, time_stamp = nil, opts = {})
|
11
|
+
parse_options(opts)
|
12
|
+
self.scope = scope
|
11
13
|
self.label = label_name if !label_name.nil?
|
12
14
|
self.date = time_stamp ||= Time.now
|
13
15
|
end
|
14
16
|
|
15
|
-
def default_options
|
16
|
-
{ :depth => :hour, :hashed_label => false }
|
17
|
-
end
|
18
|
-
|
19
17
|
def prefix
|
20
18
|
key = "#{@scope}"
|
21
|
-
key << "/#{label}" if !label.nil?
|
19
|
+
key << "/#{label.name}" if !label.nil?
|
22
20
|
key << ":"
|
23
21
|
key
|
24
22
|
end
|
@@ -26,30 +24,51 @@ module Redistat
|
|
26
24
|
def date=(input)
|
27
25
|
@date = (input.instance_of?(Redistat::Date)) ? input : Date.new(input) # Redistat::Date, not ::Date
|
28
26
|
end
|
27
|
+
attr_reader :date
|
29
28
|
|
30
29
|
def depth
|
31
|
-
|
30
|
+
options[:depth]
|
31
|
+
end
|
32
|
+
|
33
|
+
def scope
|
34
|
+
@scope.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
def scope=(input)
|
38
|
+
@scope = (input.instance_of?(Redistat::Scope)) ? input : Scope.new(input)
|
32
39
|
end
|
33
40
|
|
34
|
-
def label
|
35
|
-
@label.
|
41
|
+
def label=(input)
|
42
|
+
@label = (input.instance_of?(Redistat::Label)) ? input : Label.create(input, @options)
|
36
43
|
end
|
44
|
+
attr_reader :label
|
37
45
|
|
38
46
|
def label_hash
|
39
47
|
@label.hash
|
40
48
|
end
|
41
49
|
|
42
|
-
def
|
43
|
-
@label.
|
50
|
+
def parent
|
51
|
+
@parent ||= self.class.new(self.scope, @label.parent, self.date, @options) unless @label.parent.nil?
|
44
52
|
end
|
45
53
|
|
46
|
-
def
|
47
|
-
@label
|
54
|
+
def children
|
55
|
+
db.smembers("#{scope}#{LABEL_INDEX}#{@label}").map { |member|
|
56
|
+
child_label = [@label, member].reject { |i| i.nil? }
|
57
|
+
self.class.new(self.scope, child_label.join(GROUP_SEPARATOR), self.date, @options)
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def update_index
|
62
|
+
@label.groups.each do |label|
|
63
|
+
# break if label.parent.nil?
|
64
|
+
parent = (label.parent || "")
|
65
|
+
db.sadd("#{scope}#{LABEL_INDEX}#{parent}", label.me)
|
66
|
+
end
|
48
67
|
end
|
49
68
|
|
50
|
-
def groups
|
51
|
-
@groups ||=
|
52
|
-
self.class.new(@scope,
|
69
|
+
def groups # TODO: Is this useless?
|
70
|
+
@groups ||= @label.groups.map do |label|
|
71
|
+
self.class.new(@scope, label, self.date, @options)
|
53
72
|
end
|
54
73
|
end
|
55
74
|
|
data/lib/redistat/label.rb
CHANGED
@@ -1,48 +1,59 @@
|
|
1
1
|
module Redistat
|
2
2
|
class Label
|
3
3
|
include Database
|
4
|
+
include Options
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
def default_options
|
7
|
+
{ :hashed_label => false }
|
8
|
+
end
|
7
9
|
|
8
|
-
def self.create(name,
|
9
|
-
self.new(name,
|
10
|
+
def self.create(name, opts = {})
|
11
|
+
self.new(name, opts).save
|
10
12
|
end
|
11
13
|
|
12
|
-
def initialize(str,
|
13
|
-
|
14
|
+
def initialize(str, opts = {})
|
15
|
+
parse_options(opts)
|
14
16
|
@raw = str.to_s
|
15
17
|
end
|
16
|
-
|
17
|
-
def
|
18
|
-
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
@raw
|
19
21
|
end
|
20
22
|
|
21
23
|
def name
|
22
|
-
@options[:hashed_label] ? hash :
|
24
|
+
@options[:hashed_label] ? hash : self.to_s
|
23
25
|
end
|
24
26
|
|
25
27
|
def hash
|
26
|
-
@hash ||= Digest::SHA1.hexdigest(
|
28
|
+
@hash ||= Digest::SHA1.hexdigest(self.to_s)
|
27
29
|
end
|
28
30
|
|
29
31
|
def save
|
30
|
-
@saved =
|
32
|
+
@saved = db.hset(KEY_LEBELS, hash, self.to_s) if @options[:hashed_label]
|
31
33
|
self
|
32
34
|
end
|
33
35
|
|
34
36
|
def saved?
|
37
|
+
return true unless @options[:hashed_label]
|
35
38
|
@saved ||= false
|
36
39
|
end
|
37
40
|
|
41
|
+
def parent
|
42
|
+
@parent ||= groups[1] if groups.size > 1
|
43
|
+
end
|
44
|
+
|
45
|
+
def me
|
46
|
+
self.to_s.split(GROUP_SEPARATOR).last
|
47
|
+
end
|
48
|
+
|
38
49
|
def groups
|
39
|
-
return @groups
|
50
|
+
return @groups unless @groups.nil?
|
40
51
|
@groups = []
|
41
52
|
parent = ""
|
42
|
-
|
53
|
+
self.to_s.split(GROUP_SEPARATOR).each do |part|
|
43
54
|
if !part.blank?
|
44
|
-
group = ((parent.blank?) ? "" : "#{parent}
|
45
|
-
@groups << group
|
55
|
+
group = ((parent.blank?) ? "" : "#{parent}#{GROUP_SEPARATOR}") + part
|
56
|
+
@groups << Label.new(group)
|
46
57
|
parent = group
|
47
58
|
end
|
48
59
|
end
|
data/lib/redistat/model.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
module Redistat
|
2
2
|
module Model
|
3
|
-
include
|
3
|
+
include Database
|
4
|
+
include Options
|
4
5
|
|
5
6
|
def self.included(base)
|
6
7
|
base.extend(self)
|
7
8
|
end
|
8
9
|
|
10
|
+
|
9
11
|
#
|
10
12
|
# statistics store/fetch methods
|
11
13
|
#
|
12
14
|
|
13
|
-
def store(label, stats = {}, date = nil,
|
15
|
+
def store(label, stats = {}, date = nil, opts = {}, meta = {})
|
14
16
|
Event.new(name, label, date, stats, options.merge(opts), meta).save
|
15
17
|
end
|
16
18
|
alias :event :store
|
@@ -21,53 +23,30 @@ module Redistat
|
|
21
23
|
alias :lookup :fetch
|
22
24
|
|
23
25
|
def find(label, from, till, opts = {})
|
24
|
-
Finder.new( { :scope => name,
|
26
|
+
Finder.new( { :scope => self.name,
|
25
27
|
:label => label,
|
26
28
|
:from => from,
|
27
29
|
:till => till }.merge(options.merge(opts)) )
|
28
30
|
end
|
29
31
|
|
32
|
+
|
30
33
|
#
|
31
34
|
# options methods
|
32
35
|
#
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
def hashed_label(boolean = nil)
|
40
|
-
if !boolean.nil?
|
41
|
-
options[:hashed_label] = boolean
|
42
|
-
else
|
43
|
-
options[:hashed_label] || nil
|
44
|
-
end
|
45
|
-
end
|
37
|
+
option_accessor :depth
|
38
|
+
option_accessor :class_name
|
39
|
+
option_accessor :store_event
|
40
|
+
option_accessor :hashed_label
|
41
|
+
option_accessor :label_indexing
|
46
42
|
|
47
|
-
def class_name(class_name = nil)
|
48
|
-
if !class_name.nil?
|
49
|
-
options[:class_name] = class_name
|
50
|
-
else
|
51
|
-
options[:class_name] || nil
|
52
|
-
end
|
53
|
-
end
|
54
43
|
alias :scope :class_name
|
55
44
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
59
|
-
else
|
60
|
-
options[:depth] || nil
|
61
|
-
end
|
45
|
+
def connect_to(opts = {})
|
46
|
+
Connection.create(opts.merge(:ref => name))
|
47
|
+
options[:connection_ref] = name
|
62
48
|
end
|
63
49
|
|
64
|
-
def store_event(boolean = nil)
|
65
|
-
if !boolean.nil?
|
66
|
-
options[:store_event] = boolean
|
67
|
-
else
|
68
|
-
options[:store_event] || nil
|
69
|
-
end
|
70
|
-
end
|
71
50
|
|
72
51
|
#
|
73
52
|
# resource access methods
|
@@ -78,10 +57,6 @@ module Redistat
|
|
78
57
|
end
|
79
58
|
alias :redis :connection
|
80
59
|
|
81
|
-
def options
|
82
|
-
@options ||= {}
|
83
|
-
end
|
84
|
-
|
85
60
|
def name
|
86
61
|
options[:class_name] || (@name ||= self.to_s)
|
87
62
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Redistat
|
2
|
+
module Options
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
class InvalidDefaultOptions < ArgumentError; end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def option_accessor(*opts)
|
12
|
+
opts.each do |option|
|
13
|
+
define_method(option) do |*args|
|
14
|
+
if !args.first.nil?
|
15
|
+
options[option.to_sym] = args.first
|
16
|
+
else
|
17
|
+
options[option.to_sym] || nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse_options(opts)
|
25
|
+
opts ||= {}
|
26
|
+
@raw_options = opts
|
27
|
+
@options = default_options.merge(opts.reject { |k,v| v.nil? })
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_options
|
31
|
+
{}
|
32
|
+
end
|
33
|
+
|
34
|
+
def options
|
35
|
+
@options ||= {}
|
36
|
+
end
|
37
|
+
|
38
|
+
def raw_options
|
39
|
+
@raw_options ||= {}
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
data/lib/redistat/summary.rb
CHANGED
@@ -2,20 +2,28 @@ module Redistat
|
|
2
2
|
class Summary
|
3
3
|
include Database
|
4
4
|
|
5
|
-
def self.
|
5
|
+
def self.default_options
|
6
|
+
{ :enable_grouping => true,
|
7
|
+
:label_indexing => true,
|
8
|
+
:connection_ref => nil }
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.update_all(key, stats = {}, depth_limit = nil, opts = {})
|
6
12
|
stats ||= {}
|
7
13
|
return nil if stats.size == 0
|
8
14
|
|
15
|
+
options = default_options.merge((opts || {}).reject { |k,v| v.nil? })
|
16
|
+
|
9
17
|
depth_limit ||= key.depth
|
10
|
-
enable_grouping = true if enable_grouping.nil?
|
11
18
|
|
12
|
-
if enable_grouping
|
19
|
+
if options[:enable_grouping]
|
13
20
|
stats = inject_group_summaries(stats)
|
14
21
|
key.groups.each { |k|
|
15
|
-
update_key(k, stats, depth_limit, connection_ref)
|
22
|
+
update_key(k, stats, depth_limit, options[:connection_ref])
|
23
|
+
k.update_index if options[:label_indexing]
|
16
24
|
}
|
17
25
|
else
|
18
|
-
update_key(key, stats, depth_limit, connection_ref)
|
26
|
+
update_key(key, stats, depth_limit, options[:connection_ref])
|
19
27
|
end
|
20
28
|
end
|
21
29
|
|
data/lib/redistat/version.rb
CHANGED
data/redistat.gemspec
CHANGED
data/spec/event_spec.rb
CHANGED
@@ -18,7 +18,7 @@ describe Redistat::Event do
|
|
18
18
|
it "should initialize properly" do
|
19
19
|
@event.id.should be_nil
|
20
20
|
@event.scope.should == @scope
|
21
|
-
@event.label.should == @label
|
21
|
+
@event.label.to_s.should == @label
|
22
22
|
@event.label_hash.should == @label_hash
|
23
23
|
@event.date.to_time.to_s.should == @date.to_s
|
24
24
|
@event.stats.should == @stats
|
@@ -33,12 +33,12 @@ describe Redistat::Event do
|
|
33
33
|
@event.date = @date
|
34
34
|
@event.date.to_time.to_s.should == @date.to_s
|
35
35
|
# label
|
36
|
-
@event.label.should == @label
|
36
|
+
@event.label.to_s.should == @label
|
37
37
|
@event.label_hash.should == @label_hash
|
38
38
|
@label = "contact_us"
|
39
39
|
@label_hash = Digest::SHA1.hexdigest(@label)
|
40
40
|
@event.label = @label
|
41
|
-
@event.label.should == @label
|
41
|
+
@event.label.to_s.should == @label
|
42
42
|
@event.label_hash.should == @label_hash
|
43
43
|
end
|
44
44
|
|
@@ -64,7 +64,7 @@ describe Redistat::Event do
|
|
64
64
|
@event = Redistat::Event.new(@scope, @label, @date, @stats, @options.merge({:store_event => true}), @meta).save
|
65
65
|
fetched = Redistat::Event.find(@scope, @event.id)
|
66
66
|
@event.scope.should == fetched.scope
|
67
|
-
@event.label.should == fetched.label
|
67
|
+
@event.label.to_s.should == fetched.label.to_s
|
68
68
|
@event.date.to_s.should == fetched.date.to_s
|
69
69
|
end
|
70
70
|
|
data/spec/finder_spec.rb
CHANGED
@@ -9,41 +9,43 @@ describe Redistat::Finder do
|
|
9
9
|
@label = "about_us"
|
10
10
|
@date = Time.now
|
11
11
|
@key = Redistat::Key.new(@scope, @label, @date, {:depth => :day})
|
12
|
-
@stats = {"views" => 3, "visitors" => 2}
|
12
|
+
@stats = {"views" => 3, "visitors" => 2}
|
13
|
+
@two_hours_ago = 2.hours.ago
|
14
|
+
@one_hour_ago = 1.hour.ago
|
13
15
|
end
|
14
16
|
|
15
17
|
it "should initialize properly" do
|
16
|
-
|
17
|
-
one_hour_ago = 1.hour.ago
|
18
|
-
options = {:scope => "PageViews", :label => "Label", :from => two_hours_ago, :till => one_hour_ago, :depth => :hour, :interval => :hour}
|
19
|
-
|
20
|
-
finder = Redistat::Finder.new(options)
|
21
|
-
finder.options.should == options
|
18
|
+
options = {:scope => "PageViews", :label => "Label", :from => @two_hours_ago, :till => @one_hour_ago, :depth => :hour, :interval => :hour}
|
22
19
|
|
23
20
|
finder = Redistat::Finder.new
|
24
21
|
finder.send(:set_options, options)
|
25
|
-
finder.options.should
|
26
|
-
|
27
|
-
finder
|
28
|
-
finder.options.should == options
|
29
|
-
|
30
|
-
|
31
|
-
finder.
|
22
|
+
finder.options[:scope].should be_a(Redistat::Scope)
|
23
|
+
finder.options[:scope].to_s.should == options[:scope]
|
24
|
+
finder.options[:label].should be_a(Redistat::Label)
|
25
|
+
finder.options[:label].to_s.should == options[:label]
|
26
|
+
finder.options.should == options.merge(:scope => finder.options[:scope], :label => finder.options[:label])
|
27
|
+
|
28
|
+
finder = Redistat::Finder.dates(@two_hours_ago, @one_hour_ago)
|
29
|
+
finder.options[:from].should == @two_hours_ago
|
30
|
+
finder.options[:till].should == @one_hour_ago
|
31
|
+
|
32
|
+
finder = Redistat::Finder.scope("hello")
|
33
|
+
finder.options[:scope].to_s.should == "hello"
|
32
34
|
|
33
|
-
finder = Redistat::Finder.label("
|
34
|
-
finder.options.should ==
|
35
|
+
finder = Redistat::Finder.label("hello")
|
36
|
+
finder.options[:label].to_s.should == "hello"
|
35
37
|
|
36
|
-
finder = Redistat::Finder.from(two_hours_ago)
|
37
|
-
finder.options.should ==
|
38
|
+
finder = Redistat::Finder.from(@two_hours_ago)
|
39
|
+
finder.options[:from].should == @two_hours_ago
|
38
40
|
|
39
|
-
finder = Redistat::Finder.till(one_hour_ago)
|
40
|
-
finder.options.should ==
|
41
|
+
finder = Redistat::Finder.till(@one_hour_ago)
|
42
|
+
finder.options[:till].should == @one_hour_ago
|
41
43
|
|
42
|
-
finder = Redistat::Finder.depth(:hour)
|
43
|
-
finder.options.should ==
|
44
|
+
finder = Redistat::Finder.depth(:hour)
|
45
|
+
finder.options[:depth].should == :hour
|
44
46
|
|
45
|
-
finder = Redistat::Finder.interval(:hour)
|
46
|
-
finder.options.should ==
|
47
|
+
finder = Redistat::Finder.interval(:hour)
|
48
|
+
finder.options[:interval].should == :hour
|
47
49
|
|
48
50
|
end
|
49
51
|
|
@@ -89,6 +91,21 @@ describe Redistat::Finder do
|
|
89
91
|
lambda { Redistat::Finder.find(:from => 3.hours.ago) }.should raise_error(Redistat::InvalidOptions)
|
90
92
|
end
|
91
93
|
|
94
|
+
it "should find children" do
|
95
|
+
Redistat::Key.new("PageViews", "message/public/die").update_index
|
96
|
+
Redistat::Key.new("PageViews", "message/public/live").update_index
|
97
|
+
Redistat::Key.new("PageViews", "message/public/fester").update_index
|
98
|
+
members = db.smembers("#{@scope}#{Redistat::LABEL_INDEX}message/public") # checking 'message/public'
|
99
|
+
options = {:scope => "PageViews", :label => "message/public", :from => @two_hours_ago, :till => @one_hour_ago, :depth => :hour, :interval => :hour}
|
100
|
+
finder = Redistat::Finder.new(options)
|
101
|
+
finder.children.first.should be_a(Redistat::Finder)
|
102
|
+
subs = finder.children.map { |f| f.options[:label].me }
|
103
|
+
subs.should have(3).items
|
104
|
+
subs.should include('die')
|
105
|
+
subs.should include('live')
|
106
|
+
subs.should include('fester')
|
107
|
+
end
|
108
|
+
|
92
109
|
describe "Lazy-Loading" do
|
93
110
|
|
94
111
|
before(:each) do
|
@@ -103,7 +120,6 @@ describe Redistat::Finder do
|
|
103
120
|
end
|
104
121
|
|
105
122
|
it "should lazy-load" do
|
106
|
-
|
107
123
|
@finder.instance_variable_get("@result").should be_nil
|
108
124
|
stats = @finder.all
|
109
125
|
@finder.instance_variable_get("@result").should_not be_nil
|
@@ -146,7 +162,7 @@ describe Redistat::Finder do
|
|
146
162
|
res.should == match
|
147
163
|
end
|
148
164
|
|
149
|
-
end
|
165
|
+
end # "Lazy-Loading"
|
150
166
|
|
151
167
|
|
152
168
|
# helper methods
|
data/spec/key_spec.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Redistat::Key do
|
4
|
+
include Redistat::Database
|
4
5
|
|
5
6
|
before(:each) do
|
7
|
+
db.flushdb
|
6
8
|
@scope = "PageViews"
|
7
9
|
@label = "about_us"
|
8
10
|
@label_hash = Digest::SHA1.hexdigest(@label)
|
@@ -12,9 +14,9 @@ describe Redistat::Key do
|
|
12
14
|
|
13
15
|
it "should initialize properly" do
|
14
16
|
@key.scope.should == @scope
|
15
|
-
@key.label.should == @label
|
17
|
+
@key.label.to_s.should == @label
|
16
18
|
@key.label_hash.should == @label_hash
|
17
|
-
@key.
|
19
|
+
@key.groups.map { |k| k.instance_variable_get("@label") }.should == @key.instance_variable_get("@label").groups
|
18
20
|
@key.date.should be_instance_of(Redistat::Date)
|
19
21
|
@key.date.to_time.to_s.should == @date.to_s
|
20
22
|
end
|
@@ -52,25 +54,74 @@ describe Redistat::Key do
|
|
52
54
|
@key.date = @date
|
53
55
|
@key.date.to_time.to_s.should == @date.to_s
|
54
56
|
# label
|
55
|
-
@key.label.should == @label
|
57
|
+
@key.label.to_s.should == @label
|
56
58
|
@key.label_hash == @label_hash
|
57
59
|
@label = "contact_us"
|
58
60
|
@label_hash = Digest::SHA1.hexdigest(@label)
|
59
61
|
@key.label = @label
|
60
|
-
@key.label.should == @label
|
62
|
+
@key.label.to_s.should == @label
|
61
63
|
@key.label_hash == @label_hash
|
62
64
|
end
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
describe "Grouping" do
|
67
|
+
before(:each) do
|
68
|
+
@label = "message/public/offensive"
|
69
|
+
@key = Redistat::Key.new(@scope, @label, @date, {:depth => :hour})
|
70
|
+
end
|
69
71
|
|
70
|
-
|
72
|
+
it "should create a group of keys from label group" do
|
73
|
+
label = 'message/public/offensive'
|
74
|
+
result = [ "message/public/offensive",
|
75
|
+
"message/public",
|
76
|
+
"message" ]
|
77
|
+
|
78
|
+
key = Redistat::Key.new(@scope, label, @date, {:depth => :hour})
|
79
|
+
|
80
|
+
key.groups.map { |k| k.label.to_s }.should == result
|
81
|
+
end
|
71
82
|
|
72
|
-
|
73
|
-
|
83
|
+
it "should know it's parent" do
|
84
|
+
@key.parent.should be_a(Redistat::Key)
|
85
|
+
@key.parent.label.to_s.should == 'message/public'
|
86
|
+
Redistat::Key.new(@scope, 'hello', @date).parent.should be_nil
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should update label index and return children" do
|
90
|
+
db.smembers("#{@scope}#{Redistat::LABEL_INDEX}#{@key.label.parent}").should == []
|
91
|
+
@key.children.should have(0).items
|
92
|
+
|
93
|
+
@key.update_index # indexing 'message/publish/offensive'
|
94
|
+
Redistat::Key.new("PageViews", "message/public/die").update_index # indexing 'message/publish/die'
|
95
|
+
Redistat::Key.new("PageViews", "message/public/live").update_index # indexing 'message/publish/live'
|
96
|
+
|
97
|
+
members = db.smembers("#{@scope}#{Redistat::LABEL_INDEX}#{@key.label.parent}") # checking 'message/public'
|
98
|
+
members.should have(3).item
|
99
|
+
members.should include('offensive')
|
100
|
+
members.should include('live')
|
101
|
+
members.should include('die')
|
102
|
+
|
103
|
+
key = @key.parent
|
104
|
+
key.children.first.should be_a(Redistat::Key)
|
105
|
+
key.children.should have(3).item
|
106
|
+
key.children.map { |k| k.label.me }.should == members
|
107
|
+
|
108
|
+
members = db.smembers("#{@scope}#{Redistat::LABEL_INDEX}#{key.label.parent}") # checking 'message'
|
109
|
+
members.should have(1).item
|
110
|
+
members.should include('public')
|
111
|
+
|
112
|
+
key = key.parent
|
113
|
+
key.children.should have(1).item
|
114
|
+
key.children.map { |k| k.label.me }.should == members
|
115
|
+
|
116
|
+
members = db.smembers("#{@scope}#{Redistat::LABEL_INDEX}") # checking ''
|
117
|
+
members.should have(1).item
|
118
|
+
members.should include('message')
|
119
|
+
|
120
|
+
key.parent.should be_nil
|
121
|
+
key = Redistat::Key.new("PageViews")
|
122
|
+
key.children.should have(1).item
|
123
|
+
key.children.map { |k| k.label.me }.should include('message')
|
124
|
+
end
|
74
125
|
end
|
75
126
|
|
76
127
|
end
|
data/spec/label_spec.rb
CHANGED
@@ -17,32 +17,42 @@ describe Redistat::Label do
|
|
17
17
|
it "should store a label hash lookup key" do
|
18
18
|
label = Redistat::Label.new(@name, {:hashed_label => true}).save
|
19
19
|
label.saved?.should be_true
|
20
|
-
db.
|
20
|
+
db.hget(Redistat::KEY_LEBELS, label.hash).should == @name
|
21
21
|
|
22
22
|
name = "contact_us"
|
23
23
|
label = Redistat::Label.create(name, {:hashed_label => true})
|
24
24
|
label.saved?.should be_true
|
25
|
-
db.
|
25
|
+
db.hget(Redistat::KEY_LEBELS, label.hash).should == name
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
28
|
+
describe "Grouping" do
|
29
|
+
before(:each) do
|
30
|
+
@name = "message/public/offensive"
|
31
|
+
@label = Redistat::Label.new(@name)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should know it's parent label group" do
|
35
|
+
@label.parent.to_s.should == 'message/public'
|
36
|
+
Redistat::Label.new('hello').parent.should be_nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should separate label names into groups" do
|
40
|
+
@label.name.should == @name
|
41
|
+
@label.groups.map { |l| l.to_s }.should == [ "message/public/offensive",
|
42
|
+
"message/public",
|
43
|
+
"message" ]
|
35
44
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
45
|
+
@name = "/message/public/"
|
46
|
+
@label = Redistat::Label.new(@name)
|
47
|
+
@label.name.should == @name
|
48
|
+
@label.groups.map { |l| l.to_s }.should == [ "message/public",
|
49
|
+
"message" ]
|
41
50
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
51
|
+
@name = "message"
|
52
|
+
@label = Redistat::Label.new(@name)
|
53
|
+
@label.name.should == @name
|
54
|
+
@label.groups.map { |l| l.to_s }.should == [ "message" ]
|
55
|
+
end
|
46
56
|
end
|
47
57
|
|
48
58
|
end
|
data/spec/model_spec.rb
CHANGED
@@ -22,8 +22,8 @@ describe Redistat::Model do
|
|
22
22
|
one_hour_ago = 1.hour.ago
|
23
23
|
finder = ModelHelper1.find('label', two_hours_ago, one_hour_ago)
|
24
24
|
finder.should be_a(Redistat::Finder)
|
25
|
-
finder.options[:scope].should == 'ModelHelper1'
|
26
|
-
finder.options[:label].should == 'label'
|
25
|
+
finder.options[:scope].to_s.should == 'ModelHelper1'
|
26
|
+
finder.options[:label].to_s.should == 'label'
|
27
27
|
finder.options[:from].should == two_hours_ago
|
28
28
|
finder.options[:till].should == one_hour_ago
|
29
29
|
end
|
@@ -82,34 +82,71 @@ describe Redistat::Model do
|
|
82
82
|
stats.first.should == stats.total
|
83
83
|
end
|
84
84
|
|
85
|
+
it "should store and fetch grouping enabled stats" do
|
86
|
+
ModelHelper1.store("sheep/black", {:count => 6, :weight => 461}, @time.hours_ago(4))
|
87
|
+
ModelHelper1.store("sheep/black", {:count => 2, :weight => 156}, @time)
|
88
|
+
ModelHelper1.store("sheep/white", {:count => 5, :weight => 393}, @time.hours_ago(4))
|
89
|
+
ModelHelper1.store("sheep/white", {:count => 4, :weight => 316}, @time)
|
90
|
+
|
91
|
+
stats = ModelHelper1.fetch("sheep/black", @time.hours_ago(2), @time.hours_since(1))
|
92
|
+
stats.total["count"].should == 2
|
93
|
+
stats.total["weight"].should == 156
|
94
|
+
stats.first.should == stats.total
|
95
|
+
|
96
|
+
stats = ModelHelper1.fetch("sheep/black", @time.hours_ago(5), @time.hours_since(1))
|
97
|
+
stats.total[:count].should == 8
|
98
|
+
stats.total[:weight].should == 617
|
99
|
+
stats.first.should == stats.total
|
100
|
+
|
101
|
+
stats = ModelHelper1.fetch("sheep/white", @time.hours_ago(2), @time.hours_since(1))
|
102
|
+
stats.total[:count].should == 4
|
103
|
+
stats.total[:weight].should == 316
|
104
|
+
stats.first.should == stats.total
|
105
|
+
|
106
|
+
stats = ModelHelper1.fetch("sheep/white", @time.hours_ago(5), @time.hours_since(1))
|
107
|
+
stats.total[:count].should == 9
|
108
|
+
stats.total[:weight].should == 709
|
109
|
+
stats.first.should == stats.total
|
110
|
+
|
111
|
+
stats = ModelHelper1.fetch("sheep", @time.hours_ago(2), @time.hours_since(1))
|
112
|
+
stats.total[:count].should == 6
|
113
|
+
stats.total[:weight].should == 472
|
114
|
+
stats.first.should == stats.total
|
115
|
+
|
116
|
+
stats = ModelHelper1.fetch("sheep", @time.hours_ago(5), @time.hours_since(1))
|
117
|
+
stats.total[:count].should == 17
|
118
|
+
stats.total[:weight].should == 1326
|
119
|
+
stats.first.should == stats.total
|
120
|
+
end
|
121
|
+
|
85
122
|
it "should connect to different Redis servers on a per-model basis" do
|
86
123
|
ModelHelper3.redis.client.db.should == 14
|
87
124
|
|
88
|
-
ModelHelper3.store("sheep.black", {:count => 6, :weight => 461}, @time.hours_ago(4))
|
89
|
-
ModelHelper3.store("sheep.black", {:count => 2, :weight => 156}, @time)
|
125
|
+
ModelHelper3.store("sheep.black", {:count => 6, :weight => 461}, @time.hours_ago(4), :label_indexing => false)
|
126
|
+
ModelHelper3.store("sheep.black", {:count => 2, :weight => 156}, @time, :label_indexing => false)
|
90
127
|
|
91
128
|
db.keys("*").should be_empty
|
92
129
|
ModelHelper1.redis.keys("*").should be_empty
|
93
130
|
db("ModelHelper3").keys("*").should have(5).items
|
94
131
|
ModelHelper3.redis.keys("*").should have(5).items
|
95
132
|
|
96
|
-
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(2), @time.hours_since(1))
|
133
|
+
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(2), @time.hours_since(1), :label_indexing => false)
|
97
134
|
stats.total["count"].should == 2
|
98
135
|
stats.total["weight"].should == 156
|
99
|
-
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(5), @time.hours_since(1))
|
136
|
+
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(5), @time.hours_since(1), :label_indexing => false)
|
100
137
|
stats.total[:count].should == 8
|
101
138
|
stats.total[:weight].should == 617
|
102
139
|
|
103
140
|
ModelHelper3.connect_to(:port => 8379, :db => 13)
|
104
141
|
ModelHelper3.redis.client.db.should == 13
|
105
142
|
|
106
|
-
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(5), @time.hours_since(1))
|
143
|
+
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(5), @time.hours_since(1), :label_indexing => false)
|
107
144
|
stats.total.should == {}
|
108
145
|
|
109
146
|
ModelHelper3.connect_to(:port => 8379, :db => 14)
|
110
147
|
ModelHelper3.redis.client.db.should == 14
|
111
148
|
|
112
|
-
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(5), @time.hours_since(1))
|
149
|
+
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(5), @time.hours_since(1), :label_indexing => false)
|
113
150
|
stats.total[:count].should == 8
|
114
151
|
stats.total[:weight].should == 617
|
115
152
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Redistat::Options do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@helper = OptionsHelper.new
|
7
|
+
@helper.parse_options(:wtf => 'dude', :foo => 'booze')
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should #parse_options" do
|
11
|
+
@helper.options[:hello].should == 'world'
|
12
|
+
@helper.options[:foo].should == 'booze'
|
13
|
+
@helper.options[:wtf].should == 'dude'
|
14
|
+
@helper.raw_options.should_not have_key(:hello)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should create option_accessors" do
|
18
|
+
@helper.hello.should == 'world'
|
19
|
+
@helper.hello('woooo')
|
20
|
+
@helper.hello.should == 'woooo'
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
class OptionsHelper
|
26
|
+
include Redistat::Options
|
27
|
+
|
28
|
+
option_accessor :hello
|
29
|
+
|
30
|
+
def default_options
|
31
|
+
{ :hello => 'world',
|
32
|
+
:foo => 'bar' }
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
end
|
data/spec/summary_spec.rb
CHANGED
@@ -69,7 +69,7 @@ describe Redistat::Summary do
|
|
69
69
|
|
70
70
|
it "should not store key group summaries when option is disabled" do
|
71
71
|
stats = {"views" => 3, "visitors/eu" => 2, "visitors/us" => 4}
|
72
|
-
Redistat::Summary.update_all(@key, stats, :hour,
|
72
|
+
Redistat::Summary.update_all(@key, stats, :hour, {:enable_grouping => false})
|
73
73
|
summary = db.hgetall(@key.to_s(:hour))
|
74
74
|
summary.should have(3).items
|
75
75
|
summary["views"].should == "3"
|
@@ -83,8 +83,8 @@ describe Redistat::Summary do
|
|
83
83
|
key = Redistat::Key.new(@scope, label, @date)
|
84
84
|
Redistat::Summary.update_all(key, stats, :hour)
|
85
85
|
|
86
|
-
key.groups[0].label.should == "views/about_us"
|
87
|
-
key.groups[1].label.should == "views"
|
86
|
+
key.groups[0].label.to_s.should == "views/about_us"
|
87
|
+
key.groups[1].label.to_s.should == "views"
|
88
88
|
child1 = key.groups[0]
|
89
89
|
parent = key.groups[1]
|
90
90
|
|
@@ -92,8 +92,8 @@ describe Redistat::Summary do
|
|
92
92
|
key = Redistat::Key.new(@scope, label, @date)
|
93
93
|
Redistat::Summary.update_all(key, stats, :hour)
|
94
94
|
|
95
|
-
key.groups[0].label.should == "views/contact"
|
96
|
-
key.groups[1].label.should == "views"
|
95
|
+
key.groups[0].label.to_s.should == "views/contact"
|
96
|
+
key.groups[1].label.to_s.should == "views"
|
97
97
|
child2 = key.groups[0]
|
98
98
|
|
99
99
|
summary = db.hgetall(child1.to_s(:hour))
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redistat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jim Myhrberg
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-03-
|
18
|
+
date: 2011-03-10 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -130,6 +130,20 @@ dependencies:
|
|
130
130
|
version: 0.6.3
|
131
131
|
type: :development
|
132
132
|
version_requirements: *id007
|
133
|
+
- !ruby/object:Gem::Dependency
|
134
|
+
name: ruby-debug
|
135
|
+
prerelease: false
|
136
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
hash: 3
|
142
|
+
segments:
|
143
|
+
- 0
|
144
|
+
version: "0"
|
145
|
+
type: :development
|
146
|
+
version_requirements: *id008
|
133
147
|
description: A Redis-backed statistics storage and querying library written in Ruby.
|
134
148
|
email:
|
135
149
|
- contact@jimeh.me
|
@@ -164,6 +178,7 @@ files:
|
|
164
178
|
- lib/redistat/key.rb
|
165
179
|
- lib/redistat/label.rb
|
166
180
|
- lib/redistat/model.rb
|
181
|
+
- lib/redistat/options.rb
|
167
182
|
- lib/redistat/result.rb
|
168
183
|
- lib/redistat/scope.rb
|
169
184
|
- lib/redistat/summary.rb
|
@@ -181,6 +196,7 @@ files:
|
|
181
196
|
- spec/label_spec.rb
|
182
197
|
- spec/model_helper.rb
|
183
198
|
- spec/model_spec.rb
|
199
|
+
- spec/options_spec.rb
|
184
200
|
- spec/redis-test.conf
|
185
201
|
- spec/result_spec.rb
|
186
202
|
- spec/scope_spec.rb
|
@@ -234,6 +250,7 @@ test_files:
|
|
234
250
|
- spec/label_spec.rb
|
235
251
|
- spec/model_helper.rb
|
236
252
|
- spec/model_spec.rb
|
253
|
+
- spec/options_spec.rb
|
237
254
|
- spec/redis-test.conf
|
238
255
|
- spec/result_spec.rb
|
239
256
|
- spec/scope_spec.rb
|